mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
335 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ea8ba1b96 | |||
| ae8b7973b4 | |||
| a7f430bda8 | |||
| 5a781eeb54 | |||
| a879d18c9c | |||
| ce49068ff9 | |||
| 62a0ab3667 | |||
| 92a231cf91 | |||
| 50dff77d01 | |||
| 0f479293b1 | |||
| 5f5d383eeb | |||
| 529481c44c | |||
| 35d379f9d3 | |||
| c871758a51 | |||
| 0d2bfc926f | |||
| 4e97776969 | |||
| d42f950a36 | |||
| 4eabe29b9a | |||
| cd10171f98 | |||
| 597c687da8 | |||
| 081d70123e | |||
| d9c2ccb4b3 | |||
| c503f356c7 | |||
| 7f9933fdb7 | |||
| a425512025 | |||
| 298c9a6f1b | |||
| 8dcb2a75fa | |||
| 111a9902ac | |||
| 0389fcca7e | |||
| bb3ada4a67 | |||
| 6a68bd58f9 | |||
| b1414bf15b | |||
| f91943977c | |||
| 4c0ece944a | |||
| 2c75eb8745 | |||
| 711820ec70 | |||
| 69d87f16ee | |||
| 38f94799f4 | |||
| 4264d0becd | |||
| 7e7d6b9c3a | |||
| dfc06eda7a | |||
| f0aa6ebed6 | |||
| 6806aaf162 | |||
| ccec75c98d | |||
| 22029b4487 | |||
| d6b60046ce | |||
| 6685e78c36 | |||
| 8685b2f5bf | |||
| 4af225405c | |||
| 51e594ae81 | |||
| c2554b2b27 | |||
| 86a762b5ee | |||
| 211241befe | |||
| 0caa2ac696 | |||
| 4eb8a5c082 | |||
| d080b64907 | |||
| 5ab55dfb64 | |||
| 04209def46 | |||
| 3a61930bd0 | |||
| 456c7889a3 | |||
| 982d8ea84a | |||
| 67eb2bbf19 | |||
| a6596e2446 | |||
| 812b089f1d | |||
| 2172b99fee | |||
| b6144e5682 | |||
| 6e6f8637d1 | |||
| 00f7f5ff0a | |||
| 3d4a778b73 | |||
| 446c1add4f | |||
| aef4b0ec5a | |||
| 675e0b94c1 | |||
| b8b54ee524 | |||
| 97ea8a6789 | |||
| 95a400abfb | |||
| 4383a673bb | |||
| f7b94fc3e8 | |||
| 93760d1211 | |||
| 421b5cb311 | |||
| 1cc36e5be9 | |||
| f7c32d3a0b | |||
| 9c0a2eeeb2 | |||
| 7fa9f1c9cf | |||
| 1e03b30d33 | |||
| 7df149c8b8 | |||
| e50131d454 | |||
| cdd4e8cd7f | |||
| 02b7ddbc70 | |||
| 8e5c4903d4 | |||
| bd3499671c | |||
| 2e4d7e4ef9 | |||
| c6be3b33c9 | |||
| c112bb0ae1 | |||
| 165fba868c | |||
| 2ca64ad88a | |||
| ea27206a32 | |||
| c48c5e7691 | |||
| bc15f839cd | |||
| 46db372951 | |||
| 91258271e4 | |||
| e76fbcb290 | |||
| 82ca27e46f | |||
| bca104798b | |||
| b30eb6837c | |||
| ac06d1dfa9 | |||
| cfb39acc97 | |||
| 222dbf8377 | |||
| 10838a636f | |||
| 3c3ae32f07 | |||
| a3e46a2db7 | |||
| de1b938e2e | |||
| d72aeac319 | |||
| 5247eeba84 | |||
| ae70e3c81c | |||
| c942c8d2cf | |||
| 1201af20e4 | |||
| d1df4d3739 | |||
| 1ef8800c6c | |||
| 4d7e4e0c58 | |||
| c7067269b3 | |||
| 3af6a22b9f | |||
| 31a9694fc8 | |||
| 92b8e99cbc | |||
| 3b68e97710 | |||
| 6f494ef438 | |||
| 19704805fd | |||
| 31c6965c7f | |||
| 5b1a84e395 | |||
| 6985fa8057 | |||
| 03f0c57704 | |||
| d274e893a6 | |||
| aa8b06b622 | |||
| 323dbb912e | |||
| 63d7e81a48 | |||
| 07960d4918 | |||
| 07cfcbc3a9 | |||
| 2af27d899f | |||
| 0621a8eff1 | |||
| 7ac646bc96 | |||
| 2c3243c93c | |||
| 2bf5f7a6b3 | |||
| bf39492c34 | |||
| 007bdede46 | |||
| 22cc6c5918 | |||
| 461ba53b39 | |||
| d1d6eb095e | |||
| f732fab820 | |||
| fda3f8201a | |||
| e608b36713 | |||
| 59180e76a7 | |||
| c5987d7c37 | |||
| 5650e20edd | |||
| 2885177f5b | |||
| 058ce36402 | |||
| 2afe560e41 | |||
| b95362a3fd | |||
| 9ea45697ac | |||
| fe2b8580a0 | |||
| 622fc3edf7 | |||
| 9868c28c73 | |||
| a970516080 | |||
| 0c9def89de | |||
| 8892a05868 | |||
| d6768ccc18 | |||
| faf20b7a5a | |||
| 661996471e | |||
| 5639ff0939 | |||
| e98b602d4f | |||
| edfe5d2f18 | |||
| 26df4580b3 | |||
| 57208bf47a | |||
| 8b34558284 | |||
| dbe8f200a9 | |||
| ea4d9a20ac | |||
| e19e9757d4 | |||
| 2473e956ff | |||
| 854307d8d8 | |||
| 3401359bdf | |||
| f1c00dd8a6 | |||
| bdf91ac435 | |||
| 181023c0c3 | |||
| fb1fa073a6 | |||
| e9806a96dc | |||
| 9b93508374 | |||
| 8b4750e705 | |||
| 2e033339d1 | |||
| c75da7ba10 | |||
| eeac150030 | |||
| 0ce9516aef | |||
| e47cc44947 | |||
| 57db73dcb8 | |||
| d7be1e0dab | |||
| 30c873b4b5 | |||
| e72b0a04cd | |||
| f8b41c1ad2 | |||
| 8c777111fa | |||
| d28d603081 | |||
| 52d0681ca1 | |||
| 97854d9fec | |||
| 73f3860bb7 | |||
| 452f1b877c | |||
| c278d8c656 | |||
| e3b288716d | |||
| 27738cc20f | |||
| babff8e635 | |||
| 290cc73d3d | |||
| 8a30bc2993 | |||
| aa8be28a01 | |||
| f43b28e7ba | |||
| 1476867ee7 | |||
| 4d9dc61f5d | |||
| 7eebc48a6e | |||
| 8478e8e70a | |||
| e386bdb82c | |||
| 4912c3c455 | |||
| 8fcc7ab9d1 | |||
| 7c47b470ff | |||
| 479ef3f3fd | |||
| be1b7da12f | |||
| 89360b18f4 | |||
| 209fe5f452 | |||
| e18a118f8b | |||
| 77aac7768d | |||
| e2767371b5 | |||
| aab9da0366 | |||
| cda1e5507c | |||
| 1d5ffaf30a | |||
| c55606ed08 | |||
| aa8802a81d | |||
| 1beb7068f6 | |||
| 9d324e59a0 | |||
| 8547f8601d | |||
| 40cb81470b | |||
| 6e3b3c5419 | |||
| a221835558 | |||
| aa06a09dee | |||
| bde0931e51 | |||
| 7b95c928d1 | |||
| 53f88d455f | |||
| 53a506f6bb | |||
| f95bf96ec9 | |||
| 66a5742df3 | |||
| 59c7bb1f86 | |||
| a1c3efbb5f | |||
| 6efe3aee34 | |||
| f2fe7f335c | |||
| 48c797e429 | |||
| be782a2197 | |||
| 8098e45bad | |||
| 06679a5583 | |||
| 745eb1a881 | |||
| 10c55ff912 | |||
| 83186b689f | |||
| dc2947c52d | |||
| e4ec376075 | |||
| c81e11d537 | |||
| de6180b093 | |||
| 1c10cdd1e8 | |||
| 941b92cbed | |||
| e26d8839b3 | |||
| a1c7380398 | |||
| 7dd622bdb2 | |||
| 64c96c579d | |||
| 39e3876301 | |||
| f771603789 | |||
| e441832e99 | |||
| f963fc5f98 | |||
| b55eee1b0d | |||
| 28742171fd | |||
| 7a75b94556 | |||
| ab71ff93bb | |||
| cf30327740 | |||
| e22a038725 | |||
| 7aedb9ee33 | |||
| 5b1719cd77 | |||
| c056b81753 | |||
| dbdd67ec62 | |||
| 4fcfa5b991 | |||
| ed06a6de26 | |||
| afa799b4f0 | |||
| f0d149b330 | |||
| caaf83b8e6 | |||
| b30f4d7bb7 | |||
| b6b03f38d7 | |||
| 46b0d7dc03 | |||
| fcf64798b5 | |||
| 94ed07d9cb | |||
| b81c62d064 | |||
| ca1a11acac | |||
| c261d40610 | |||
| 3017955eff | |||
| 22c82ff206 | |||
| f54952481b | |||
| 9e733b09e2 | |||
| a7cf19cec5 | |||
| 0cf7f7bd89 | |||
| 949c3d450c | |||
| 3b4ae7b028 | |||
| 8b39698553 | |||
| 6fad00ed22 | |||
| 5f6d8df34b | |||
| 35de7e19ee | |||
| 10e979e58b | |||
| 4143b445d6 | |||
| eefdd2c768 | |||
| 9f91168396 | |||
| 7aed6279a2 | |||
| c3fe112fd7 | |||
| 90103b0ae9 | |||
| 0cf15c0fdd | |||
| 4e9af3e277 | |||
| 01fd489b47 | |||
| 270b167e08 | |||
| b158110801 | |||
| 17f7a24118 | |||
| d518a7d8c8 | |||
| 24cd3c1f4c | |||
| 2a8c369cff | |||
| 002546b3e4 | |||
| 1627f57f1f | |||
| 3811cd4c0a | |||
| d927e37364 | |||
| 1d302bf384 | |||
| 4b150fd451 | |||
| 3a6016d356 | |||
| 135506f672 | |||
| cb36ca31f6 | |||
| edd66d96dd | |||
| 35610a535d | |||
| acf2955b96 | |||
| 8fc744f4f4 | |||
| 9a5891e6e6 | |||
| 64b64d9ba0 | |||
| 1419172fbd | |||
| 420e0ba25f |
@@ -1,6 +1,9 @@
|
||||
name: "Validate Gradle Wrapper"
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
validation:
|
||||
name: "Validation"
|
||||
|
||||
@@ -21,6 +21,7 @@ classes/
|
||||
/build
|
||||
buildSrc/build
|
||||
/spring-*/build
|
||||
/spring-core/graalvm/build
|
||||
/spring-core/kotlin-coroutines/build
|
||||
/framework-bom/build
|
||||
/integration-tests/build
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
Juergen Hoeller <jhoeller@pivotal.io> jhoeller <jhoeller@vmware.com>
|
||||
<jhoeller@pivotal.io> <jhoeller@vmware.com>
|
||||
<jhoeller@pivotal.io> <jhoeller@gopivotal.com>
|
||||
<rstoyanchev@pivotal.io> <rstoyanchev@vmware.com>
|
||||
<rstoyanchev@pivotal.io> <rstoyanchev@gopivotal.com>
|
||||
<pwebb@pivotal.io> <pwebb@vmware.com>
|
||||
<pwebb@pivotal.io> <pwebb@gopivotal.com>
|
||||
<cbeams@pivotal.io> <cbeams@vmware.com>
|
||||
<cbeams@pivotal.io> <cbeams@gopivotal.com>
|
||||
<cbeams@pivotal.io> <cbeams@gmail.com>
|
||||
<apoutsma@pivotal.io> <apoutsma@vmware.com>
|
||||
<apoutsma@pivotal.io> <apoutsma@gopivotal.com>
|
||||
<apoutsma@pivotal.io> <poutsma@mac.com>
|
||||
<ogierke@pivotal.io> <ogierke@vmware.com>
|
||||
<ogierke@pivotal.io> <ogierke@gopivotal.com>
|
||||
<dsyer@pivotal.io> <dsyer@vmware.com>
|
||||
<dsyer@pivotal.io> <dsyer@gopivotal.com>
|
||||
<dsyer@pivotal.io> <david_syer@hotmail.com>
|
||||
<aclement@pivotal.io> <aclement@vmware.com>
|
||||
<aclement@pivotal.io> <aclement@gopivotal.com>
|
||||
<aclement@pivotal.io> <andrew.clement@gmail.com>
|
||||
Juergen Hoeller <jhoeller@vmware.com>
|
||||
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@pivotal.io>
|
||||
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@gopivotal.com>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@pivotal.io>
|
||||
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@gopivotal.com>
|
||||
Phillip Webb <pwebb@vmware.com>
|
||||
Phillip Webb <pwebb@vmware.com> <pwebb@pivotal.io>
|
||||
Phillip Webb <pwebb@vmware.com> <pwebb@gopivotal.com>
|
||||
Chris Beams <cbeams@vmware.com>
|
||||
Chris Beams <cbeams@vmware.com> <cbeams@pivotal.io>
|
||||
Chris Beams <cbeams@vmware.com> <cbeams@gopivotal.com>
|
||||
Arjen Poutsma <apoutsma@vmware.com>
|
||||
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@pivotal.io>
|
||||
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@gopivotal.com>
|
||||
Arjen Poutsma <apoutsma@vmware.com> <poutsma@mac.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@vmware.com>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@pivotal.io>
|
||||
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@gopivotal.com>
|
||||
Dave Syer <dsyer@vmware.com>
|
||||
Dave Syer <dsyer@vmware.com> <dsyer@pivotal.io>
|
||||
Dave Syer <dsyer@vmware.com> <dsyer@gopivotal.com>
|
||||
Dave Syer <dsyer@vmware.com> <david_syer@hotmail.com>
|
||||
Andy Clement <aclement@vmware.com>
|
||||
Andy Clement <aclement@vmware.com> <aclement@pivotal.io>
|
||||
Andy Clement <aclement@vmware.com> <aclement@gopivotal.com>
|
||||
Andy Clement <aclement@vmware.com> <andrew.clement@gmail.com>
|
||||
Sam Brannen <sbrannen@vmware.com>
|
||||
Sam Brannen <sbrannen@vmware.com> <sbrannen@pivotal.io>
|
||||
Sam Brannen <sbrannen@vmware.com> <sam@sambrannen.com>
|
||||
<dmitry.katsubo@gmail.com> <dmitry.katsubo@gmai.com>
|
||||
Nick Williams <nicholas@nicholaswilliams.net> Nicholas Williams <nicholas@nicholaswilliams.net>
|
||||
Nick Williams <nicholas@nicholaswilliams.net>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Enable auto-env through the sdkman_auto_env config
|
||||
# Add key=value pairs of SDKs to use below
|
||||
java=8.0.322-librca
|
||||
java=8.0.345-librca
|
||||
|
||||
@@ -14,16 +14,16 @@ For access to artifacts or a distribution zip, see the [Spring Framework Artifac
|
||||
|
||||
## Documentation
|
||||
|
||||
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
|
||||
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), GitHub [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
|
||||
[API reference](https://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
|
||||
|
||||
## Micro-Benchmarks
|
||||
|
||||
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) Wiki page.
|
||||
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) wiki page.
|
||||
|
||||
## Build from Source
|
||||
|
||||
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) Wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||
|
||||
## Continuous Integration Builds
|
||||
|
||||
|
||||
+29
-27
@@ -27,19 +27,19 @@ configure(allprojects) { project ->
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
|
||||
mavenBom "io.netty:netty-bom:4.1.75.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.17"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.1"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.7"
|
||||
mavenBom "io.netty:netty-bom:4.1.82.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.23"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR13"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.3"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.48.v20220622"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
|
||||
mavenBom "org.junit:junit-bom:5.8.2"
|
||||
}
|
||||
dependencies {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.2') {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.18.0') {
|
||||
entry 'log4j-api'
|
||||
entry 'log4j-core'
|
||||
entry 'log4j-jul'
|
||||
@@ -67,8 +67,8 @@ configure(allprojects) { project ->
|
||||
dependency "io.reactivex:rxjava:1.3.8"
|
||||
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
|
||||
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.1.3"
|
||||
dependency "io.smallrye.reactive:mutiny:1.4.0"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.1.5"
|
||||
dependency "io.smallrye.reactive:mutiny:1.7.0"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
|
||||
|
||||
dependency "com.caucho:hessian:4.0.63"
|
||||
@@ -79,11 +79,11 @@ configure(allprojects) { project ->
|
||||
dependency "com.google.code.gson:gson:2.8.9"
|
||||
dependency "com.google.protobuf:protobuf-java-util:3.19.3"
|
||||
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.18") {
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.19") {
|
||||
exclude group: "xpp3", name: "xpp3_min"
|
||||
exclude group: "xmlpull", name: "xmlpull"
|
||||
}
|
||||
dependency "org.apache.johnzon:johnzon-jsonb:1.2.16"
|
||||
dependency "org.apache.johnzon:johnzon-jsonb:1.2.18"
|
||||
dependency("org.codehaus.jettison:jettison:1.3.8") {
|
||||
exclude group: "stax", name: "stax-api"
|
||||
}
|
||||
@@ -94,9 +94,9 @@ configure(allprojects) { project ->
|
||||
dependency "org.ogce:xpp3:1.1.6"
|
||||
dependency "org.yaml:snakeyaml:1.30"
|
||||
|
||||
dependency "com.h2database:h2:2.1.210"
|
||||
dependency "com.h2database:h2:2.1.214"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
|
||||
dependency "com.github.librepdf:openpdf:1.3.26"
|
||||
dependency "com.github.librepdf:openpdf:1.3.29"
|
||||
dependency "com.rometools:rome:1.18.0"
|
||||
dependency "commons-io:commons-io:2.5"
|
||||
dependency "io.vavr:vavr:0.10.4"
|
||||
@@ -124,22 +124,22 @@ configure(allprojects) { project ->
|
||||
dependency "org.ehcache:jcache:1.0.1"
|
||||
dependency "org.ehcache:ehcache:3.4.0"
|
||||
dependency "org.hibernate:hibernate-core:5.4.33.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.2.3.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.2.5.Final"
|
||||
dependency "org.webjars:webjars-locator-core:0.48"
|
||||
dependency "org.webjars:underscorejs:1.8.3"
|
||||
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.60') {
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.65') {
|
||||
entry 'tomcat-util'
|
||||
entry('tomcat-websocket') {
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.60') {
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.65') {
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
|
||||
dependencySet(group: 'io.undertow', version: '2.2.19.Final') {
|
||||
entry 'undertow-core'
|
||||
entry('undertow-servlet') {
|
||||
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
|
||||
@@ -150,7 +150,7 @@ configure(allprojects) { project ->
|
||||
}
|
||||
}
|
||||
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.10"
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.12"
|
||||
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1.3'
|
||||
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3'
|
||||
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
|
||||
@@ -188,17 +188,17 @@ configure(allprojects) { project ->
|
||||
exclude group: "junit", name: "junit"
|
||||
}
|
||||
dependency "org.testng:testng:7.4.0"
|
||||
dependency "org.junit.support:testng-engine:1.0.1"
|
||||
dependency "org.hamcrest:hamcrest:2.1"
|
||||
dependency "org.junit.support:testng-engine:1.0.4"
|
||||
dependency "org.hamcrest:hamcrest:2.2"
|
||||
dependency "org.awaitility:awaitility:3.1.6"
|
||||
dependency "org.assertj:assertj-core:3.22.0"
|
||||
dependency "org.assertj:assertj-core:3.23.0"
|
||||
dependencySet(group: 'org.xmlunit', version: '2.9.0') {
|
||||
entry 'xmlunit-assertj'
|
||||
entry('xmlunit-matchers') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.mockito', version: '4.4.0') {
|
||||
dependencySet(group: 'org.mockito', version: '4.6.1') {
|
||||
entry('mockito-core') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
@@ -206,10 +206,10 @@ configure(allprojects) { project ->
|
||||
}
|
||||
dependency "io.mockk:mockk:1.12.1"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.59.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.64.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.59.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.64.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
@@ -217,8 +217,8 @@ configure(allprojects) { project ->
|
||||
exclude group: "io.netty", name: "netty"
|
||||
}
|
||||
dependency "org.skyscreamer:jsonassert:1.5.0"
|
||||
dependency "com.jayway.jsonpath:json-path:2.6.0"
|
||||
dependency "org.bouncycastle:bcpkix-jdk15on:1.66"
|
||||
dependency "com.jayway.jsonpath:json-path:2.7.0"
|
||||
dependency "org.bouncycastle:bcpkix-jdk18on:1.71"
|
||||
|
||||
dependencySet(group: 'org.apache.tiles', version: '3.0.8') {
|
||||
entry 'tiles-api'
|
||||
@@ -340,7 +340,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "9.3"
|
||||
toolVersion = "10.3.3"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
@@ -413,6 +413,8 @@ configure(rootProject) {
|
||||
|
||||
nohttp {
|
||||
source.exclude "**/test-output/**"
|
||||
source.exclude "spring-core/graalvm/build/**" // only available on `main`
|
||||
source.exclude "spring-core-test/build/**" // only available on `main`
|
||||
allowlistFile = project.file("src/nohttp/allowlist.lines")
|
||||
def rootPath = file(rootDir).toPath()
|
||||
def projectDirs = allprojects.collect { it.projectDir } + "${rootDir}/buildSrc"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:focal-20220302
|
||||
FROM ubuntu:focal-20220826
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
|
||||
@@ -3,18 +3,18 @@ set -e
|
||||
|
||||
case "$1" in
|
||||
java8)
|
||||
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u322-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u322b06.tar.gz"
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/8u345+1/bellsoft-jdk8u345+1-linux-amd64.tar.gz"
|
||||
;;
|
||||
java11)
|
||||
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.14.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.14.1_1.tar.gz"
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/11.0.16+8/bellsoft-jdk11.0.16+8-linux-amd64.tar.gz"
|
||||
;;
|
||||
java17)
|
||||
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz"
|
||||
;;
|
||||
java18)
|
||||
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk18-2022-02-12-08-06-beta/OpenJDK18-jdk_x64_linux_hotspot_2022-02-12-08-06.tar.gz"
|
||||
;;
|
||||
*)
|
||||
java17)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/17.0.4+8/bellsoft-jdk17.0.4+8-linux-amd64.tar.gz"
|
||||
;;
|
||||
java18)
|
||||
echo "https://github.com/bell-sw/Liberica/releases/download/18.0.2+10/bellsoft-jdk18.0.2+10-linux-amd64.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
@@ -14,8 +14,6 @@ rm -rf /var/lib/apt/lists/*
|
||||
|
||||
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
|
||||
|
||||
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.2/concourse-release-scripts-0.3.2.jar
|
||||
|
||||
###########################################################
|
||||
# JAVA
|
||||
###########################################################
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
github-repo: "https://github.com/spring-projects/spring-framework.git"
|
||||
github-repo-name: "spring-projects/spring-framework"
|
||||
sonatype-staging-profile: "org.springframework"
|
||||
docker-hub-organization: "springci"
|
||||
artifactory-server: "https://repo.spring.io"
|
||||
branch: "5.3.x"
|
||||
@@ -7,4 +8,7 @@ milestone: "5.3.x"
|
||||
build-name: "spring-framework"
|
||||
pipeline-name: "spring-framework"
|
||||
concourse-url: "https://ci.spring.io"
|
||||
registry-mirror-host: docker.repo.spring.io
|
||||
registry-mirror-username: ((artifactory-username))
|
||||
registry-mirror-password: ((artifactory-password))
|
||||
task-timeout: 1h00m
|
||||
|
||||
+23
-10
@@ -12,7 +12,7 @@ anchors:
|
||||
SONATYPE_USERNAME: ((sonatype-username))
|
||||
SONATYPE_PASSWORD: ((sonatype-password))
|
||||
SONATYPE_URL: ((sonatype-url))
|
||||
SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
|
||||
SONATYPE_STAGING_PROFILE: ((sonatype-staging-profile))
|
||||
artifactory-task-params: &artifactory-task-params
|
||||
ARTIFACTORY_SERVER: ((artifactory-server))
|
||||
ARTIFACTORY_USERNAME: ((artifactory-username))
|
||||
@@ -24,6 +24,10 @@ anchors:
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: ((milestone))
|
||||
registry-mirror-vars: ®istry-mirror-vars
|
||||
registry-mirror-host: ((registry-mirror-host))
|
||||
registry-mirror-username: ((registry-mirror-username))
|
||||
registry-mirror-password: ((registry-mirror-password))
|
||||
slack-fail-params: &slack-fail-params
|
||||
text: >
|
||||
:concourse-failed: <https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!>
|
||||
@@ -41,6 +45,11 @@ anchors:
|
||||
GITHUB_TOKEN: ((github-ci-release-token))
|
||||
|
||||
resource_types:
|
||||
- name: registry-image
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/registry-image-resource
|
||||
tag: 1.5.0
|
||||
- name: artifactory-resource
|
||||
type: registry-image
|
||||
source:
|
||||
@@ -87,7 +96,7 @@ resources:
|
||||
branch: ((branch))
|
||||
paths: ["ci/images/*"]
|
||||
- name: ci-image
|
||||
type: docker-image
|
||||
type: registry-image
|
||||
icon: docker
|
||||
source:
|
||||
<<: *docker-resource-source
|
||||
@@ -157,13 +166,20 @@ resources:
|
||||
jobs:
|
||||
- name: build-ci-images
|
||||
plan:
|
||||
- get: ci-images-git-repo
|
||||
trigger: true
|
||||
- in_parallel:
|
||||
- get: git-repo
|
||||
- get: ci-images-git-repo
|
||||
trigger: true
|
||||
- task: build-ci-image
|
||||
privileged: true
|
||||
file: git-repo/ci/tasks/build-ci-image.yml
|
||||
output_mapping:
|
||||
image: ci-image
|
||||
vars:
|
||||
ci-image-name: ci-image
|
||||
<<: *registry-mirror-vars
|
||||
- put: ci-image
|
||||
params:
|
||||
build: ci-images-git-repo/ci/images
|
||||
dockerfile: ci-images-git-repo/ci/images/ci-image/Dockerfile
|
||||
image: ci-image/image.tar
|
||||
- name: build
|
||||
serial: true
|
||||
public: true
|
||||
@@ -340,7 +356,6 @@ jobs:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
@@ -385,7 +400,6 @@ jobs:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RC
|
||||
@@ -430,7 +444,6 @@ jobs:
|
||||
download_artifacts: true
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: RELEASE
|
||||
|
||||
@@ -6,11 +6,11 @@ CONFIG_DIR=git-repo/ci/config
|
||||
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
|
||||
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
|
||||
|
||||
java -jar /opt/concourse-release-scripts.jar \
|
||||
java -jar /concourse-release-scripts.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
|
||||
publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
|
||||
|
||||
java -jar /opt/concourse-release-scripts.jar \
|
||||
java -jar /concourse-release-scripts.jar \
|
||||
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
|
||||
promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
|
||||
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
|
||||
java -jar /opt/concourse-release-scripts.jar syncToCentral "RELEASE" $BUILD_INFO_LOCATION || { exit 1; }
|
||||
|
||||
echo "Sync complete"
|
||||
echo $version > version/version
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/oci-build-task
|
||||
tag: 0.9.1
|
||||
registry_mirror:
|
||||
host: ((registry-mirror-host))
|
||||
username: ((registry-mirror-username))
|
||||
password: ((registry-mirror-password))
|
||||
inputs:
|
||||
- name: ci-images-git-repo
|
||||
outputs:
|
||||
- name: image
|
||||
caches:
|
||||
- path: ci-image-cache
|
||||
params:
|
||||
CONTEXT: ci-images-git-repo/ci/images
|
||||
DOCKERFILE: ci-images-git-repo/ci/images/ci-image/Dockerfile
|
||||
DOCKER_HUB_AUTH: ((docker-hub-auth))
|
||||
run:
|
||||
path: /bin/sh
|
||||
args:
|
||||
- "-c"
|
||||
- |
|
||||
mkdir -p /root/.docker
|
||||
cat > /root/.docker/config.json <<EOF
|
||||
{ "auths": { "https://index.docker.io/v1/": { "auth": "$DOCKER_HUB_AUTH" }}}
|
||||
EOF
|
||||
build
|
||||
@@ -1,5 +1,10 @@
|
||||
---
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/concourse-release-scripts
|
||||
tag: '0.3.4'
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: artifactory-repo
|
||||
@@ -13,6 +18,6 @@ params:
|
||||
SONATYPE_USER:
|
||||
SONATYPE_PASSWORD:
|
||||
SONATYPE_URL:
|
||||
SONATYPE_STAGING_PROFILE_ID:
|
||||
SONATYPE_STAGING_PROFILE:
|
||||
run:
|
||||
path: git-repo/ci/scripts/promote-version.sh
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
version=5.3.17-SNAPSHOT
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
version=5.3.23
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
kotlin.stdlib.default.dependency=false
|
||||
kotlin.stdlib.default.dependency=false
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ asciidoctorPdf {
|
||||
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokkaHtmlMultiModule']) {
|
||||
group = "Distribution"
|
||||
description = "Builds -${archiveClassifier} archive containing api and reference " +
|
||||
"for deployment at https://docs.spring.io/spring-framework/docs."
|
||||
"for deployment at https://docs.spring.io/spring-framework/docs/."
|
||||
|
||||
archiveBaseName.set("spring-framework")
|
||||
archiveClassifier.set("docs")
|
||||
|
||||
@@ -72,6 +72,7 @@ eclipse.classpath.file.whenMerged {
|
||||
// Include project specific settings
|
||||
task eclipseSettings(type: Copy) {
|
||||
from rootProject.files(
|
||||
'src/eclipse/org.eclipse.core.resources.prefs',
|
||||
'src/eclipse/org.eclipse.jdt.core.prefs',
|
||||
'src/eclipse/org.eclipse.jdt.ui.prefs')
|
||||
into project.file('.settings/')
|
||||
@@ -79,6 +80,7 @@ task eclipseSettings(type: Copy) {
|
||||
}
|
||||
|
||||
task cleanEclipseSettings(type: Delete) {
|
||||
delete project.file('.settings/org.eclipse.core.resources.prefs')
|
||||
delete project.file('.settings/org.eclipse.jdt.core.prefs')
|
||||
delete project.file('.settings/org.eclipse.jdt.ui.prefs')
|
||||
}
|
||||
|
||||
+1
-1
@@ -31,6 +31,6 @@ You'll notice these files are already intentionally in .gitignore. The same poli
|
||||
|
||||
## FAQ
|
||||
|
||||
Q. What about IntelliJ IDEA's own [Gradle support](https://confluence.jetbrains.net/display/IDEADEV/Gradle+integration)?
|
||||
Q. What about IntelliJ IDEA's own [Gradle support](https://www.jetbrains.com/help/idea/gradle.html)?
|
||||
|
||||
A. Keep an eye on https://youtrack.jetbrains.com/issue/IDEA-53476
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
|
||||
/**
|
||||
* Integration tests for advice invocation order for advice configured via the
|
||||
@@ -52,7 +52,7 @@ class AopNamespaceHandlerAdviceOrderIntegrationTests {
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after returning");
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after throwing");
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class AopNamespaceHandlerAdviceOrderIntegrationTests {
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after returning", "after");
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after throwing", "after");
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
|
||||
/**
|
||||
* Integration tests for advice invocation order for advice configured via
|
||||
@@ -65,8 +65,7 @@ class AspectJAutoProxyAdviceOrderIntegrationTests {
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(
|
||||
() -> echo.echo(new Exception()));
|
||||
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
|
||||
}
|
||||
}
|
||||
@@ -95,8 +94,7 @@ class AspectJAutoProxyAdviceOrderIntegrationTests {
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
|
||||
|
||||
aspect.invocations.clear();
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(
|
||||
() -> echo.echo(new Exception()));
|
||||
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
|
||||
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
|
||||
/**
|
||||
* Integration tests for the @EnableCaching annotation.
|
||||
@@ -62,8 +62,7 @@ class EnableCachingIntegrationTests {
|
||||
// this test is a bit fragile, but gets the job done, proving that an
|
||||
// attempt was made to look up the AJ aspect. It's due to classpath issues
|
||||
// in .integration-tests that it's not found.
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(
|
||||
ctx::refresh)
|
||||
assertThatException().isThrownBy(ctx::refresh)
|
||||
.withMessageContaining("AspectJCachingConfiguration");
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,7 +45,7 @@ import org.springframework.transaction.interceptor.BeanFactoryTransactionAttribu
|
||||
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
|
||||
/**
|
||||
* Integration tests for the @EnableTransactionManagement annotation.
|
||||
@@ -98,7 +98,7 @@ class EnableTransactionManagementIntegrationTests {
|
||||
// this test is a bit fragile, but gets the job done, proving that an
|
||||
// attempt was made to look up the AJ aspect. It's due to classpath issues
|
||||
// in .integration-tests that it's not found.
|
||||
assertThatExceptionOfType(Exception.class)
|
||||
assertThatException()
|
||||
.isThrownBy(ctx::refresh)
|
||||
.withMessageContaining("AspectJJtaTransactionManagementConfiguration");
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.8.1"
|
||||
id "io.spring.ge.conventions" version "0.0.9"
|
||||
id "com.gradle.enterprise" version "3.10.2"
|
||||
id "io.spring.ge.conventions" version "0.0.10"
|
||||
}
|
||||
|
||||
include "spring-aop"
|
||||
|
||||
@@ -63,7 +63,7 @@ public interface Joinpoint {
|
||||
/**
|
||||
* Return the static part of this joinpoint.
|
||||
* <p>The static part is an accessible object on which a chain of
|
||||
* interceptors are installed.
|
||||
* interceptors is installed.
|
||||
*/
|
||||
@Nonnull
|
||||
AccessibleObject getStaticPart();
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ public interface IntroductionAwareMethodMatcher extends MethodMatcher {
|
||||
* @param targetClass the target class
|
||||
* @param hasIntroductions {@code true} if the object on whose behalf we are
|
||||
* asking is the subject on one or more introductions; {@code false} otherwise
|
||||
* @return whether or not this method matches statically
|
||||
* @return whether this method matches statically
|
||||
*/
|
||||
boolean matches(Method method, Class<?> targetClass, boolean hasIntroductions);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public interface MethodMatcher {
|
||||
* will be made.
|
||||
* @param method the candidate method
|
||||
* @param targetClass the target class
|
||||
* @return whether or not this method matches statically
|
||||
* @return whether this method matches statically
|
||||
*/
|
||||
boolean matches(Method method, Class<?> targetClass);
|
||||
|
||||
@@ -70,7 +70,7 @@ public interface MethodMatcher {
|
||||
* runtime even if the 2-arg matches method returns {@code true}?
|
||||
* <p>Can be invoked when an AOP proxy is created, and need not be invoked
|
||||
* again before each method invocation,
|
||||
* @return whether or not a runtime match via the 3-arg
|
||||
* @return whether a runtime match via the 3-arg
|
||||
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method
|
||||
* is required if static matching passed
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.aop;
|
||||
|
||||
/**
|
||||
* Marker interface implemented by all AOP proxies. Used to detect
|
||||
* whether or not objects are Spring-generated proxies.
|
||||
* whether objects are Spring-generated proxies.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 2.0.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -368,7 +368,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
* to which argument name. There are multiple strategies for determining
|
||||
* this binding, which are arranged in a ChainOfResponsibility.
|
||||
*/
|
||||
public final synchronized void calculateArgumentBindings() {
|
||||
public final void calculateArgumentBindings() {
|
||||
// The simple case... nothing to bind.
|
||||
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
|
||||
return;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -378,7 +378,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to evaluate join point for arguments " + Arrays.asList(args) +
|
||||
logger.debug("Failed to evaluate join point for arguments " + Arrays.toString(args) +
|
||||
" - falling back to non-match", ex);
|
||||
}
|
||||
return false;
|
||||
|
||||
+2
-2
@@ -39,7 +39,7 @@ import org.springframework.lang.Nullable;
|
||||
public interface AspectJAdvisorFactory {
|
||||
|
||||
/**
|
||||
* Determine whether or not the given class is an aspect, as reported
|
||||
* Determine whether the given class is an aspect, as reported
|
||||
* by AspectJ's {@link org.aspectj.lang.reflect.AjTypeSystem}.
|
||||
* <p>Will simply return {@code false} if the supposed aspect is
|
||||
* invalid (such as an extension of a concrete aspect class).
|
||||
@@ -47,7 +47,7 @@ public interface AspectJAdvisorFactory {
|
||||
* such as those with unsupported instantiation models.
|
||||
* Use the {@link #validate} method to handle these cases if necessary.
|
||||
* @param clazz the supposed annotation-style AspectJ class
|
||||
* @return whether or not this class is recognized by AspectJ as an aspect class
|
||||
* @return whether this class is recognized by AspectJ as an aspect class
|
||||
*/
|
||||
boolean isAspect(Class<?> clazz);
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.util.ClassUtils;
|
||||
/**
|
||||
* AspectJ-based proxy factory, allowing for programmatic building
|
||||
* of proxies which include AspectJ aspects (code style as well
|
||||
* Java 5 annotation style).
|
||||
* annotation style).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -60,14 +60,14 @@ public class AspectMetadata implements Serializable {
|
||||
private final Class<?> aspectClass;
|
||||
|
||||
/**
|
||||
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
|
||||
* Re-resolved on deserialization since it isn't serializable itself.
|
||||
* AspectJ reflection information.
|
||||
* <p>Re-resolved on deserialization since it isn't serializable itself.
|
||||
*/
|
||||
private transient AjType<?> ajType;
|
||||
|
||||
/**
|
||||
* Spring AOP pointcut corresponding to the per clause of the
|
||||
* aspect. Will be the Pointcut.TRUE canonical instance in the
|
||||
* aspect. Will be the {@code Pointcut.TRUE} canonical instance in the
|
||||
* case of a singleton, otherwise an AspectJExpressionPointcut.
|
||||
*/
|
||||
private final Pointcut perClausePointcut;
|
||||
|
||||
+2
-2
@@ -60,8 +60,8 @@ public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProx
|
||||
* <li>Otherwise the advice declared first gets highest precedence (i.e., runs
|
||||
* first).</li>
|
||||
* </ul>
|
||||
* <p><b>Important:</b> Advisors are sorted in precedence order, from highest
|
||||
* precedence to lowest. "On the way in" to a join point, the highest precedence
|
||||
* <p><b>Important:</b> Advisors are sorted in precedence order, from the highest
|
||||
* precedence to the lowest. "On the way in" to a join point, the highest precedence
|
||||
* advisor should run first. "On the way out" of a join point, the highest
|
||||
* precedence advisor should run last.
|
||||
*/
|
||||
|
||||
@@ -314,7 +314,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all of the given advisors to this proxy configuration.
|
||||
* Add all the given advisors to this proxy configuration.
|
||||
* @param advisors the advisors to register
|
||||
*/
|
||||
public void addAdvisors(Advisor... advisors) {
|
||||
@@ -322,7 +322,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all of the given advisors to this proxy configuration.
|
||||
* Add all the given advisors to this proxy configuration.
|
||||
* @param advisors the advisors to register
|
||||
*/
|
||||
public void addAdvisors(Collection<Advisor> advisors) {
|
||||
|
||||
@@ -134,7 +134,7 @@ public abstract class AopProxyUtils {
|
||||
if (targetClass.isInterface()) {
|
||||
advised.setInterfaces(targetClass);
|
||||
}
|
||||
else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
|
||||
else if (Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
|
||||
advised.setInterfaces(targetClass.getInterfaces());
|
||||
}
|
||||
specifiedInterfaces = advised.getProxiedInterfaces();
|
||||
@@ -245,18 +245,4 @@ public abstract class AopProxyUtils {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied {@link Class} is a JVM-generated implementation
|
||||
* class for a lambda expression or method reference.
|
||||
* <p>This method makes a best-effort attempt at determining this, based on
|
||||
* checks that work on modern, main stream JVMs.
|
||||
* @param clazz the class to check
|
||||
* @return {@code true} if the class is a lambda implementation class
|
||||
* @since 5.3.16
|
||||
*/
|
||||
static boolean isLambda(Class<?> clazz) {
|
||||
return (clazz.isSynthetic() && (clazz.getSuperclass() == Object.class) &&
|
||||
(clazz.getInterfaces().length > 0) && clazz.getName().contains("$$Lambda"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -375,6 +375,22 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the given method with a CGLIB MethodProxy if possible, falling back
|
||||
* to a plain reflection invocation in case of a fast-class generation failure.
|
||||
*/
|
||||
@Nullable
|
||||
private static Object invokeMethod(@Nullable Object target, Method method, Object[] args, MethodProxy methodProxy)
|
||||
throws Throwable {
|
||||
try {
|
||||
return methodProxy.invoke(target, args);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
CglibMethodInvocation.logFastClassGenerationFailure(method);
|
||||
return AopUtils.invokeJoinpointUsingReflection(target, method, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a return value. Wraps a return of {@code this} if necessary to be the
|
||||
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
|
||||
@@ -425,7 +441,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
@Override
|
||||
@Nullable
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object retVal = methodProxy.invoke(this.target, args);
|
||||
Object retVal = invokeMethod(this.target, method, args, methodProxy);
|
||||
return processReturnType(proxy, this.target, method, retVal);
|
||||
}
|
||||
}
|
||||
@@ -450,7 +466,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Object oldProxy = null;
|
||||
try {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
Object retVal = methodProxy.invoke(this.target, args);
|
||||
Object retVal = invokeMethod(this.target, method, args, methodProxy);
|
||||
return processReturnType(proxy, this.target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -478,7 +494,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object target = this.targetSource.getTarget();
|
||||
try {
|
||||
Object retVal = methodProxy.invoke(target, args);
|
||||
Object retVal = invokeMethod(target, method, args, methodProxy);
|
||||
return processReturnType(proxy, target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -508,7 +524,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Object target = this.targetSource.getTarget();
|
||||
try {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
Object retVal = methodProxy.invoke(target, args);
|
||||
Object retVal = invokeMethod(target, method, args, methodProxy);
|
||||
return processReturnType(proxy, target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
@@ -685,13 +701,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
// it does nothing but a reflective operation on the target, and no hot
|
||||
// swapping or fancy proxying.
|
||||
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
|
||||
try {
|
||||
retVal = methodProxy.invoke(target, argsToUse);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
CglibMethodInvocation.logFastClassGenerationFailure(method);
|
||||
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
|
||||
}
|
||||
retVal = invokeMethod(target, method, argsToUse, methodProxy);
|
||||
}
|
||||
else {
|
||||
// We need to create a method invocation...
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import java.lang.reflect.Proxy;
|
||||
|
||||
import org.springframework.aop.SpringProxy;
|
||||
import org.springframework.core.NativeDetector;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
|
||||
@@ -60,7 +61,7 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
throw new AopConfigException("TargetSource cannot determine target class: " +
|
||||
"Either an interface or a target is required for proxy creation.");
|
||||
}
|
||||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
|
||||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
|
||||
return new JdkDynamicAopProxy(config);
|
||||
}
|
||||
return new ObjenesisCglibAopProxy(config);
|
||||
|
||||
@@ -72,8 +72,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
* NOTE: We could avoid the code duplication between this class and the CGLIB
|
||||
* proxies by refactoring "invoke" into a template method. However, this approach
|
||||
* adds at least 10% performance overhead versus a copy-paste solution, so we sacrifice
|
||||
* elegance for performance. (We have a good test suite to ensure that the different
|
||||
* proxies behave the same :-)
|
||||
* elegance for performance (we have a good test suite to ensure that the different
|
||||
* proxies behave the same :-)).
|
||||
* This way, we can also more easily take advantage of minor optimizations in each class.
|
||||
*/
|
||||
|
||||
@@ -198,7 +198,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
// Get the interception chain for this method.
|
||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
||||
|
||||
// Check whether we have any advice. If we don't, we can fallback on direct
|
||||
// Check whether we have any advice. If we don't, we can fall back on direct
|
||||
// reflective invocation of the target, and avoid creating a MethodInvocation.
|
||||
if (chain.isEmpty()) {
|
||||
// We can skip creating a MethodInvocation: just invoke the target directly
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,7 +50,7 @@ import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.FactoryBean} implementation that builds an
|
||||
* AOP proxy based on beans in Spring {@link org.springframework.beans.factory.BeanFactory}.
|
||||
* AOP proxy based on beans in a Spring {@link org.springframework.beans.factory.BeanFactory}.
|
||||
*
|
||||
* <p>{@link org.aopalliance.intercept.MethodInterceptor MethodInterceptors} and
|
||||
* {@link org.springframework.aop.Advisor Advisors} are identified by a list of bean
|
||||
@@ -61,10 +61,11 @@ import org.springframework.util.ObjectUtils;
|
||||
*
|
||||
* <p>Global interceptors and advisors can be added at the factory level. The specified
|
||||
* ones are expanded in an interceptor list where an "xxx*" entry is included in the
|
||||
* list, matching the given prefix with the bean names (e.g. "global*" would match
|
||||
* both "globalBean1" and "globalBean2", "*" all defined interceptors). The matching
|
||||
* interceptors get applied according to their returned order value, if they implement
|
||||
* the {@link org.springframework.core.Ordered} interface.
|
||||
* list, matching the given prefix with the bean names — for example, "global*"
|
||||
* would match both "globalBean1" and "globalBean2"; whereas, "*" would match all
|
||||
* defined interceptors. The matching interceptors get applied according to their
|
||||
* returned order value, if they implement the {@link org.springframework.core.Ordered}
|
||||
* interface.
|
||||
*
|
||||
* <p>Creates a JDK proxy when proxy interfaces are given, and a CGLIB proxy for the
|
||||
* actual target class if not. Note that the latter will only work if the target class
|
||||
@@ -75,7 +76,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* This won't work for existing prototype references, which are independent. However,
|
||||
* it will work for prototypes subsequently obtained from the factory. Changes to
|
||||
* interception will work immediately on singletons (including existing references).
|
||||
* However, to change interfaces or target it's necessary to obtain a new instance
|
||||
* However, to change interfaces or a target it's necessary to obtain a new instance
|
||||
* from the factory. This means that singleton instances obtained from the factory
|
||||
* do not have the same object identity. However, they do have the same interceptors
|
||||
* and target, and changing any reference will change all objects.
|
||||
@@ -406,7 +407,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
if (namedBeanClass != null) {
|
||||
return (Advisor.class.isAssignableFrom(namedBeanClass) || Advice.class.isAssignableFrom(namedBeanClass));
|
||||
}
|
||||
// Treat it as an target bean if we can't tell.
|
||||
// Treat it as a target bean if we can't tell.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not determine type of bean with name '" + beanName +
|
||||
"' - assuming it is neither an Advisor nor an Advice");
|
||||
@@ -424,7 +425,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
if (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {
|
||||
if (this.beanFactory == null) {
|
||||
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
|
||||
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
|
||||
"- cannot resolve interceptor names " + Arrays.toString(this.interceptorNames));
|
||||
}
|
||||
|
||||
// Globals can't be last unless we specified a targetSource using the property...
|
||||
|
||||
+8
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,6 +50,7 @@ import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostP
|
||||
import org.springframework.core.SmartClassLoader;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -85,6 +86,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Sam Brannen
|
||||
* @since 13.10.2003
|
||||
* @see #setInterceptorNames
|
||||
* @see #getAdvicesAndAdvisorsForBean
|
||||
@@ -117,7 +119,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
|
||||
|
||||
/**
|
||||
* Indicates whether or not the proxy should be frozen. Overridden from super
|
||||
* Indicates whether the proxy should be frozen. Overridden from super
|
||||
* to prevent the configuration from becoming frozen too early.
|
||||
*/
|
||||
private boolean freezeProxy = false;
|
||||
@@ -143,9 +145,9 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
|
||||
|
||||
/**
|
||||
* Set whether or not the proxy should be frozen, preventing advice
|
||||
* Set whether the proxy should be frozen, preventing advice
|
||||
* from being added to it once it is created.
|
||||
* <p>Overridden from the super class to prevent the proxy configuration
|
||||
* <p>Overridden from the superclass to prevent the proxy configuration
|
||||
* from being frozen before the proxy is created.
|
||||
*/
|
||||
@Override
|
||||
@@ -442,8 +444,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
proxyFactory.copyFrom(this);
|
||||
|
||||
if (proxyFactory.isProxyTargetClass()) {
|
||||
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
|
||||
if (Proxy.isProxyClass(beanClass)) {
|
||||
// Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
|
||||
if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
|
||||
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
|
||||
for (Class<?> ifc : beanClass.getInterfaces()) {
|
||||
proxyFactory.addInterface(ifc);
|
||||
|
||||
+2
-2
@@ -56,7 +56,7 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
|
||||
protected transient Log defaultLogger = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
* Indicates whether or not proxy class names should be hidden when using dynamic loggers.
|
||||
* Indicates whether proxy class names should be hidden when using dynamic loggers.
|
||||
* @see #setUseDynamicLogger
|
||||
*/
|
||||
private boolean hideProxyClassNames = false;
|
||||
@@ -119,7 +119,7 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
|
||||
|
||||
|
||||
/**
|
||||
* Determines whether or not logging is enabled for the particular {@code MethodInvocation}.
|
||||
* Determines whether logging is enabled for the particular {@code MethodInvocation}.
|
||||
* If not, the method invocation proceeds as normal, otherwise the method invocation is passed
|
||||
* to the {@code invokeUnderTrace} method for handling.
|
||||
* @see #invokeUnderTrace(org.aopalliance.intercept.MethodInvocation, org.apache.commons.logging.Log)
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ public interface AsyncUncaughtExceptionHandler {
|
||||
* Handle the given uncaught exception thrown from an asynchronous method.
|
||||
* @param ex the exception thrown from the asynchronous method
|
||||
* @param method the asynchronous method
|
||||
* @param params the parameters used to invoked the method
|
||||
* @param params the parameters used to invoke the method
|
||||
*/
|
||||
void handleUncaughtException(Throwable ex, Method method, Object... params);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -183,8 +183,8 @@ public abstract class AopUtils {
|
||||
* may be {@code DefaultFoo}. In this case, the method may be
|
||||
* {@code DefaultFoo.bar()}. This enables attributes on that method to be found.
|
||||
* <p><b>NOTE:</b> In contrast to {@link org.springframework.util.ClassUtils#getMostSpecificMethod},
|
||||
* this method resolves Java 5 bridge methods in order to retrieve attributes
|
||||
* from the <i>original</i> method definition.
|
||||
* this method resolves bridge methods in order to retrieve attributes from
|
||||
* the <i>original</i> method definition.
|
||||
* @param method the method to be invoked, which may come from an interface
|
||||
* @param targetClass the target class for the current invocation.
|
||||
* May be {@code null} or may not even implement the method.
|
||||
@@ -217,7 +217,7 @@ public abstract class AopUtils {
|
||||
* out a pointcut for a class.
|
||||
* @param pc the static or dynamic pointcut to check
|
||||
* @param targetClass the class to test
|
||||
* @param hasIntroductions whether or not the advisor chain
|
||||
* @param hasIntroductions whether the advisor chain
|
||||
* for this bean includes any introductions
|
||||
* @return whether the pointcut can apply on any method
|
||||
*/
|
||||
@@ -261,7 +261,7 @@ public abstract class AopUtils {
|
||||
/**
|
||||
* Can the given advisor apply at all on the given class?
|
||||
* This is an important test as it can be used to optimize
|
||||
* out a advisor for a class.
|
||||
* out an advisor for a class.
|
||||
* @param advisor the advisor to check
|
||||
* @param targetClass class we're testing
|
||||
* @return whether the pointcut can apply on any method
|
||||
@@ -272,11 +272,11 @@ public abstract class AopUtils {
|
||||
|
||||
/**
|
||||
* Can the given advisor apply at all on the given class?
|
||||
* <p>This is an important test as it can be used to optimize out a advisor for a class.
|
||||
* <p>This is an important test as it can be used to optimize out an advisor for a class.
|
||||
* This version also takes into account introductions (for IntroductionAwareMethodMatchers).
|
||||
* @param advisor the advisor to check
|
||||
* @param targetClass class we're testing
|
||||
* @param hasIntroductions whether or not the advisor chain for this bean includes
|
||||
* @param hasIntroductions whether the advisor chain for this bean includes
|
||||
* any introductions
|
||||
* @return whether the pointcut can apply on any method
|
||||
*/
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor imple
|
||||
|
||||
/**
|
||||
* Create an empty DefaultPointcutAdvisor.
|
||||
* <p>Advice must be set before use using setter methods.
|
||||
* <p>Advice must be set before using setter methods.
|
||||
* Pointcut will normally be set also, but defaults to {@code Pointcut.TRUE}.
|
||||
*/
|
||||
public DefaultPointcutAdvisor() {
|
||||
|
||||
@@ -90,7 +90,7 @@ public abstract class MethodMatchers {
|
||||
* @param targetClass the target class
|
||||
* @param hasIntroductions {@code true} if the object on whose behalf we are
|
||||
* asking is the subject on one or more introductions; {@code false} otherwise
|
||||
* @return whether or not this method matches statically
|
||||
* @return whether this method matches statically
|
||||
*/
|
||||
public static boolean matches(MethodMatcher mm, Method method, Class<?> targetClass, boolean hasIntroductions) {
|
||||
Assert.notNull(mm, "MethodMatcher must not be null");
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,8 +24,7 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple ClassFilter that looks for a specific Java 5 annotation
|
||||
* being present on a class.
|
||||
* Simple ClassFilter that looks for a specific annotation being present on a class.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,9 +26,8 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple Pointcut that looks for a specific Java 5 annotation
|
||||
* being present on a {@link #forClassAnnotation class} or
|
||||
* {@link #forMethodAnnotation method}.
|
||||
* Simple {@link Pointcut} that looks for a specific annotation being present on a
|
||||
* {@linkplain #forClassAnnotation class} or {@linkplain #forMethodAnnotation method}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,9 +27,10 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple MethodMatcher that looks for a specific Java 5 annotation
|
||||
* being present on a method (checking both the method on the invoked
|
||||
* interface, if any, and the corresponding method on the target class).
|
||||
* Simple {@link org.springframework.aop.MethodMatcher MethodMatcher} that looks
|
||||
* for a specific annotation being present on a method (checking both the method
|
||||
* on the invoked interface, if any, and the corresponding method on the target
|
||||
* class).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import org.springframework.lang.Nullable;
|
||||
* {@link AbstractPrototypeBasedTargetSource} can be used to create objects
|
||||
* in order to put them into the pool.
|
||||
*
|
||||
* <p>Subclasses must also implement some of the monitoring methods from the
|
||||
* <p>Subclasses must also implement some monitoring methods from the
|
||||
* {@link PoolingConfig} interface. The {@link #getPoolingConfigMixin()} method
|
||||
* makes these stats available on proxied objects through an IntroductionAdvisor.
|
||||
*
|
||||
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Additional parameter name discover tests that need Java 5.
|
||||
* Yes this will re-run the tests from the superclass, but that
|
||||
* doesn't matter in the grand scheme of things...
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AspectJAdviceParameterNameDiscoverAnnotationTests extends AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
public void testAnnotationBinding() {
|
||||
assertParameterNames(getMethod("pjpAndAnAnnotation"),
|
||||
"execution(* *(..)) && @annotation(ann)",
|
||||
new String[] {"thisJoinPoint","ann"});
|
||||
}
|
||||
|
||||
|
||||
public void pjpAndAnAnnotation(ProceedingJoinPoint pjp, MyAnnotation ann) {}
|
||||
|
||||
@interface MyAnnotation {}
|
||||
|
||||
}
|
||||
+259
-195
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,8 +17,11 @@
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException;
|
||||
@@ -27,200 +30,265 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link AspectJAdviceParameterNameDiscoverer} class.
|
||||
*
|
||||
* <p>See also {@link TigerAspectJAdviceParameterNameDiscovererTests} for tests relating to annotations.
|
||||
* Unit tests for {@link AspectJAdviceParameterNameDiscoverer}.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class AspectJAdviceParameterNameDiscovererTests {
|
||||
class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
public void testNoArgs() {
|
||||
assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]);
|
||||
@Nested
|
||||
class StandardTests {
|
||||
|
||||
@Test
|
||||
void noArgs() {
|
||||
assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void joinPointOnly() {
|
||||
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void joinPointStaticPartOnly() {
|
||||
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void twoJoinPoints() {
|
||||
assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneThrowable() {
|
||||
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneJPAndOneThrowable() {
|
||||
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneJPAndTwoThrowables() {
|
||||
assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class,
|
||||
"Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwableNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
|
||||
@Test
|
||||
void returning() {
|
||||
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousReturning() {
|
||||
assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class,
|
||||
"Binding of returning parameter 'obj' is ambiguous, there are 2 candidates.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void returningNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisBindingWithBadPointcutExpressions() {
|
||||
assertException(getMethod("oneObject"), "this(", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
assertException(getMethod("oneObject"), "this(x && foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetBindingWithBadPointcutExpressions() {
|
||||
assertException(getMethod("oneObject"), "target(", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
assertException(getMethod("oneObject"), "target(x && foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsBindingOneObject() {
|
||||
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsBindingOneObjectTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ambiguousArgsBinding() {
|
||||
assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them");
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsOnePrimitive() {
|
||||
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void argsOnePrimitiveOneObject() {
|
||||
assertException(getMethod("oneObjectOnePrimitive"), "args(count,obj)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate variable names but only one candidate binding slot when matching primitive args");
|
||||
}
|
||||
|
||||
@Test
|
||||
void thisAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwingAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
|
||||
new String[] {"ex", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void allTogetherNow() {
|
||||
assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex",
|
||||
new String[] {"thisJoinPoint", "ex", "x", "foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void referenceBinding() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
void referenceBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"});
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoinPointOnly() {
|
||||
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
|
||||
}
|
||||
/**
|
||||
* Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer}.
|
||||
*/
|
||||
@Nested
|
||||
class AnnotationTests {
|
||||
|
||||
@Test
|
||||
public void testJoinPointStaticPartOnly() {
|
||||
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
|
||||
}
|
||||
@Test
|
||||
void atThis() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoJoinPoints() {
|
||||
assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
@Test
|
||||
void atTarget() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneThrowable() {
|
||||
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
|
||||
}
|
||||
@Test
|
||||
void atArgs() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneJPAndOneThrowable() {
|
||||
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
|
||||
}
|
||||
@Test
|
||||
void atWithin() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneJPAndTwoThrowables() {
|
||||
assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class,
|
||||
"Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2");
|
||||
}
|
||||
@Test
|
||||
void atWithincode() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrowableNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
@Test
|
||||
void atAnnotation() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturning() {
|
||||
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
|
||||
}
|
||||
@Test
|
||||
void ambiguousAnnotationTwoVars() {
|
||||
assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class,
|
||||
"Found 2 potential annotation variable(s), and 2 potential argument slots");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousReturning() {
|
||||
assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class,
|
||||
"Binding of returning parameter 'obj' is ambiguous, there are 2 candidates.");
|
||||
}
|
||||
@Test
|
||||
void ambiguousAnnotationOneVar() {
|
||||
assertException(getMethod("oneAnnotation"),"@annotation(a) && @this(x)",IllegalArgumentException.class,
|
||||
"Found 2 candidate annotation binding variables but only one potential argument binding slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningNoCandidates() {
|
||||
assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class,
|
||||
"Not enough arguments in method to satisfy binding of returning and throwing variables");
|
||||
}
|
||||
@Test
|
||||
void annotationMedley() {
|
||||
assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
|
||||
null, "ex", new String[] {"ex", "foo", "count", "a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
|
||||
}
|
||||
@Test
|
||||
void annotationBinding() {
|
||||
assertParameterNames(getMethod("pjpAndAnAnnotation"),
|
||||
"execution(* *(..)) && @annotation(ann)",
|
||||
new String[] {"thisJoinPoint","ann"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisBindingWithBadPointcutExpressions() {
|
||||
assertException(getMethod("oneObject"), "this(", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
assertException(getMethod("oneObject"), "this(x && foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetBindingOneCandidate() {
|
||||
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"});
|
||||
assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetBindingTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetBindingWithBadPointcutExpressions() {
|
||||
assertException(getMethod("oneObject"), "target(", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
assertException(getMethod("oneObject"), "target(x && foo()", IllegalStateException.class,
|
||||
"Failed to bind all argument names: 1 argument(s) could not be bound");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgsBindingOneObject() {
|
||||
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgsBindingOneObjectTwoCandidates() {
|
||||
assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousArgsBinding() {
|
||||
assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class,
|
||||
"Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgsOnePrimitive() {
|
||||
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgsOnePrimitiveOneObject() {
|
||||
assertException(getMethod("oneObjectOnePrimitive"), "args(count,obj)", AmbiguousBindingException.class,
|
||||
"Found 2 candidate variable names but only one candidate binding slot when matching primitive args");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThisAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
|
||||
new String[] {"obj", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrowingAndPrimitive() {
|
||||
assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
|
||||
new String[] {"ex", "count"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllTogetherNow() {
|
||||
assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex",
|
||||
new String[] {"thisJoinPoint", "ex", "x", "foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceBinding() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceBindingWithAlternateTokenizations() {
|
||||
assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"});
|
||||
assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"});
|
||||
}
|
||||
|
||||
|
||||
protected Method getMethod(String name) {
|
||||
private Method getMethod(String name) {
|
||||
// Assumes no overloading of test methods...
|
||||
Method[] candidates = getClass().getMethods();
|
||||
for (Method candidate : candidates) {
|
||||
for (Method candidate : getClass().getMethods()) {
|
||||
if (candidate.getName().equals(name)) {
|
||||
return candidate;
|
||||
}
|
||||
@@ -228,11 +296,11 @@ public class AspectJAdviceParameterNameDiscovererTests {
|
||||
throw new AssertionError("Bad test specification, no method '" + name + "' found in test class");
|
||||
}
|
||||
|
||||
protected void assertParameterNames(Method method, String pointcut, String[] parameterNames) {
|
||||
private void assertParameterNames(Method method, String pointcut, String[] parameterNames) {
|
||||
assertParameterNames(method, pointcut, null, null, parameterNames);
|
||||
}
|
||||
|
||||
protected void assertParameterNames(
|
||||
private void assertParameterNames(
|
||||
Method method, String pointcut, String returning, String throwing, String[] parameterNames) {
|
||||
|
||||
assertThat(parameterNames.length).as("bad test specification, must have same number of parameter names as method arguments").isEqualTo(method.getParameterCount());
|
||||
@@ -243,8 +311,8 @@ public class AspectJAdviceParameterNameDiscovererTests {
|
||||
discoverer.setThrowingName(throwing);
|
||||
String[] discoveredNames = discoverer.getParameterNames(method);
|
||||
|
||||
String formattedExpectedNames = format(parameterNames);
|
||||
String formattedActualNames = format(discoveredNames);
|
||||
String formattedExpectedNames = Arrays.toString(parameterNames);
|
||||
String formattedActualNames = Arrays.toString(discoveredNames);
|
||||
|
||||
assertThat(discoveredNames.length).as("Expecting " + parameterNames.length + " parameter names in return set '" +
|
||||
formattedExpectedNames + "', but found " + discoveredNames.length +
|
||||
@@ -257,37 +325,23 @@ public class AspectJAdviceParameterNameDiscovererTests {
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertException(Method method, String pointcut, Class<? extends Throwable> exceptionType, String message) {
|
||||
private void assertException(Method method, String pointcut, Class<? extends Throwable> exceptionType, String message) {
|
||||
assertException(method, pointcut, null, null, exceptionType, message);
|
||||
}
|
||||
|
||||
protected void assertException(Method method, String pointcut, String returning,
|
||||
private void assertException(Method method, String pointcut, String returning,
|
||||
String throwing, Class<? extends Throwable> exceptionType, String message) {
|
||||
|
||||
AspectJAdviceParameterNameDiscoverer discoverer = new AspectJAdviceParameterNameDiscoverer(pointcut);
|
||||
discoverer.setRaiseExceptions(true);
|
||||
discoverer.setReturningName(returning);
|
||||
discoverer.setThrowingName(throwing);
|
||||
assertThatExceptionOfType(exceptionType).isThrownBy(() ->
|
||||
discoverer.getParameterNames(method))
|
||||
assertThatExceptionOfType(exceptionType)
|
||||
.isThrownBy(() -> discoverer.getParameterNames(method))
|
||||
.withMessageContaining(message);
|
||||
}
|
||||
|
||||
|
||||
private static String format(String[] names) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('(');
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
sb.append(names[i]);
|
||||
if ((i + 1) < names.length) {
|
||||
sb.append(',');
|
||||
}
|
||||
}
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
// Methods to discover parameter names for
|
||||
|
||||
public void noArgs() {
|
||||
@@ -329,4 +383,14 @@ public class AspectJAdviceParameterNameDiscovererTests {
|
||||
public void theBigOne(JoinPoint jp, Throwable x, int y, Object foo) {
|
||||
}
|
||||
|
||||
public void oneAnnotation(MyAnnotation ann) {}
|
||||
|
||||
public void twoAnnotations(MyAnnotation ann, MyAnnotation anotherAnn) {}
|
||||
|
||||
public void annotationMedley(Throwable t, Object foo, int x, MyAnnotation ma) {}
|
||||
|
||||
public void pjpAndAnAnnotation(ProceedingJoinPoint pjp, MyAnnotation ann) {}
|
||||
|
||||
@interface MyAnnotation {}
|
||||
|
||||
}
|
||||
|
||||
+286
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,9 @@
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
@@ -25,6 +28,8 @@ import org.aspectj.weaver.tools.PointcutPrimitive;
|
||||
import org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import test.annotation.EmptySpringAnnotation;
|
||||
import test.annotation.transaction.Tx;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
@@ -56,12 +61,19 @@ public class AspectJExpressionPointcutTests {
|
||||
|
||||
private Method setSomeNumber;
|
||||
|
||||
private final Map<String, Method> methodsOnHasGeneric = new HashMap<>();
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws NoSuchMethodException {
|
||||
getAge = TestBean.class.getMethod("getAge");
|
||||
setAge = TestBean.class.getMethod("setAge", int.class);
|
||||
setSomeNumber = TestBean.class.getMethod("setSomeNumber", Number.class);
|
||||
|
||||
// Assumes no overloading
|
||||
for (Method method : HasGeneric.class.getMethods()) {
|
||||
methodsOnHasGeneric.put(method.getName(), method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -299,6 +311,279 @@ public class AspectJExpressionPointcutTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchGenericArgument() {
|
||||
String expression = "execution(* set*(java.util.List<org.springframework.beans.testfixture.beans.TestBean>) )";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
// TODO this will currently map, would be nice for optimization
|
||||
//assertTrue(ajexp.matches(HasGeneric.class));
|
||||
//assertFalse(ajexp.matches(TestBean.class));
|
||||
|
||||
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
|
||||
assertThat(ajexp.matches(takesGenericList, HasGeneric.class)).isTrue();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isTrue();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchVarargs() throws Exception {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
class MyTemplate {
|
||||
public int queryForInt(String sql, Object... params) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
String expression = "execution(int *.*(String, Object...))";
|
||||
AspectJExpressionPointcut jdbcVarArgs = new AspectJExpressionPointcut();
|
||||
jdbcVarArgs.setExpression(expression);
|
||||
|
||||
assertThat(jdbcVarArgs.matches(
|
||||
MyTemplate.class.getMethod("queryForInt", String.class, Object[].class),
|
||||
MyTemplate.class)).isTrue();
|
||||
|
||||
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
|
||||
assertThat(jdbcVarArgs.matches(takesGenericList, HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(getAge, TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithAtWithin() throws Exception {
|
||||
String expression = "@within(test.annotation.transaction.Tx)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithoutBinding() throws Exception {
|
||||
String expression = "within(@test.annotation.transaction.Tx *)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithSubpackageWildcard() throws Exception {
|
||||
String expression = "within(@(test.annotation..*) *)";
|
||||
AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertThat(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class)).isFalse();
|
||||
assertThat(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isTrue();
|
||||
|
||||
expression = "within(@(test.annotation.transaction..*) *)";
|
||||
AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertThat(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithExactPackageWildcard() throws Exception {
|
||||
String expression = "within(@(test.annotation.transaction.*) *)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
private AspectJExpressionPointcut testMatchAnnotationOnClass(String expression) throws Exception {
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isTrue();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
return ajexp;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodWithFQN() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnCglibProxyMethod() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new BeanA());
|
||||
factory.setProxyTargetClass(true);
|
||||
BeanA proxy = (BeanA) factory.getProxy();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnDynamicProxyMethod() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new BeanA());
|
||||
factory.setProxyTargetClass(false);
|
||||
IBeanA proxy = (IBeanA) factory.getProxy();
|
||||
assertThat(ajexp.matches(IBeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodWithWildcard() throws Exception {
|
||||
String expression = "execution(@(test.annotation..*) * *(..))";
|
||||
AspectJExpressionPointcut anySpringMethodAnnotation = new AspectJExpressionPointcut();
|
||||
anySpringMethodAnnotation.setExpression(expression);
|
||||
|
||||
assertThat(anySpringMethodAnnotation.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodArgumentsWithFQN() throws Exception {
|
||||
String expression = "@args(*, test.annotation.EmptySpringAnnotation))";
|
||||
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
|
||||
// True because it maybeMatches with potential argument subtypes
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodArgumentsWithWildcards() throws Exception {
|
||||
String expression = "execution(* *(*, @(test..*) *))";
|
||||
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
public static class HasGeneric {
|
||||
|
||||
public void setFriends(List<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> numbers) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ProcessesSpringAnnotatedParameters {
|
||||
|
||||
public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) {
|
||||
}
|
||||
|
||||
public void takesNoAnnotatedParameters(TestBean tb, BeanA tb3) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Tx
|
||||
public static class HasTransactionalAnnotation {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
public Object bar(String foo) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EmptySpringAnnotation
|
||||
public static class SpringAnnotated {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface IBeanA {
|
||||
|
||||
@Tx
|
||||
int getAge();
|
||||
}
|
||||
|
||||
|
||||
static class BeanA implements IBeanA {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Tx
|
||||
@Override
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Tx
|
||||
static class BeanB {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException;
|
||||
|
||||
/**
|
||||
* Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer};
|
||||
* see supertype for remaining tests.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class TigerAspectJAdviceParameterNameDiscovererTests extends AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
@Test
|
||||
public void testAtThis() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtTarget() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtArgs() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtWithin() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtWithincode() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAtAnnotation() {
|
||||
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousAnnotationTwoVars() {
|
||||
assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class,
|
||||
"Found 2 potential annotation variable(s), and 2 potential argument slots");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousAnnotationOneVar() {
|
||||
assertException(getMethod("oneAnnotation"),"@annotation(a) && @this(x)",IllegalArgumentException.class,
|
||||
"Found 2 candidate annotation binding variables but only one potential argument binding slot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationMedley() {
|
||||
assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
|
||||
null, "ex", new String[] {"ex", "foo", "count", "a"});
|
||||
}
|
||||
|
||||
|
||||
public void oneAnnotation(MyAnnotation ann) {}
|
||||
|
||||
public void twoAnnotations(MyAnnotation ann, MyAnnotation anotherAnn) {}
|
||||
|
||||
public void annotationMedley(Throwable t, Object foo, int x, MyAnnotation ma) {}
|
||||
|
||||
@interface MyAnnotation {}
|
||||
|
||||
}
|
||||
-330
@@ -1,330 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import test.annotation.EmptySpringAnnotation;
|
||||
import test.annotation.transaction.Tx;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Java 5 specific {@link AspectJExpressionPointcutTests}.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class TigerAspectJExpressionPointcutTests {
|
||||
|
||||
private Method getAge;
|
||||
|
||||
private final Map<String, Method> methodsOnHasGeneric = new HashMap<>();
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws NoSuchMethodException {
|
||||
getAge = TestBean.class.getMethod("getAge");
|
||||
// Assumes no overloading
|
||||
for (Method method : HasGeneric.class.getMethods()) {
|
||||
methodsOnHasGeneric.put(method.getName(), method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMatchGenericArgument() {
|
||||
String expression = "execution(* set*(java.util.List<org.springframework.beans.testfixture.beans.TestBean>) )";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
// TODO this will currently map, would be nice for optimization
|
||||
//assertTrue(ajexp.matches(HasGeneric.class));
|
||||
//assertFalse(ajexp.matches(TestBean.class));
|
||||
|
||||
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
|
||||
assertThat(ajexp.matches(takesGenericList, HasGeneric.class)).isTrue();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isTrue();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
|
||||
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchVarargs() throws Exception {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
class MyTemplate {
|
||||
public int queryForInt(String sql, Object... params) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
String expression = "execution(int *.*(String, Object...))";
|
||||
AspectJExpressionPointcut jdbcVarArgs = new AspectJExpressionPointcut();
|
||||
jdbcVarArgs.setExpression(expression);
|
||||
|
||||
assertThat(jdbcVarArgs.matches(
|
||||
MyTemplate.class.getMethod("queryForInt", String.class, Object[].class),
|
||||
MyTemplate.class)).isTrue();
|
||||
|
||||
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
|
||||
assertThat(jdbcVarArgs.matches(takesGenericList, HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
|
||||
assertThat(jdbcVarArgs.matches(getAge, TestBean.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithAtWithin() throws Exception {
|
||||
String expression = "@within(test.annotation.transaction.Tx)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithoutBinding() throws Exception {
|
||||
String expression = "within(@test.annotation.transaction.Tx *)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithSubpackageWildcard() throws Exception {
|
||||
String expression = "within(@(test.annotation..*) *)";
|
||||
AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertThat(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class)).isFalse();
|
||||
assertThat(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isTrue();
|
||||
|
||||
expression = "within(@(test.annotation.transaction..*) *)";
|
||||
AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertThat(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchAnnotationOnClassWithExactPackageWildcard() throws Exception {
|
||||
String expression = "within(@(test.annotation.transaction.*) *)";
|
||||
testMatchAnnotationOnClass(expression);
|
||||
}
|
||||
|
||||
private AspectJExpressionPointcut testMatchAnnotationOnClass(String expression) throws Exception {
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isTrue();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
return ajexp;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodWithFQN() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnCglibProxyMethod() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new BeanA());
|
||||
factory.setProxyTargetClass(true);
|
||||
BeanA proxy = (BeanA) factory.getProxy();
|
||||
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnDynamicProxyMethod() throws Exception {
|
||||
String expression = "@annotation(test.annotation.transaction.Tx)";
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new BeanA());
|
||||
factory.setProxyTargetClass(false);
|
||||
IBeanA proxy = (IBeanA) factory.getProxy();
|
||||
assertThat(ajexp.matches(IBeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodWithWildcard() throws Exception {
|
||||
String expression = "execution(@(test.annotation..*) * *(..))";
|
||||
AspectJExpressionPointcut anySpringMethodAnnotation = new AspectJExpressionPointcut();
|
||||
anySpringMethodAnnotation.setExpression(expression);
|
||||
|
||||
assertThat(anySpringMethodAnnotation.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
|
||||
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodArgumentsWithFQN() throws Exception {
|
||||
String expression = "@args(*, test.annotation.EmptySpringAnnotation))";
|
||||
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
|
||||
// True because it maybeMatches with potential argument subtypes
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotationOnMethodArgumentsWithWildcards() throws Exception {
|
||||
String expression = "execution(* *(*, @(test..*) *))";
|
||||
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
|
||||
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isTrue();
|
||||
assertThat(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
public static class HasGeneric {
|
||||
|
||||
public void setFriends(List<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> numbers) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ProcessesSpringAnnotatedParameters {
|
||||
|
||||
public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) {
|
||||
}
|
||||
|
||||
public void takesNoAnnotatedParameters(TestBean tb, BeanA tb3) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Tx
|
||||
public static class HasTransactionalAnnotation {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
public Object bar(String foo) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EmptySpringAnnotation
|
||||
public static class SpringAnnotated {
|
||||
|
||||
public void foo() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface IBeanA {
|
||||
|
||||
@Tx
|
||||
int getAge();
|
||||
}
|
||||
|
||||
|
||||
static class BeanA implements IBeanA {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Tx
|
||||
@Override
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Tx
|
||||
static class BeanB {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -142,11 +142,11 @@ public class TrickyAspectJPointcutExpressionTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public static @interface Log {
|
||||
@interface Log {
|
||||
}
|
||||
|
||||
|
||||
public static interface TestService {
|
||||
public interface TestService {
|
||||
|
||||
public String sayHello();
|
||||
}
|
||||
|
||||
+1
-1
@@ -931,7 +931,7 @@ abstract class AbstractMakeModifiable {
|
||||
return setter.getDeclaringClass().getMethod(getterName);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
// must be write only
|
||||
// must be write-only
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.springframework.aop.framework;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -134,61 +133,4 @@ public class AopProxyUtilsTests {
|
||||
AopProxyUtils.proxiedUserInterfaces(proxy));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLambda() {
|
||||
assertIsLambda(AopProxyUtilsTests.staticLambdaExpression);
|
||||
assertIsLambda(AopProxyUtilsTests::staticStringFactory);
|
||||
|
||||
assertIsLambda(this.instanceLambdaExpression);
|
||||
assertIsLambda(this::instanceStringFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLambda() {
|
||||
assertIsNotLambda(new EnigmaSupplier());
|
||||
|
||||
assertIsNotLambda(new Supplier<String>() {
|
||||
@Override
|
||||
public String get() {
|
||||
return "anonymous inner class";
|
||||
}
|
||||
});
|
||||
|
||||
assertIsNotLambda(new Fake$$LambdaSupplier());
|
||||
}
|
||||
|
||||
private static void assertIsLambda(Supplier<String> supplier) {
|
||||
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isTrue();
|
||||
}
|
||||
|
||||
private static void assertIsNotLambda(Supplier<String> supplier) {
|
||||
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isFalse();
|
||||
}
|
||||
|
||||
private static final Supplier<String> staticLambdaExpression = () -> "static lambda expression";
|
||||
|
||||
private final Supplier<String> instanceLambdaExpression = () -> "instance lambda expressions";
|
||||
|
||||
private static String staticStringFactory() {
|
||||
return "static string factory";
|
||||
}
|
||||
|
||||
private String instanceStringFactory() {
|
||||
return "instance string factory";
|
||||
}
|
||||
|
||||
private static class EnigmaSupplier implements Supplier<String> {
|
||||
@Override
|
||||
public String get() {
|
||||
return "enigma";
|
||||
}
|
||||
}
|
||||
|
||||
private static class Fake$$LambdaSupplier implements Supplier<String> {
|
||||
@Override
|
||||
public String get() {
|
||||
return "fake lambda";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ public class IntroductionBenchmarkTests {
|
||||
}
|
||||
}
|
||||
|
||||
public static interface Counter {
|
||||
public interface Counter {
|
||||
int getCount();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.testfixture.TimeStamped;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatRuntimeException;
|
||||
|
||||
/**
|
||||
* Also tests AdvisedSupport and ProxyCreatorSupport superclasses.
|
||||
@@ -277,7 +277,7 @@ public class ProxyFactoryTests {
|
||||
|
||||
assertThat(config.getAdvisors().length == oldCount).isTrue();
|
||||
|
||||
assertThatExceptionOfType(RuntimeException.class)
|
||||
assertThatRuntimeException()
|
||||
.as("Existing object won't implement this interface any more")
|
||||
.isThrownBy(ts::getTimeStamp); // Existing reference will fail
|
||||
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.aop.testfixture.advice.MyThrowsHandler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
@@ -63,9 +64,7 @@ public class ThrowsAdviceInterceptorTests {
|
||||
Exception ex = new Exception();
|
||||
MethodInvocation mi = mock(MethodInvocation.class);
|
||||
given(mi.proceed()).willThrow(ex);
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
ti.invoke(mi))
|
||||
.isSameAs(ex);
|
||||
assertThatException().isThrownBy(() -> ti.invoke(mi)).isSameAs(ex);
|
||||
assertThat(th.getCalls()).isEqualTo(0);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -307,7 +307,7 @@ public class DelegatingIntroductionInterceptorTests {
|
||||
}
|
||||
|
||||
|
||||
private static interface SubTimeStamped extends TimeStamped {
|
||||
private interface SubTimeStamped extends TimeStamped {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public abstract aspect AbstractDependencyInjectionAspect {
|
||||
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();
|
||||
|
||||
/**
|
||||
* Select least specific super type that is marked for DI
|
||||
* Select least specific supertype that is marked for DI
|
||||
* (so that injection occurs only once with pre-construction injection).
|
||||
*/
|
||||
public abstract pointcut leastSpecificSuperTypeConstruction();
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Signals the current application context to apply dependency injection to
|
||||
* non-managed classes that are instantiated outside of the Spring bean factory
|
||||
* non-managed classes that are instantiated outside the Spring bean factory
|
||||
* (typically classes annotated with the
|
||||
* {@link org.springframework.beans.factory.annotation.Configurable @Configurable}
|
||||
* annotation).
|
||||
|
||||
+16
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,9 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatRuntimeException;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
@@ -104,44 +106,44 @@ public class TransactionAspectTests {
|
||||
@Test
|
||||
public void defaultCommitOnAnnotatedClass() throws Throwable {
|
||||
Exception ex = new Exception();
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), false))
|
||||
assertThatException()
|
||||
.isThrownBy(() -> testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), false))
|
||||
.isSameAs(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultRollbackOnAnnotatedClass() throws Throwable {
|
||||
RuntimeException ex = new RuntimeException();
|
||||
assertThatExceptionOfType(RuntimeException.class).isThrownBy(() ->
|
||||
testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), true))
|
||||
assertThatRuntimeException()
|
||||
.isThrownBy(() -> testRollback(() -> annotationOnlyOnClassWithNoInterface.echo(ex), true))
|
||||
.isSameAs(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
|
||||
Exception ex = new Exception();
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
testRollback(() -> new SubclassOfClassWithTransactionalAnnotation().echo(ex), false))
|
||||
assertThatException()
|
||||
.isThrownBy(() -> testRollback(() -> new SubclassOfClassWithTransactionalAnnotation().echo(ex), false))
|
||||
.isSameAs(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
|
||||
Exception ex = new Exception();
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
testRollback(() -> new SubclassOfClassWithTransactionalMethodAnnotation().echo(ex), false))
|
||||
assertThatException()
|
||||
.isThrownBy(() -> testRollback(() -> new SubclassOfClassWithTransactionalMethodAnnotation().echo(ex), false))
|
||||
.isSameAs(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noCommitOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
final Exception ex = new Exception();
|
||||
Exception ex = new Exception();
|
||||
testNotTransactional(() -> new ImplementsAnnotatedInterface().echo(ex), ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
final Exception rollbackProvokingException = new RuntimeException();
|
||||
Exception rollbackProvokingException = new RuntimeException();
|
||||
testNotTransactional(() -> new ImplementsAnnotatedInterface().echo(rollbackProvokingException),
|
||||
rollbackProvokingException);
|
||||
}
|
||||
@@ -165,8 +167,9 @@ public class TransactionAspectTests {
|
||||
protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
|
||||
txManager.clear();
|
||||
assertThat(txManager.begun).isEqualTo(0);
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(
|
||||
toc::performTransactionalOperation).isSameAs(expected);
|
||||
assertThatExceptionOfType(Throwable.class)
|
||||
.isThrownBy(toc::performTransactionalOperation)
|
||||
.isSameAs(expected);
|
||||
assertThat(txManager.begun).isEqualTo(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
|
||||
* Obtain the property descriptor for a specific property
|
||||
* of the wrapped object.
|
||||
* @param propertyName the property to obtain the descriptor for
|
||||
* (may be a nested path, but no indexed/mapped property)
|
||||
* (may be a nested path, but not an indexed/mapped property)
|
||||
* @return the property descriptor for the specified property
|
||||
* @throws InvalidPropertyException if there is no such property
|
||||
*/
|
||||
|
||||
+29
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,8 @@ import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URL;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -286,9 +288,17 @@ public final class CachedIntrospectionResults {
|
||||
// This call is slow so we do it once.
|
||||
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
if (Class.class == beanClass &&
|
||||
("classLoader".equals(pd.getName()) || "protectionDomain".equals(pd.getName()))) {
|
||||
// Ignore Class.getClassLoader() and getProtectionDomain() methods - nobody needs to bind to those
|
||||
if (Class.class == beanClass && !("name".equals(pd.getName()) ||
|
||||
(pd.getName().endsWith("Name") && String.class == pd.getPropertyType()))) {
|
||||
// Only allow all name variants of Class properties
|
||||
continue;
|
||||
}
|
||||
if (URL.class == beanClass && "content".equals(pd.getName())) {
|
||||
// Only allow URL attribute introspection, not content resolution
|
||||
continue;
|
||||
}
|
||||
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
|
||||
// Ignore read-only properties such as ClassLoader - no need to bind to those
|
||||
continue;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
@@ -337,6 +347,10 @@ public final class CachedIntrospectionResults {
|
||||
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
|
||||
// against a declared read method, so we prefer read method descriptors here.
|
||||
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
||||
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
|
||||
// Ignore read-only properties such as ClassLoader - no need to bind to those
|
||||
continue;
|
||||
}
|
||||
this.propertyDescriptors.put(pd.getName(), pd);
|
||||
Method readMethod = pd.getReadMethod();
|
||||
if (readMethod != null) {
|
||||
@@ -354,7 +368,7 @@ public final class CachedIntrospectionResults {
|
||||
|
||||
for (Method method : beanClass.getMethods()) {
|
||||
if (!this.propertyDescriptors.containsKey(method.getName()) &&
|
||||
!readMethodNames.contains((method.getName())) && isPlainAccessor(method)) {
|
||||
!readMethodNames.contains(method.getName()) && isPlainAccessor(method)) {
|
||||
this.propertyDescriptors.put(method.getName(),
|
||||
new GenericTypeAwarePropertyDescriptor(beanClass, method.getName(), method, null, null));
|
||||
readMethodNames.add(method.getName());
|
||||
@@ -363,8 +377,10 @@ public final class CachedIntrospectionResults {
|
||||
}
|
||||
|
||||
private boolean isPlainAccessor(Method method) {
|
||||
if (method.getParameterCount() > 0 || method.getReturnType() == void.class ||
|
||||
method.getDeclaringClass() == Object.class || Modifier.isStatic(method.getModifiers())) {
|
||||
if (Modifier.isStatic(method.getModifiers()) ||
|
||||
method.getDeclaringClass() == Object.class || method.getDeclaringClass() == Class.class ||
|
||||
method.getParameterCount() > 0 || method.getReturnType() == void.class ||
|
||||
isInvalidReadOnlyPropertyType(method.getReturnType())) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
@@ -377,6 +393,12 @@ public final class CachedIntrospectionResults {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType) {
|
||||
return (returnType != null && (AutoCloseable.class.isAssignableFrom(returnType) ||
|
||||
ClassLoader.class.isAssignableFrom(returnType) ||
|
||||
ProtectionDomain.class.isAssignableFrom(returnType)));
|
||||
}
|
||||
|
||||
|
||||
BeanInfo getBeanInfo() {
|
||||
return this.beanInfo;
|
||||
|
||||
@@ -327,7 +327,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
/**
|
||||
* Register the specified property as "processed" in the sense
|
||||
* of some processor calling the corresponding setter method
|
||||
* outside of the PropertyValue(s) mechanism.
|
||||
* outside the PropertyValue(s) mechanism.
|
||||
* <p>This will lead to {@code true} being returned from
|
||||
* a {@link #contains} call for the specified property.
|
||||
* @param propertyName the name of the property.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,8 +23,9 @@ import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Common interface for classes that can access named properties
|
||||
* (such as bean properties of an object or fields in an object)
|
||||
* Serves as base interface for {@link BeanWrapper}.
|
||||
* (such as bean properties of an object or fields in an object).
|
||||
*
|
||||
* <p>Serves as base interface for {@link BeanWrapper}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1
|
||||
|
||||
@@ -22,7 +22,7 @@ package org.springframework.beans;
|
||||
* {@link org.springframework.beans.PropertyEditorRegistry property editor registry}.
|
||||
*
|
||||
* <p>This is particularly useful when you need to use the same set of
|
||||
* property editors in several different situations: write a corresponding
|
||||
* property editors in several situations: write a corresponding
|
||||
* registrar and reuse that in each case.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Support package for beans-style handling of Java 5 annotations.
|
||||
* Support package for beans-style handling of annotations.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* <p><b>The container is only responsible for managing the lifecycle of the FactoryBean
|
||||
* instance, not the lifecycle of the objects created by the FactoryBean.</b> Therefore,
|
||||
* a destroy method on an exposed bean object (such as {@link java.io.Closeable#close()}
|
||||
* a destroy method on an exposed bean object (such as {@link java.io.Closeable#close()})
|
||||
* will <i>not</i> be called automatically. Instead, a FactoryBean should implement
|
||||
* {@link DisposableBean} and delegate any such close call to the underlying object.
|
||||
*
|
||||
@@ -108,7 +108,7 @@ public interface FactoryBean<T> {
|
||||
* been fully initialized. It must not rely on state created during
|
||||
* initialization; of course, it can still use such state if available.
|
||||
* <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return
|
||||
* {@code null} here. Therefore it is highly recommended to implement
|
||||
* {@code null} here. Therefore, it is highly recommended to implement
|
||||
* this method properly, using the current state of the FactoryBean.
|
||||
* @return the type of object that this FactoryBean creates,
|
||||
* or {@code null} if not known at the time of the call
|
||||
|
||||
+2
-2
@@ -343,7 +343,7 @@ public interface ListableBeanFactory extends BeanFactory {
|
||||
|
||||
/**
|
||||
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
|
||||
* traversing its interfaces and super classes if no annotation can be found on
|
||||
* traversing its interfaces and superclasses if no annotation can be found on
|
||||
* the given class itself, as well as checking the bean's factory method (if any).
|
||||
* @param beanName the name of the bean to look for annotations on
|
||||
* @param annotationType the type of annotation to look for
|
||||
@@ -361,7 +361,7 @@ public interface ListableBeanFactory extends BeanFactory {
|
||||
|
||||
/**
|
||||
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
|
||||
* traversing its interfaces and super classes if no annotation can be found on
|
||||
* traversing its interfaces and superclasses if no annotation can be found on
|
||||
* the given class itself, as well as checking the bean's factory method (if any).
|
||||
* @param beanName the name of the bean to look for annotations on
|
||||
* @param annotationType the type of annotation to look for
|
||||
|
||||
+2
-2
@@ -137,7 +137,7 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||
* as a <em>qualifier</em>, the bean must 'match' against the annotation as
|
||||
* well as any attributes it may contain. The bean definition must contain
|
||||
* the same qualifier or match by meta attributes. A "value" attribute will
|
||||
* fallback to match against the bean name or an alias if a qualifier or
|
||||
* fall back to match against the bean name or an alias if a qualifier or
|
||||
* attribute does not match.
|
||||
* @see Qualifier
|
||||
*/
|
||||
@@ -186,7 +186,7 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||
if (isQualifier(metaType)) {
|
||||
foundMeta = true;
|
||||
// Only accept fallback match if @Qualifier annotation has a value...
|
||||
// Otherwise it is just a marker for a custom qualifier annotation.
|
||||
// Otherwise, it is just a marker for a custom qualifier annotation.
|
||||
if ((fallbackToMeta && ObjectUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
|
||||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
|
||||
return false;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
|
||||
* that enforces required JavaBean properties to have been configured.
|
||||
* Required bean properties are detected through a Java 5 annotation:
|
||||
* Required bean properties are detected through an annotation:
|
||||
* by default, Spring's {@link Required} annotation.
|
||||
*
|
||||
* <p>The motivation for the existence of this BeanPostProcessor is to allow
|
||||
|
||||
+7
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,8 +20,8 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Strategy interface for resolving a value through evaluating it
|
||||
* as an expression, if applicable.
|
||||
* Strategy interface for resolving a value by evaluating it as an expression,
|
||||
* if applicable.
|
||||
*
|
||||
* <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not
|
||||
* contain a default implementation of this strategy. However,
|
||||
@@ -36,12 +36,13 @@ public interface BeanExpressionResolver {
|
||||
/**
|
||||
* Evaluate the given value as an expression, if applicable;
|
||||
* return the value as-is otherwise.
|
||||
* @param value the value to check
|
||||
* @param evalContext the evaluation context
|
||||
* @param value the value to evaluate as an expression
|
||||
* @param beanExpressionContext the bean expression context to use when
|
||||
* evaluating the expression
|
||||
* @return the resolved value (potentially the given value as-is)
|
||||
* @throws BeansException if evaluation failed
|
||||
*/
|
||||
@Nullable
|
||||
Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException;
|
||||
Object evaluate(@Nullable String value, BeanExpressionContext beanExpressionContext) throws BeansException;
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import org.springframework.beans.BeansException;
|
||||
*
|
||||
* <p>A {@code BeanFactoryPostProcessor} may interact with and modify bean
|
||||
* definitions, but never bean instances. Doing so may cause premature bean
|
||||
* instantiation, violating the container and causing unintended side-effects.
|
||||
* instantiation, violating the container and causing unintended side effects.
|
||||
* If bean instance interaction is required, consider implementing
|
||||
* {@link BeanPostProcessor} instead.
|
||||
*
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ public class ConstructorArgumentValues {
|
||||
|
||||
/**
|
||||
* Copy all given argument values into this object, using separate holder
|
||||
* instances to keep the values independent from the original object.
|
||||
* instances to keep the values independent of the original object.
|
||||
* <p>Note: Identical ValueHolder instances will only be registered once,
|
||||
* to allow for merging and re-merging of argument value definitions. Distinct
|
||||
* ValueHolder instances carrying the same content are of course allowed.
|
||||
|
||||
+1
-1
@@ -155,7 +155,7 @@ public abstract class YamlProcessor {
|
||||
* resources. Each resource is parsed in turn and the documents inside checked against
|
||||
* the {@link #setDocumentMatchers(DocumentMatcher...) matchers}. If a document
|
||||
* matches it is passed into the callback, along with its representation as Properties.
|
||||
* Depending on the {@link #setResolutionMethod(ResolutionMethod)} not all of the
|
||||
* Depending on the {@link #setResolutionMethod(ResolutionMethod)} not all the
|
||||
* documents will be parsed.
|
||||
* @param callback a callback to delegate to once matching documents are found
|
||||
* @see #createYaml()
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ public class BeanComponentDefinition extends BeanDefinitionHolder implements Com
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementations expects the other object to be of type BeanComponentDefinition
|
||||
* This implementation expects the other object to be of type BeanComponentDefinition
|
||||
* as well, in addition to the superclass's equality requirements.
|
||||
*/
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -50,13 +50,13 @@ import org.springframework.beans.factory.config.BeanReference;
|
||||
* {@link #getBeanReferences}, tools may wish to inspect all {@link BeanDefinition BeanDefinitions} to gather
|
||||
* the full set of {@link BeanReference BeanReferences}. Implementations are required to provide
|
||||
* all {@link BeanReference BeanReferences} that are required to validate the configuration of the
|
||||
* overall logical entity as well as those required to provide full user visualisation of the configuration.
|
||||
* overall logical entity as well as those required to provide full user visualization of the configuration.
|
||||
* It is expected that certain {@link BeanReference BeanReferences} will not be important to
|
||||
* validation or to the user view of the configuration and as such these may be omitted. A tool may wish to
|
||||
* display any additional {@link BeanReference BeanReferences} sourced through the supplied
|
||||
* {@link BeanDefinition BeanDefinitions} but this is not considered to be a typical case.
|
||||
*
|
||||
* <p>Tools can determine the important of contained {@link BeanDefinition BeanDefinitions} by checking the
|
||||
* <p>Tools can determine the importance of contained {@link BeanDefinition BeanDefinitions} by checking the
|
||||
* {@link BeanDefinition#getRole role identifier}. The role is essentially a hint to the tool as to how
|
||||
* important the configuration provider believes a {@link BeanDefinition} is to the end user. It is expected
|
||||
* that tools will <strong>not</strong> display all {@link BeanDefinition BeanDefinitions} for a given
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Support package for the Java 6 ServiceLoader facility.
|
||||
* Support package for the Java {@link java.util.ServiceLoader} facility.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
||||
+1
-1
@@ -1510,7 +1510,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
try {
|
||||
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
|
||||
// Don't try autowiring by type for type Object: never makes sense,
|
||||
// even if it technically is a unsatisfied, non-simple property.
|
||||
// even if it technically is an unsatisfied, non-simple property.
|
||||
if (Object.class != pd.getPropertyType()) {
|
||||
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
|
||||
// Do not allow eager init for type matching in case of a prioritized post-processor.
|
||||
|
||||
+2
-2
@@ -945,7 +945,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether or not the configured initializer method is the default.
|
||||
* Specify whether the configured initializer method is the default.
|
||||
* <p>The default value is {@code true} for a locally specified init method
|
||||
* but switched to {@code false} for a shared setting in a defaults section
|
||||
* (e.g. {@code bean init-method} versus {@code beans default-init-method}
|
||||
@@ -984,7 +984,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether or not the configured destroy method is the default.
|
||||
* Specify whether the configured destroy method is the default.
|
||||
* <p>The default value is {@code true} for a locally specified destroy method
|
||||
* but switched to {@code false} for a shared setting in a defaults section
|
||||
* (e.g. {@code bean destroy-method} versus {@code beans default-destroy-method}
|
||||
|
||||
+1
-1
@@ -593,7 +593,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
|
||||
|
||||
// Setup the types that we want to match against
|
||||
// Set up the types that we want to match against
|
||||
Class<?> classToMatch = typeToMatch.resolve();
|
||||
if (classToMatch == null) {
|
||||
classToMatch = FactoryBean.class;
|
||||
|
||||
+1
-1
@@ -293,7 +293,7 @@ public final class BeanDefinitionBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not this definition is abstract.
|
||||
* Set whether this definition is abstract.
|
||||
*/
|
||||
public BeanDefinitionBuilder setAbstract(boolean flag) {
|
||||
this.beanDefinition.setAbstract(flag);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -985,7 +985,7 @@ class ConstructorResolver {
|
||||
|
||||
|
||||
/**
|
||||
* Delegate for checking Java 6's {@link ConstructorProperties} annotation.
|
||||
* Delegate for checking Java's {@link ConstructorProperties} annotation.
|
||||
*/
|
||||
private static class ConstructorPropertiesChecker {
|
||||
|
||||
|
||||
+20
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -280,7 +280,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the dependency comparator for this BeanFactory (may be {@code null}.
|
||||
* Return the dependency comparator for this BeanFactory (may be {@code null}).
|
||||
* @since 4.0
|
||||
*/
|
||||
@Nullable
|
||||
@@ -585,7 +585,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (!matchFound) {
|
||||
// In case of FactoryBean, try to match FactoryBean instance itself next.
|
||||
beanName = FACTORY_BEAN_PREFIX + beanName;
|
||||
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
|
||||
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
|
||||
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matchFound) {
|
||||
@@ -2165,20 +2167,25 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Nullable
|
||||
public Object getOrderSource(Object obj) {
|
||||
String beanName = this.instancesToBeanNames.get(obj);
|
||||
if (beanName == null || !containsBeanDefinition(beanName)) {
|
||||
if (beanName == null) {
|
||||
return null;
|
||||
}
|
||||
RootBeanDefinition beanDefinition = getMergedLocalBeanDefinition(beanName);
|
||||
List<Object> sources = new ArrayList<>(2);
|
||||
Method factoryMethod = beanDefinition.getResolvedFactoryMethod();
|
||||
if (factoryMethod != null) {
|
||||
sources.add(factoryMethod);
|
||||
try {
|
||||
RootBeanDefinition beanDefinition = (RootBeanDefinition) getMergedBeanDefinition(beanName);
|
||||
List<Object> sources = new ArrayList<>(2);
|
||||
Method factoryMethod = beanDefinition.getResolvedFactoryMethod();
|
||||
if (factoryMethod != null) {
|
||||
sources.add(factoryMethod);
|
||||
}
|
||||
Class<?> targetType = beanDefinition.getTargetType();
|
||||
if (targetType != null && targetType != obj.getClass()) {
|
||||
sources.add(targetType);
|
||||
}
|
||||
return sources.toArray();
|
||||
}
|
||||
Class<?> targetType = beanDefinition.getTargetType();
|
||||
if (targetType != null && targetType != obj.getClass()) {
|
||||
sources.add(targetType);
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
return null;
|
||||
}
|
||||
return sources.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import org.springframework.util.ClassUtils;
|
||||
/**
|
||||
* Basic {@link AutowireCandidateResolver} that performs a full generic type
|
||||
* match with the candidate's type if the dependency is declared as a generic type
|
||||
* (e.g. Repository<Customer>).
|
||||
* (e.g. {@code Repository<Customer>}).
|
||||
*
|
||||
* <p>This is the base class for
|
||||
* {@link org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver},
|
||||
|
||||
+7
-5
@@ -17,7 +17,7 @@
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
@@ -31,6 +31,8 @@ import org.springframework.lang.Nullable;
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 27.05.2003
|
||||
* @param <E> the element type
|
||||
*/
|
||||
@@ -55,16 +57,16 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
|
||||
|
||||
|
||||
/**
|
||||
* Return a new instance containing an arbitrary number of elements.
|
||||
* Create a new instance containing an arbitrary number of elements.
|
||||
* @param elements the elements to be contained in the list
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @return a {@code ManagedList} containing the specified elements
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SafeVarargs
|
||||
public static <E> ManagedList<E> of(E... elements) {
|
||||
ManagedList<E> list = new ManagedList<>();
|
||||
list.addAll(Arrays.asList(elements));
|
||||
Collections.addAll(list, elements);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
+7
-5
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -30,6 +30,8 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 21.01.2004
|
||||
* @param <E> the element type
|
||||
*/
|
||||
@@ -54,16 +56,16 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
|
||||
|
||||
|
||||
/**
|
||||
* Return a new instance containing an arbitrary number of elements.
|
||||
* Create a new instance containing an arbitrary number of elements.
|
||||
* @param elements the elements to be contained in the set
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @return a {@code ManagedSet} containing the specified elements
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SafeVarargs
|
||||
public static <E> ManagedSet<E> of(E... elements) {
|
||||
ManagedSet<E> set = new ManagedSet<>();
|
||||
set.addAll(Arrays.asList(elements));
|
||||
Collections.addAll(set, elements);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ public abstract class AbstractBeanDefinitionParser implements BeanDefinitionPars
|
||||
/**
|
||||
* Register the supplied {@link BeanDefinitionHolder bean} with the supplied
|
||||
* {@link BeanDefinitionRegistry registry}.
|
||||
* <p>Subclasses can override this method to control whether or not the supplied
|
||||
* <p>Subclasses can override this method to control whether the supplied
|
||||
* {@link BeanDefinitionHolder bean} is actually even registered, or to
|
||||
* register even more beans.
|
||||
* <p>The default implementation registers the supplied {@link BeanDefinitionHolder bean}
|
||||
|
||||
+2
-2
@@ -1362,7 +1362,7 @@ public class BeanDefinitionParserDelegate {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a custom element (outside of the default namespace).
|
||||
* Parse a custom element (outside the default namespace).
|
||||
* @param ele the element to parse
|
||||
* @return the resulting bean definition
|
||||
*/
|
||||
@@ -1372,7 +1372,7 @@ public class BeanDefinitionParserDelegate {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a custom element (outside of the default namespace).
|
||||
* Parse a custom element (outside the default namespace).
|
||||
* @param ele the element to parse
|
||||
* @param containingBd the containing bean definition (if any)
|
||||
* @return the resulting bean definition
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver
|
||||
* Create a new {@code DefaultNamespaceHandlerResolver} using the
|
||||
* supplied mapping file location.
|
||||
* @param classLoader the {@link ClassLoader} instance used to load mapping resources
|
||||
* may be {@code null}, in which case the thread context ClassLoader will be used)
|
||||
* may be {@code null}, in which case the thread context ClassLoader will be used
|
||||
* @param handlerMappingsLocation the mapping file location
|
||||
*/
|
||||
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader, String handlerMappingsLocation) {
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ public class DelegatingEntityResolver implements EntityResolver {
|
||||
* <p>Configures the {@link PluggableSchemaResolver} with the supplied
|
||||
* {@link ClassLoader}.
|
||||
* @param classLoader the ClassLoader to use for loading
|
||||
* (can be {@code null}) to use the default ClassLoader)
|
||||
* (can be {@code null} to use the default ClassLoader)
|
||||
*/
|
||||
public DelegatingEntityResolver(@Nullable ClassLoader classLoader) {
|
||||
this.dtdResolver = new BeansDtdResolver();
|
||||
|
||||
+2
-2
@@ -80,7 +80,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
* Loads the schema URL → schema file location mappings using the default
|
||||
* mapping file pattern "META-INF/spring.schemas".
|
||||
* @param classLoader the ClassLoader to use for loading
|
||||
* (can be {@code null}) to use the default ClassLoader)
|
||||
* (can be {@code null} to use the default ClassLoader)
|
||||
* @see PropertiesLoaderUtils#loadAllProperties(String, ClassLoader)
|
||||
*/
|
||||
public PluggableSchemaResolver(@Nullable ClassLoader classLoader) {
|
||||
@@ -92,7 +92,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
* Loads the schema URL → schema file location mappings using the given
|
||||
* mapping file pattern.
|
||||
* @param classLoader the ClassLoader to use for loading
|
||||
* (can be {@code null}) to use the default ClassLoader)
|
||||
* (can be {@code null} to use the default ClassLoader)
|
||||
* @param schemaMappingsLocation the location of the file that defines schema mappings
|
||||
* (must not be empty)
|
||||
* @see PropertiesLoaderUtils#loadAllProperties(String, ClassLoader)
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ import org.springframework.util.StringUtils;
|
||||
* the bean that will be considered as a parameter.
|
||||
*
|
||||
* <b>Note</b>: This implementation supports only named parameters - there is no
|
||||
* support for indexes or types. Further more, the names are used as hints by
|
||||
* support for indexes or types. Furthermore, the names are used as hints by
|
||||
* the container which, by default, does type introspection.
|
||||
*
|
||||
* @author Costin Leau
|
||||
|
||||
+2
-2
@@ -184,7 +184,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not the XML parser should be XML namespace aware.
|
||||
* Set whether the XML parser should be XML namespace aware.
|
||||
* Default is "false".
|
||||
* <p>This is typically not needed when schema validation is active.
|
||||
* However, without validation, this has to be switched to "true"
|
||||
@@ -195,7 +195,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the XML parser should be XML namespace aware.
|
||||
* Return whether the XML parser should be XML namespace aware.
|
||||
*/
|
||||
public boolean isNamespaceAware() {
|
||||
return this.namespaceAware;
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,6 +29,7 @@ import org.springframework.util.StringUtils;
|
||||
* e.g. {@code UTF-8}, {@code ISO-8859-16}, etc.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Sam Brannen
|
||||
* @since 2.5.4
|
||||
* @see Charset
|
||||
*/
|
||||
@@ -37,7 +38,7 @@ public class CharsetEditor extends PropertyEditorSupport {
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
if (StringUtils.hasText(text)) {
|
||||
setValue(Charset.forName(text));
|
||||
setValue(Charset.forName(text.trim()));
|
||||
}
|
||||
else {
|
||||
setValue(null);
|
||||
|
||||
+7
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,11 +19,14 @@ package org.springframework.beans.propertyeditors;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.Currency;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Editor for {@code java.util.Currency}, translating currency codes into Currency
|
||||
* objects. Exposes the currency code as text representation of a Currency object.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
* @see java.util.Currency
|
||||
*/
|
||||
@@ -31,6 +34,9 @@ public class CurrencyEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
if (StringUtils.hasText(text)) {
|
||||
text = text.trim();
|
||||
}
|
||||
setValue(Currency.getInstance(text));
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user