mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
483 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a4dc13a043 | |||
| 63a4873edb | |||
| 7d41c5fa2e | |||
| 9d92fa79d3 | |||
| 890f29e832 | |||
| 79dfda7369 | |||
| 5de549d7d4 | |||
| c5bb5d6c03 | |||
| c2122551c8 | |||
| 7b6e1c957f | |||
| 1f35cc5cae | |||
| af8ab2e3a8 | |||
| 1dcaa04224 | |||
| 2c274cf0aa | |||
| e0d79f5dbb | |||
| 88ccab8f13 | |||
| d0cf90bb8e | |||
| 01b79514da | |||
| 17acc3554c | |||
| 0b57368d5f | |||
| 3c832f0ec8 | |||
| e87a49c61c | |||
| 617ec359bd | |||
| 922f9452f2 | |||
| a6af1def57 | |||
| f4c0ceb1cc | |||
| 14839b1f4a | |||
| b345019415 | |||
| 392f51cdd6 | |||
| 83df467b3b | |||
| 4d446f9659 | |||
| f3cedf268b | |||
| b6ef3cfad5 | |||
| d61c0ee57d | |||
| 5bdbbdfcfb | |||
| 2087f3586c | |||
| c99c3142ad | |||
| df98d0c661 | |||
| 38690bdc7c | |||
| 6d164b1445 | |||
| c7b74c4358 | |||
| e150a95685 | |||
| dded51fa80 | |||
| ba65cef52b | |||
| b6d2a2980d | |||
| b0d273e047 | |||
| 4d670ee25d | |||
| 762cf0ffe8 | |||
| 3dc4f43852 | |||
| 1dcd7f418f | |||
| 673f83e388 | |||
| 93b53dae29 | |||
| 1a8906bdc3 | |||
| ea52627c38 | |||
| dbec16d566 | |||
| 72895f0810 | |||
| 87c3bb5797 | |||
| c17f2047f6 | |||
| d646e602d9 | |||
| d8554c498c | |||
| 58412affaa | |||
| 6f716e6965 | |||
| 9aae5ed3fa | |||
| c1b2e23029 | |||
| f28918e91d | |||
| 2d08c76ab5 | |||
| 5c456db3cc | |||
| 83e3c332a5 | |||
| 16eebf2911 | |||
| 683cc2eb7f | |||
| 354635ede0 | |||
| f19afe0c76 | |||
| be801fc5fc | |||
| 77137719d8 | |||
| a1a9bb3e7f | |||
| adce6593af | |||
| 9f211de113 | |||
| 8a394c2b07 | |||
| 87c5b5a664 | |||
| 9301d7a294 | |||
| 4252b7fd7d | |||
| a4c157fc09 | |||
| 86c52a842f | |||
| d2db43a900 | |||
| 27e0febacf | |||
| a03f894a14 | |||
| cf8c36adf3 | |||
| 05683fed7a | |||
| 718d46adac | |||
| 32b35e9a23 | |||
| a8901e3cf8 | |||
| edfc6c0293 | |||
| cdc234d7db | |||
| c547809e89 | |||
| 9fe1feea9a | |||
| f9ba58eab9 | |||
| 471577a11b | |||
| 523d2f88be | |||
| ae5913f3b6 | |||
| cd12583e13 | |||
| 24f9b1d966 | |||
| e4a139e70e | |||
| 3b12beb1b8 | |||
| c7f44ff671 | |||
| fa0a1446f0 | |||
| 2522fe0292 | |||
| 2719dcb29b | |||
| b6c463676a | |||
| e71f702bb9 | |||
| 05ef630f4f | |||
| 674bad0c59 | |||
| 3d64f8162c | |||
| 6b6e8be313 | |||
| 7ce4d150ce | |||
| 74d3044641 | |||
| 24b1caf434 | |||
| 88394bff66 | |||
| e4e54b3c4a | |||
| 4f2aaa49a9 | |||
| 6317bc2262 | |||
| e0d05153aa | |||
| 198d64d539 | |||
| 111899aa63 | |||
| b451379c2f | |||
| 44f1f94f97 | |||
| 524ca1a676 | |||
| b0570cd3a6 | |||
| 35c0ae7b0c | |||
| d2e1150c79 | |||
| 4578e49213 | |||
| 7c98251142 | |||
| e4a3c1570d | |||
| b54853484e | |||
| 1dec4f3d0f | |||
| 490bdd11a5 | |||
| abe16eeb6e | |||
| 54d9dfa84f | |||
| d9ccd618ea | |||
| 92cdf526fb | |||
| 313a7836b0 | |||
| 37366e0c91 | |||
| 4d7418841c | |||
| 0584c289ab | |||
| 47a3a5c970 | |||
| c972d861ed | |||
| 90467ba568 | |||
| 0e4e25d227 | |||
| 1181bb1852 | |||
| 8632118e8d | |||
| a1bab14140 | |||
| 8e02d2706e | |||
| 882668c1bc | |||
| 364939b2a3 | |||
| 33643593e2 | |||
| 34607d96f1 | |||
| 32ab596e94 | |||
| 4ae9895814 | |||
| 362e228142 | |||
| 72e92211ce | |||
| 85a46882ce | |||
| f13ab6d18c | |||
| 5e1b6e3386 | |||
| 3aaff40e2e | |||
| 9d37794ebc | |||
| e251075d6c | |||
| 20254f02d2 | |||
| e9d9de5f99 | |||
| 671d4519b2 | |||
| 02b539c5f5 | |||
| 06b364fefe | |||
| a92441186c | |||
| 622ccc5767 | |||
| d599ec906a | |||
| df673e65e8 | |||
| 43df06b905 | |||
| ba5f4f5414 | |||
| 115ea253f6 | |||
| b16f6fa456 | |||
| 3a06622270 | |||
| 049f5250fe | |||
| a142d21700 | |||
| b33d2fe683 | |||
| bc9b9bc477 | |||
| 751739442b | |||
| 51cc719c00 | |||
| 973ee9b852 | |||
| 57f868fcbd | |||
| 7e71749e34 | |||
| 19fb0f113b | |||
| 4716e48241 | |||
| 22bf62def1 | |||
| 0e83aaa756 | |||
| 1edc08fb84 | |||
| f9331d921f | |||
| d0209e5f1f | |||
| 56c661829b | |||
| 8eedd9d5cc | |||
| eee0b76ef3 | |||
| 837dfe285a | |||
| 734f4a4706 | |||
| 97efacc9a4 | |||
| b67de25d67 | |||
| 41b7686378 | |||
| a678db3888 | |||
| 23aeba0e46 | |||
| 6316a353bb | |||
| 1f78cede72 | |||
| eeb6c10fb7 | |||
| b733474c64 | |||
| 53df8ca1f5 | |||
| bf5033281b | |||
| ed648b793b | |||
| 7cf1ccc415 | |||
| 96bbec7ab2 | |||
| d627f6049e | |||
| 883ad098f9 | |||
| ff9daa9377 | |||
| 01fa923e96 | |||
| c6e2d1d405 | |||
| ab0e651547 | |||
| 9d5881e0ad | |||
| 2f0970b184 | |||
| 63dff520e6 | |||
| 2d8b2fed8b | |||
| 78d1591e2d | |||
| b1da89344f | |||
| 7391f9b392 | |||
| 34cb4895c4 | |||
| 3a653bd35f | |||
| e0e1c12402 | |||
| c418cef68f | |||
| 1e501f2583 | |||
| ce728a6c4b | |||
| 2d5f9723fa | |||
| 1c75f95be0 | |||
| dc3801043f | |||
| 96b03c587f | |||
| 6b355df903 | |||
| 6615e9c5ef | |||
| bad81cef8a | |||
| edf25ce98a | |||
| d60c55c296 | |||
| 30263137c4 | |||
| 533608b0a1 | |||
| de0a043739 | |||
| bc33ae3f8b | |||
| e01160db31 | |||
| aff601edf1 | |||
| 7f79a373c3 | |||
| 217b6e37a6 | |||
| 8853f4b883 | |||
| 775d99ac78 | |||
| 9984a335ca | |||
| 77dd05853c | |||
| 17cab9660c | |||
| d36407d585 | |||
| 6ea7ff1c6d | |||
| 7949937655 | |||
| 8099fc8178 | |||
| 456d2c46e3 | |||
| 50391ad3d7 | |||
| e2944c37e4 | |||
| 2a74eff10f | |||
| 97aba77cc1 | |||
| cc301011b2 | |||
| b50cf9dad2 | |||
| b572f7618f | |||
| bb7e5f0172 | |||
| 5225a57411 | |||
| a0f4d81db7 | |||
| adc76a1d8f | |||
| e190851aee | |||
| 50a0094a47 | |||
| 30385dae8d | |||
| d9969d1e4d | |||
| f9cca5d9d6 | |||
| b66e718560 | |||
| 188722a358 | |||
| 1279b3b822 | |||
| bc4945d677 | |||
| e866fac8e7 | |||
| 663f2e8afd | |||
| b0e07cc7e3 | |||
| 335ca75ec2 | |||
| 8fb7399a0c | |||
| 202799e6fe | |||
| eb3be3ad88 | |||
| b9e52a8089 | |||
| 905483be30 | |||
| 33181daeac | |||
| 3cc7efc841 | |||
| e0d712946c | |||
| 1984cfe9d7 | |||
| 21b1f30660 | |||
| 9c1c787ee9 | |||
| edbc54fe78 | |||
| 150fe96a98 | |||
| 8b59b6a7f4 | |||
| 0bfcabebf3 | |||
| a34f1e3759 | |||
| f860b35df8 | |||
| 65b09be669 | |||
| 5051d7302d | |||
| aaa7c6c422 | |||
| 5f1326f233 | |||
| 6a829a322a | |||
| e11da64e9c | |||
| a7df011471 | |||
| 104f7f339a | |||
| da7ead8914 | |||
| 0b163fa536 | |||
| a7f8120164 | |||
| 0f0b1ffe0d | |||
| 2549674f41 | |||
| 2a5fc08629 | |||
| e955e52f2f | |||
| 7207f7645c | |||
| 1175b7eb52 | |||
| 8d449471c7 | |||
| b31b8ce6c1 | |||
| 30351c257c | |||
| 6d6269f1ee | |||
| 42ff01b5aa | |||
| 5f9e9513ef | |||
| 7e2b81729e | |||
| 967478b3a7 | |||
| d706899b7e | |||
| 90ccabd60b | |||
| cc061ca716 | |||
| 763f7b9be8 | |||
| c4ef002392 | |||
| 83b564781f | |||
| 929244215c | |||
| 94f1d77e22 | |||
| 67533a1b29 | |||
| 9bf7ff23c0 | |||
| a853a58c62 | |||
| 5392ac2e07 | |||
| b5d9f27ca4 | |||
| 399453d9f1 | |||
| 593928a9f3 | |||
| 59443bfe18 | |||
| 7c2471e3cc | |||
| 8da5627c6c | |||
| da071c1fce | |||
| 59cab5e7d9 | |||
| d56ca04162 | |||
| 5ca7928153 | |||
| 23233c3041 | |||
| 92f7587a40 | |||
| 16f1414e5c | |||
| 9999414b3b | |||
| 212bb7fef6 | |||
| 703d54677e | |||
| 567265123b | |||
| 9bfe410a0c | |||
| b1224835be | |||
| de378599d3 | |||
| 6403a9f10e | |||
| fe3b36af68 | |||
| 23498294de | |||
| 26c205589b | |||
| 99bd1a1533 | |||
| 3c1ee64b7f | |||
| 60fac67884 | |||
| 612a63c0f1 | |||
| 67547e61c6 | |||
| 5de6ae6fca | |||
| a3c5625d4e | |||
| 875e7f8630 | |||
| e88eb0ecf7 | |||
| e881d4b144 | |||
| b31f2bdad2 | |||
| a16d178d72 | |||
| f09093132e | |||
| dd0d0d51f6 | |||
| 273d952ddf | |||
| 3809d885b6 | |||
| 6305a69cc1 | |||
| 311b333814 | |||
| d54b903d28 | |||
| e8335c94d5 | |||
| c6e2a5ea33 | |||
| 71d384f1f8 | |||
| b313b3395f | |||
| 3c3e8e6a8b | |||
| a07dc80d72 | |||
| 14e249aee3 | |||
| b883aad1f1 | |||
| e4cb25f365 | |||
| 7bcda3a29b | |||
| 715e8c9ef6 | |||
| 65acda8d3e | |||
| 2f80a085f5 | |||
| 94824e30a4 | |||
| 0e9ecb6c99 | |||
| 67a06f5edc | |||
| c908ec1937 | |||
| df99889aa6 | |||
| 3276f81851 | |||
| a64e7091e0 | |||
| 7f59381c7d | |||
| 3f30dcae80 | |||
| 613bd3be1d | |||
| 745cfcb161 | |||
| 73e3df5df5 | |||
| 2dc9020f80 | |||
| 29fe8cecbb | |||
| 8f7debc769 | |||
| 1e64ffa7ba | |||
| f3c616ca72 | |||
| 8a59a63ade | |||
| 1da903dd59 | |||
| 5af3223e76 | |||
| 21800a5fa6 | |||
| 247662de6b | |||
| 4e8a6b9695 | |||
| 4ca64684f6 | |||
| e9cded560d | |||
| 2aa8aef216 | |||
| 3e736898a6 | |||
| 12e05280ad | |||
| b1c1a232ca | |||
| 1b85f6277d | |||
| 084b4003d1 | |||
| 76e58405b8 | |||
| 5883ea2721 | |||
| e15ed44a68 | |||
| 04bbc2ac2b | |||
| f28e08eceb | |||
| 816466e492 | |||
| d1708460e7 | |||
| 66bb145247 | |||
| 4d3668a0cb | |||
| a7c736915a | |||
| 3543e47841 | |||
| 147b8fb755 | |||
| 153690e717 | |||
| 1b4b4c3302 | |||
| 8e81360eba | |||
| 65e8d85142 | |||
| 69b4f33cfa | |||
| 48d06a4291 | |||
| fdfe58362e | |||
| 95f76af19c | |||
| 7bd524e9d7 | |||
| 6b1170b19a | |||
| 3bc1d42dcd | |||
| 859953fe81 | |||
| 5abca033d0 | |||
| a378480faf | |||
| fbc1b96aa6 | |||
| 7b1de6e1a8 | |||
| 749a4ac34a | |||
| a20e561897 | |||
| f0564b746a | |||
| c3f439417e | |||
| 71ed8143a1 | |||
| 4e32615b22 | |||
| afc398333e | |||
| 0a9c768b81 | |||
| 54e6103def | |||
| 60725294e2 | |||
| 8ffc3334b4 | |||
| 784a6d46c0 | |||
| b71a7ee26f | |||
| 893adb40e2 | |||
| 9bd60f6554 | |||
| c0ccdc24a0 | |||
| be560d7ad5 | |||
| e7e230608e | |||
| e74f868a23 | |||
| 89ee0b077f | |||
| cdde19c0bc | |||
| e9d63a0a7c | |||
| cdadb834b0 | |||
| ff65ccba3e | |||
| 27adbb9a35 | |||
| b69f081a79 | |||
| d163711def | |||
| 34067678a1 | |||
| 5dfdee6d7d | |||
| db6d7e2c69 |
@@ -1,4 +1,4 @@
|
||||
# <img src="src/docs/asciidoc/images/spring-framework.png" width="80" height="80"> Spring Framework [](https://build.spring.io/browse/SPR)
|
||||
# <img src="src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build")
|
||||
|
||||
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".
|
||||
|
||||
@@ -17,6 +17,10 @@ For access to artifacts or a distribution zip, see the [Spring Framework Artifac
|
||||
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.
|
||||
|
||||
## 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.
|
||||
|
||||
+46
-37
@@ -1,18 +1,15 @@
|
||||
plugins {
|
||||
id 'io.spring.dependency-management' version '1.0.8.RELEASE' apply false
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.3.72' apply false
|
||||
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.4.0-rc' apply false
|
||||
id 'org.jetbrains.dokka' version '0.10.1' apply false
|
||||
id 'org.asciidoctor.jvm.convert' version '2.4.0'
|
||||
id 'io.spring.gradle-enterprise-conventions' version '0.0.2'
|
||||
id 'io.spring.nohttp' version '0.0.5.RELEASE'
|
||||
id 'de.undercouch.download' version '4.0.0'
|
||||
id 'com.gradle.build-scan' version '3.2'
|
||||
id "com.jfrog.artifactory" version '4.12.0' apply false
|
||||
id "io.freefair.aspectj" version '4.1.1' apply false
|
||||
id "com.github.ben-manes.versions" version '0.24.0'
|
||||
id 'de.undercouch.download' version '4.0.4'
|
||||
id "io.freefair.aspectj" version '5.0.0' apply false
|
||||
id "com.github.ben-manes.versions" version '0.28.0'
|
||||
id "me.champeau.gradle.jmh" version "0.5.0" apply false
|
||||
}
|
||||
|
||||
apply from: "$rootDir/gradle/build-scan-user-data.gradle"
|
||||
ext {
|
||||
moduleProjects = subprojects.findAll { it.name.startsWith("spring-") }
|
||||
javaProjects = subprojects - project(":framework-bom")
|
||||
@@ -26,13 +23,14 @@ configure(allprojects) { project ->
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.10.5"
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.11.2"
|
||||
mavenBom "io.netty:netty-bom:4.1.51.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:Dysprosium-SR10"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.0.1"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.0-M2"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR5"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.0-M1"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.31.v20200723"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.3.72"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.3.5"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.4.0-rc"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.3.8-1.4.0-rc"
|
||||
mavenBom "org.junit:junit-bom:5.6.2"
|
||||
}
|
||||
dependencies {
|
||||
@@ -43,17 +41,20 @@ configure(allprojects) { project ->
|
||||
entry 'log4j-jul'
|
||||
}
|
||||
dependency "org.slf4j:slf4j-api:1.7.30"
|
||||
dependency("com.google.code.findbugs:findbugs:3.0.1") {
|
||||
exclude group: "dom4j", name: "dom4j"
|
||||
}
|
||||
dependency "com.google.code.findbugs:jsr305:3.0.2"
|
||||
|
||||
dependencySet(group: 'org.aspectj', version: '1.9.5') {
|
||||
dependencySet(group: 'org.aspectj', version: '1.9.6') {
|
||||
entry 'aspectjrt'
|
||||
entry 'aspectjtools'
|
||||
entry 'aspectjweaver'
|
||||
}
|
||||
dependencySet(group: 'org.codehaus.groovy', version: '2.5.13') {
|
||||
dependencySet(group: 'org.codehaus.groovy', version: '3.0.5') {
|
||||
entry 'groovy'
|
||||
entry 'groovy-jsr223'
|
||||
entry 'groovy-templates'
|
||||
entry 'groovy-templates' // requires findbugs for warning-free compilation
|
||||
entry 'groovy-test'
|
||||
entry 'groovy-xml'
|
||||
}
|
||||
@@ -61,6 +62,7 @@ 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.19"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.0.5"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.2.RELEASE"
|
||||
|
||||
dependency "com.caucho:hessian:4.0.63"
|
||||
@@ -69,9 +71,9 @@ configure(allprojects) { project ->
|
||||
exclude group: "stax", name: "stax-api"
|
||||
}
|
||||
dependency "com.google.code.gson:gson:2.8.6"
|
||||
dependency "com.google.protobuf:protobuf-java-util:3.11.4"
|
||||
dependency "com.google.protobuf:protobuf-java-util:3.12.4"
|
||||
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.11.1") {
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.12") {
|
||||
exclude group: "xpp3", name: "xpp3_min"
|
||||
exclude group: "xmlpull", name: "xmlpull"
|
||||
}
|
||||
@@ -89,11 +91,11 @@ configure(allprojects) { project ->
|
||||
dependency "com.h2database:h2:1.4.200"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:2.8.5"
|
||||
dependency "com.github.librepdf:openpdf:1.3.20"
|
||||
dependency "com.rometools:rome:1.12.2"
|
||||
dependency "com.rometools:rome:1.15.0"
|
||||
dependency "commons-io:commons-io:2.5"
|
||||
dependency "io.vavr:vavr:0.10.3"
|
||||
dependency "net.sf.jopt-simple:jopt-simple:5.0.4"
|
||||
dependencySet(group: 'org.apache.activemq', version: '5.8.0') {
|
||||
dependencySet(group: 'org.apache.activemq', version: '5.16.0') {
|
||||
entry 'activemq-broker'
|
||||
entry('activemq-kahadb-store') {
|
||||
exclude group: "org.springframework", name: "spring-context"
|
||||
@@ -109,7 +111,7 @@ configure(allprojects) { project ->
|
||||
dependency "org.apache.poi:poi-ooxml:4.1.2"
|
||||
dependency "org.apache-extras.beanshell:bsh:2.0b6"
|
||||
dependency "org.freemarker:freemarker:2.3.30"
|
||||
dependency "org.hsqldb:hsqldb:2.5.0"
|
||||
dependency "org.hsqldb:hsqldb:2.5.1"
|
||||
dependency "org.quartz-scheduler:quartz:2.3.2"
|
||||
dependency "org.codehaus.fabric3.api:commonj:1.1.0"
|
||||
dependency "net.sf.ehcache:ehcache:2.10.6"
|
||||
@@ -131,7 +133,7 @@ configure(allprojects) { project ->
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
dependencySet(group: 'io.undertow', version: '2.0.30.Final') {
|
||||
dependencySet(group: 'io.undertow', version: '2.1.3.Final') {
|
||||
entry 'undertow-core'
|
||||
entry('undertow-websockets-jsr') {
|
||||
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
|
||||
@@ -152,31 +154,34 @@ configure(allprojects) { project ->
|
||||
dependency("org.apache.httpcomponents:httpasyncclient:4.1.4") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency 'org.apache.httpcomponents.client5:httpclient5:5.0.1'
|
||||
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.0.1'
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.4"
|
||||
|
||||
dependency "org.jruby:jruby:9.2.11.1"
|
||||
dependency "org.jruby:jruby:9.2.12.0"
|
||||
dependency "org.python:jython-standalone:2.7.1"
|
||||
dependency "org.mozilla:rhino:1.7.11"
|
||||
|
||||
dependency "commons-fileupload:commons-fileupload:1.4"
|
||||
dependency "org.synchronoss.cloud:nio-multipart-parser:1.1.0"
|
||||
|
||||
dependency("dom4j:dom4j:1.6.1") {
|
||||
exclude group: "xml-apis", name: "xml-apis"
|
||||
dependency("org.dom4j:dom4j:2.1.3") {
|
||||
exclude group: "jaxen", name: "jaxen"
|
||||
exclude group: "net.java.dev.msv", name: "xsdlib"
|
||||
exclude group: "pull-parser", name: "pull-parser"
|
||||
exclude group: "xpp3", name: "xpp3"
|
||||
}
|
||||
dependency("jaxen:jaxen:1.1.1") {
|
||||
exclude group: "xml-apis", name: "xml-apis"
|
||||
exclude group: "xom", name: "xom"
|
||||
exclude group: "xerces", name: "xercesImpl"
|
||||
dependency("jaxen:jaxen:1.2.0") {
|
||||
exclude group: "dom4j", name: "dom4j"
|
||||
}
|
||||
|
||||
dependency("junit:junit:4.12") {
|
||||
dependency("junit:junit:4.13") {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
dependency("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.1") {
|
||||
exclude group: "junit", name: "junit"
|
||||
}
|
||||
dependency "org.testng:testng:6.14.3"
|
||||
dependency "org.testng:testng:7.3.0"
|
||||
dependency "org.hamcrest:hamcrest:2.1"
|
||||
dependency "org.awaitility:awaitility:3.1.6"
|
||||
dependency "org.assertj:assertj-core:3.16.1"
|
||||
@@ -186,7 +191,7 @@ configure(allprojects) { project ->
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.mockito', version: '3.3.3') {
|
||||
dependencySet(group: 'org.mockito', version: '3.4.6') {
|
||||
entry('mockito-core') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
@@ -194,10 +199,10 @@ configure(allprojects) { project ->
|
||||
}
|
||||
dependency "io.mockk:mockk:1.10.0"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.42.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.43.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.42.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.43.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
@@ -206,6 +211,7 @@ configure(allprojects) { project ->
|
||||
}
|
||||
dependency "org.skyscreamer:jsonassert:1.5.0"
|
||||
dependency "com.jayway.jsonpath:json-path:2.4.0"
|
||||
dependency "org.bouncycastle:bcpkix-jdk15on:1.66"
|
||||
|
||||
dependencySet(group: 'org.apache.tiles', version: '3.0.8') {
|
||||
entry 'tiles-api'
|
||||
@@ -279,6 +285,7 @@ configure(allprojects) { project ->
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://repo.spring.io/libs-spring-framework-build" }
|
||||
maven { url "https://repo.spring.io/milestone" } // Reactor
|
||||
}
|
||||
}
|
||||
configurations.all {
|
||||
@@ -304,6 +311,8 @@ configure([rootProject] + javaProjects) { project ->
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
languageVersion = "1.3"
|
||||
apiVersion = "1.3"
|
||||
freeCompilerArgs = ["-Xjsr305=strict"]
|
||||
allWarningsAsErrors = true
|
||||
}
|
||||
@@ -326,7 +335,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "8.35"
|
||||
configDir = rootProject.file("src/checkstyle")
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -365,7 +374,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
"https://fasterxml.github.io/jackson-databind/javadoc/2.10/",
|
||||
"https://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.10/",
|
||||
"https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/",
|
||||
"https://junit.org/junit4/javadoc/4.12/",
|
||||
"https://junit.org/junit4/javadoc/4.13/",
|
||||
"https://junit.org/junit5/docs/5.6.2/api/"
|
||||
] as String[]
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
apply from: "../gradle/build-cache-settings.gradle"
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
== Spring Framework Concourse pipeline
|
||||
|
||||
The Spring Framework is using https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
|
||||
The Spring team has a dedicated Concourse instance available at https://ci.spring.io.
|
||||
|
||||
=== Setting up your development environment
|
||||
|
||||
If you're part of the Spring Framework project on GitHub, you can get access to CI management features.
|
||||
First, you need to go to https://ci.spring.io and install the client CLI for your platform (see bottom right of the screen).
|
||||
|
||||
You can then login with the instance using:
|
||||
|
||||
[source]
|
||||
----
|
||||
$ fly -t spring login -n spring-framework -c https://ci.spring.io
|
||||
----
|
||||
|
||||
Once logged in, you should get something like:
|
||||
|
||||
[source]
|
||||
----
|
||||
$ fly ts
|
||||
name url team expiry
|
||||
spring https://ci.spring.io spring-framework Wed, 25 Mar 2020 17:45:26 UTC
|
||||
----
|
||||
|
||||
=== Pipeline configuration and structure
|
||||
The build pipelines are described in `pipeline.yml` file.
|
||||
This file is listing Concourse resources, i.e. build inputs and outputs such as container images, artifact repositories, source repositories, notification services, etc.
|
||||
It also describes jobs (a job is a sequence of inputs, tasks and outputs); jobs are organized by groups.
|
||||
|
||||
The `pipeline.yml` definition contains `((parameters))` which are loaded from the `parameters.yml` file or from our https://docs.cloudfoundry.org/credhub/[credhub instance].
|
||||
|
||||
You'll find in this folder the following resources:
|
||||
* `pipeline.yml` the build pipeline
|
||||
* `parameters.yml` the build parameters used for the pipeline
|
||||
* `images/` holds the container images definitions used in this pipeline
|
||||
* `scripts/` holds the build scripts that ship within the CI container images
|
||||
* `tasks` contains the task definitions used in the main `pipeline.yml`
|
||||
|
||||
=== Updating the build pipeline
|
||||
|
||||
Updating files on the repository is not enough to update the build pipeline, as changes need to be applied.
|
||||
The pipeline can be deployed using the following command:
|
||||
|
||||
[source]
|
||||
----
|
||||
$ fly -t spring set-pipeline -p spring-framework-5.3.x -c ci/pipeline.yml -l ci/parameters.yml
|
||||
----
|
||||
|
||||
NOTE: This assumes that you have credhub integration configured with the appropriate secrets.
|
||||
@@ -0,0 +1,21 @@
|
||||
== CI Images
|
||||
|
||||
These images are used by CI to run the actual builds.
|
||||
|
||||
To build the image locally run the following from this directory:
|
||||
|
||||
----
|
||||
$ docker build --no-cache -f <image-folder>/Dockerfile .
|
||||
----
|
||||
|
||||
For example
|
||||
|
||||
----
|
||||
$ docker build --no-cache -f spring-framework-ci-image/Dockerfile .
|
||||
----
|
||||
|
||||
To test run:
|
||||
|
||||
----
|
||||
$ docker run -it --entrypoint /bin/bash <SHA>
|
||||
----
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
java8)
|
||||
echo "https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u265-b01/OpenJDK8U-jdk_x64_linux_hotspot_8u265b01.tar.gz"
|
||||
;;
|
||||
java11)
|
||||
echo "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_linux_hotspot_11.0.8_10.tar.gz"
|
||||
;;
|
||||
java14)
|
||||
echo "https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk-14.0.2%2B12/OpenJDK14U-jdk_x64_linux_hotspot_14.0.2_12.tar.gz"
|
||||
;;
|
||||
java15)
|
||||
echo "https://download.java.net/java/early_access/jdk15/33/GPL/openjdk-15-ea+33_linux-x64_bin.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
exit 1
|
||||
esac
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
###########################################################
|
||||
# UTILS
|
||||
###########################################################
|
||||
|
||||
apt-get update
|
||||
apt-get install --no-install-recommends -y ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq fontconfig
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.3/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.2.0/concourse-release-scripts-0.2.0.jar
|
||||
|
||||
###########################################################
|
||||
# JAVA
|
||||
###########################################################
|
||||
JDK_URL=$( ./get-jdk-url.sh $1 )
|
||||
|
||||
mkdir -p /opt/openjdk
|
||||
cd /opt/openjdk
|
||||
curl -L ${JDK_URL} | tar zx --strip-components=1
|
||||
test -f /opt/openjdk/bin/java
|
||||
test -f /opt/openjdk/bin/javac
|
||||
|
||||
###########################################################
|
||||
# GRADLE ENTERPRISE
|
||||
###########################################################
|
||||
cd /
|
||||
mkdir ~/.gradle
|
||||
echo 'systemProp.user.name=concourse' > ~/.gradle/gradle.properties
|
||||
@@ -0,0 +1,8 @@
|
||||
FROM ubuntu:bionic-20200713
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
RUN ./setup.sh java8
|
||||
|
||||
ENV JAVA_HOME /opt/openjdk
|
||||
ENV PATH $JAVA_HOME/bin:$PATH
|
||||
@@ -0,0 +1,8 @@
|
||||
FROM ubuntu:bionic-20200713
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
RUN ./setup.sh java11
|
||||
|
||||
ENV JAVA_HOME /opt/openjdk
|
||||
ENV PATH $JAVA_HOME/bin:$PATH
|
||||
@@ -0,0 +1,8 @@
|
||||
FROM ubuntu:bionic-20200713
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
RUN ./setup.sh java14
|
||||
|
||||
ENV JAVA_HOME /opt/openjdk
|
||||
ENV PATH $JAVA_HOME/bin:$PATH
|
||||
@@ -0,0 +1,8 @@
|
||||
FROM ubuntu:bionic-20200713
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
RUN ./setup.sh java15
|
||||
|
||||
ENV JAVA_HOME /opt/openjdk
|
||||
ENV PATH $JAVA_HOME/bin:$PATH
|
||||
@@ -0,0 +1,14 @@
|
||||
email-server: "smtp.svc.pivotal.io"
|
||||
email-from: "ci@spring.io"
|
||||
email-to: ["spring-framework-dev@pivotal.io"]
|
||||
github-repo: "https://github.com/spring-projects/spring-framework.git"
|
||||
github-repo-name: "spring-projects/spring-framework"
|
||||
docker-hub-organization: "springci"
|
||||
artifactory-server: "https://repo.spring.io"
|
||||
branch: "master"
|
||||
build-name: "spring-framework"
|
||||
pipeline-name: "spring-framework"
|
||||
concourse-url: "https://ci.spring.io"
|
||||
bintray-subject: "spring"
|
||||
bintray-repo: "jars"
|
||||
task-timeout: 1h00m
|
||||
+367
@@ -0,0 +1,367 @@
|
||||
resource_types:
|
||||
- name: artifactory-resource
|
||||
type: docker-image
|
||||
source:
|
||||
repository: springio/artifactory-resource
|
||||
tag: 0.0.12-SNAPSHOT
|
||||
- name: github-status-resource
|
||||
type: docker-image
|
||||
source:
|
||||
repository: dpb587/github-status-resource
|
||||
tag: master
|
||||
- name: email
|
||||
type: docker-image
|
||||
source:
|
||||
repository: pcfseceng/email-resource
|
||||
tag: 1.0.19
|
||||
- name: slack-notification
|
||||
type: docker-image
|
||||
source:
|
||||
repository: cfcommunity/slack-notification-resource
|
||||
tag: latest
|
||||
resources:
|
||||
- name: git-repo
|
||||
type: git
|
||||
icon: github-circle
|
||||
source:
|
||||
uri: ((github-repo))
|
||||
username: ((github-username))
|
||||
password: ((github-password))
|
||||
branch: ((branch))
|
||||
- name: every-morning
|
||||
type: time
|
||||
icon: alarm
|
||||
source:
|
||||
start: 8:00 AM
|
||||
stop: 9:00 AM
|
||||
location: Europe/Vienna
|
||||
- name: ci-images-git-repo
|
||||
type: git
|
||||
icon: github-circle
|
||||
source:
|
||||
uri: ((github-repo))
|
||||
branch: ((branch))
|
||||
paths: ["ci/images/*"]
|
||||
- name: spring-framework-ci-image
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
repository: ((docker-hub-organization))/spring-framework-ci-image
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
- name: spring-framework-jdk11-ci-image
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
repository: ((docker-hub-organization))/spring-framework-jdk11-ci-image
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
- name: spring-framework-jdk14-ci-image
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
repository: ((docker-hub-organization))/spring-framework-jdk14-ci-image
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
- name: spring-framework-jdk15-ci-image
|
||||
type: docker-image
|
||||
icon: docker
|
||||
source:
|
||||
repository: ((docker-hub-organization))/spring-framework-jdk15-ci-image
|
||||
username: ((docker-hub-username))
|
||||
password: ((docker-hub-password))
|
||||
tag: 5.3.x
|
||||
- name: artifactory-repo
|
||||
type: artifactory-resource
|
||||
icon: package-variant
|
||||
source:
|
||||
uri: ((artifactory-server))
|
||||
username: ((artifactory-username))
|
||||
password: ((artifactory-password))
|
||||
build_name: ((build-name))
|
||||
- name: repo-status-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: build
|
||||
- name: repo-status-jdk11-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk11-build
|
||||
- name: repo-status-jdk14-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk14-build
|
||||
- name: repo-status-jdk15-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk15-build
|
||||
- name: slack-alert
|
||||
type: slack-notification
|
||||
icon: slack
|
||||
source:
|
||||
url: ((slack-webhook-url))
|
||||
jobs:
|
||||
- name: build-spring-framework-ci-images
|
||||
plan:
|
||||
- get: ci-images-git-repo
|
||||
trigger: true
|
||||
- in_parallel:
|
||||
- put: spring-framework-ci-image
|
||||
params:
|
||||
build: ci-images-git-repo/ci/images
|
||||
dockerfile: ci-images-git-repo/ci/images/spring-framework-ci-image/Dockerfile
|
||||
- put: spring-framework-jdk11-ci-image
|
||||
params:
|
||||
build: ci-images-git-repo/ci/images
|
||||
dockerfile: ci-images-git-repo/ci/images/spring-framework-jdk11-ci-image/Dockerfile
|
||||
- put: spring-framework-jdk14-ci-image
|
||||
params:
|
||||
build: ci-images-git-repo/ci/images
|
||||
dockerfile: ci-images-git-repo/ci/images/spring-framework-jdk14-ci-image/Dockerfile
|
||||
- put: spring-framework-jdk15-ci-image
|
||||
params:
|
||||
build: ci-images-git-repo/ci/images
|
||||
dockerfile: ci-images-git-repo/ci/images/spring-framework-jdk15-ci-image/Dockerfile
|
||||
- name: build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
- get: spring-framework-ci-image
|
||||
- get: git-repo
|
||||
trigger: true
|
||||
- put: repo-status-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: build-project
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
image: spring-framework-ci-image
|
||||
file: git-repo/ci/tasks/build-project.yml
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
text: >
|
||||
:concourse-failed: ${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!
|
||||
[<https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|build log>]
|
||||
[<$TEXT_FILE_CONTENT|build scan>]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
- put: repo-status-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- put: artifactory-repo
|
||||
params: &artifactory-params
|
||||
repo: libs-snapshot-local
|
||||
folder: distribution-repository
|
||||
build_uri: "https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}"
|
||||
build_number: "${BUILD_PIPELINE_NAME}-${BUILD_JOB_NAME}-${BUILD_NAME}"
|
||||
disable_checksum_uploads: true
|
||||
threads: 8
|
||||
artifact_set:
|
||||
- include:
|
||||
- "/**/spring-*.zip"
|
||||
properties:
|
||||
"zip.name": "spring-framework"
|
||||
"zip.displayname": "Spring Framework"
|
||||
"zip.deployed": "false"
|
||||
- include:
|
||||
- "/**/spring-*-docs.zip"
|
||||
properties:
|
||||
"zip.type": "docs"
|
||||
- include:
|
||||
- "/**/spring-*-dist.zip"
|
||||
properties:
|
||||
"zip.type": "dist"
|
||||
- include:
|
||||
- "/**/spring-*-schema.zip"
|
||||
properties:
|
||||
"zip.type": "schema"
|
||||
get_params:
|
||||
threads: 8
|
||||
- name: jdk11-build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
- get: spring-framework-jdk11-ci-image
|
||||
- get: git-repo
|
||||
- get: every-morning
|
||||
trigger: true
|
||||
- put: repo-status-jdk11-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: check-project
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
image: spring-framework-jdk11-ci-image
|
||||
file: git-repo/ci/tasks/check-project.yml
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk11-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
text: >
|
||||
:concourse-failed: ${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!
|
||||
[<https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|build log>]
|
||||
[<$TEXT_FILE_CONTENT|build scan>]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
- put: repo-status-jdk11-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: jdk14-build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
- get: spring-framework-jdk14-ci-image
|
||||
- get: git-repo
|
||||
- get: every-morning
|
||||
trigger: true
|
||||
- put: repo-status-jdk14-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: check-project
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
image: spring-framework-jdk14-ci-image
|
||||
file: git-repo/ci/tasks/check-project.yml
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk14-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
text: >
|
||||
:concourse-failed: ${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!
|
||||
[<https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|build log>]
|
||||
[<$TEXT_FILE_CONTENT|build scan>]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
- put: repo-status-jdk14-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: jdk15-build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
- get: spring-framework-jdk15-ci-image
|
||||
- get: git-repo
|
||||
- get: every-morning
|
||||
trigger: true
|
||||
- put: repo-status-jdk15-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: check-project
|
||||
privileged: true
|
||||
timeout: ((task-timeout))
|
||||
image: spring-framework-jdk15-ci-image
|
||||
file: git-repo/ci/tasks/check-project.yml
|
||||
params:
|
||||
BRANCH: ((branch))
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk15-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
text: >
|
||||
:concourse-failed: ${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!
|
||||
[<https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|build log>]
|
||||
[<$TEXT_FILE_CONTENT|build scan>]
|
||||
text_file: git-repo/build/build-scan-uri.txt
|
||||
silent: true
|
||||
icon_emoji: ":concourse:"
|
||||
username: concourse-ci
|
||||
- put: repo-status-jdk15-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: stage-milestone
|
||||
serial: true
|
||||
plan:
|
||||
- get: spring-framework-ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- task: stage
|
||||
image: spring-framework-ci-image
|
||||
file: git-repo/ci/tasks/stage-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
|
||||
- put: artifactory-repo
|
||||
params:
|
||||
<<: *artifactory-params
|
||||
repo: libs-staging-local
|
||||
- put: git-repo
|
||||
params:
|
||||
repository: stage-git-repo
|
||||
- name: promote-milestone
|
||||
serial: true
|
||||
plan:
|
||||
- get: spring-framework-ci-image
|
||||
- get: git-repo
|
||||
trigger: false
|
||||
- get: artifactory-repo
|
||||
trigger: false
|
||||
passed: [stage-milestone]
|
||||
params:
|
||||
download_artifacts: false
|
||||
save_build_info: true
|
||||
- task: promote
|
||||
image: spring-framework-ci-image
|
||||
file: git-repo/ci/tasks/promote-version.yml
|
||||
params:
|
||||
RELEASE_TYPE: M
|
||||
ARTIFACTORY_SERVER: ((artifactory-server))
|
||||
ARTIFACTORY_USERNAME: ((artifactory-username))
|
||||
ARTIFACTORY_PASSWORD: ((artifactory-password))
|
||||
groups:
|
||||
- name: "Build"
|
||||
jobs: ["build", "jdk11-build", "jdk14-build", "jdk15-build"]
|
||||
- name: "Release"
|
||||
jobs: ["stage-milestone", "promote-milestone"]
|
||||
- name: "CI Images"
|
||||
jobs: ["build-spring-framework-ci-images"]
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
repository=$(pwd)/distribution-repository
|
||||
|
||||
pushd git-repo > /dev/null
|
||||
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
|
||||
popd > /dev/null
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
|
||||
pushd git-repo > /dev/null
|
||||
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 check
|
||||
popd > /dev/null
|
||||
@@ -0,0 +1,2 @@
|
||||
source /opt/concourse-java.sh
|
||||
setup_symlinks
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
|
||||
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 promote $RELEASE_TYPE $BUILD_INFO_LOCATION > /dev/null || { exit 1; }
|
||||
|
||||
java -jar /opt/concourse-release-scripts.jar distribute $RELEASE_TYPE $BUILD_INFO_LOCATION > /dev/null || { exit 1; }
|
||||
|
||||
echo "Promotion complete"
|
||||
echo $version > version/version
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/common.sh
|
||||
repository=$(pwd)/distribution-repository
|
||||
|
||||
pushd git-repo > /dev/null
|
||||
git fetch --tags --all > /dev/null
|
||||
popd > /dev/null
|
||||
|
||||
git clone git-repo stage-git-repo > /dev/null
|
||||
|
||||
pushd stage-git-repo > /dev/null
|
||||
|
||||
snapshotVersion=$( awk -F '=' '$1 == "version" { print $2 }' gradle.properties )
|
||||
if [[ $RELEASE_TYPE = "M" ]]; then
|
||||
stageVersion=$( get_next_milestone_release $snapshotVersion)
|
||||
nextVersion=$snapshotVersion
|
||||
elif [[ $RELEASE_TYPE = "RC" ]]; then
|
||||
stageVersion=$( get_next_rc_release $snapshotVersion)
|
||||
nextVersion=$snapshotVersion
|
||||
elif [[ $RELEASE_TYPE = "RELEASE" ]]; then
|
||||
stageVersion=$( get_next_release $snapshotVersion)
|
||||
nextVersion=$( bump_version_number $snapshotVersion)
|
||||
else
|
||||
echo "Unknown release type $RELEASE_TYPE" >&2; exit 1;
|
||||
fi
|
||||
|
||||
echo "Staging $stageVersion (next version will be $nextVersion)"
|
||||
sed -i "s/version=$snapshotVersion/version=$stageVersion/" gradle.properties
|
||||
|
||||
git config user.name "Spring Buildmaster" > /dev/null
|
||||
git config user.email "buildmaster@springframework.org" > /dev/null
|
||||
git add gradle.properties > /dev/null
|
||||
git commit -m"Release v$stageVersion" > /dev/null
|
||||
git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null
|
||||
|
||||
./gradlew --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
|
||||
|
||||
git reset --hard HEAD^ > /dev/null
|
||||
if [[ $nextVersion != $snapshotVersion ]]; then
|
||||
echo "Setting next development version (v$nextVersion)"
|
||||
sed -i "s/version=$snapshotVersion/version=$nextVersion/" gradle.properties
|
||||
git add gradle.properties > /dev/null
|
||||
git commit -m"Next development version (v$nextVersion)" > /dev/null
|
||||
fi;
|
||||
|
||||
echo "Staging Complete"
|
||||
|
||||
popd > /dev/null
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
outputs:
|
||||
- name: distribution-repository
|
||||
- name: git-repo
|
||||
caches:
|
||||
- path: gradle
|
||||
params:
|
||||
BRANCH:
|
||||
CI: true
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY:
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME:
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD:
|
||||
GRADLE_ENTERPRISE_URL: https://ge.spring.io
|
||||
run:
|
||||
path: bash
|
||||
args:
|
||||
- -ec
|
||||
- |
|
||||
${PWD}/git-repo/ci/scripts/build-project.sh
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
outputs:
|
||||
- name: distribution-repository
|
||||
- name: git-repo
|
||||
caches:
|
||||
- path: gradle
|
||||
params:
|
||||
BRANCH:
|
||||
CI: true
|
||||
GRADLE_ENTERPRISE_ACCESS_KEY:
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME:
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD:
|
||||
GRADLE_ENTERPRISE_URL: https://ge.spring.io
|
||||
run:
|
||||
path: bash
|
||||
args:
|
||||
- -ec
|
||||
- |
|
||||
${PWD}/git-repo/ci/scripts/check-project.sh
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: artifactory-repo
|
||||
outputs:
|
||||
- name: version
|
||||
params:
|
||||
RELEASE_TYPE:
|
||||
ARTIFACTORY_SERVER:
|
||||
ARTIFACTORY_USERNAME:
|
||||
ARTIFACTORY_PASSWORD:
|
||||
BINTRAY_SUBJECT:
|
||||
BINTRAY_REPO:
|
||||
BINTRAY_USERNAME:
|
||||
BINTRAY_API_KEY:
|
||||
run:
|
||||
path: git-repo/ci/scripts/promote-version.sh
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
platform: linux
|
||||
inputs:
|
||||
- name: git-repo
|
||||
outputs:
|
||||
- name: stage-git-repo
|
||||
- name: distribution-repository
|
||||
params:
|
||||
RELEASE_TYPE:
|
||||
CI: true
|
||||
GRADLE_ENTERPRISE_CACHE_USERNAME:
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD:
|
||||
GRADLE_ENTERPRISE_URL: https://ge.spring.io
|
||||
caches:
|
||||
- path: gradle
|
||||
run:
|
||||
path: git-repo/ci/scripts/stage-version.sh
|
||||
@@ -18,12 +18,6 @@ publishing {
|
||||
mavenJava(MavenPublication) {
|
||||
artifactId = 'spring-framework-bom'
|
||||
from components.javaPlatform
|
||||
// remove scope information from published BOM
|
||||
pom.withXml {
|
||||
asNode().dependencyManagement.first().dependencies.first().each {
|
||||
it.remove(it.scope.first())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
version=5.2.9.BUILD-SNAPSHOT
|
||||
version=5.3.0-M2
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
kotlin.stdlib.default.dependency=false
|
||||
@@ -1,18 +0,0 @@
|
||||
buildCache {
|
||||
local {
|
||||
enabled = true
|
||||
}
|
||||
remote(HttpBuildCache) {
|
||||
enabled = true
|
||||
url = 'https://ge.spring.io/cache/'
|
||||
def cacheUsername = System.getenv('GRADLE_ENTERPRISE_CACHE_USERNAME')
|
||||
def cachePassword = System.getenv('GRADLE_ENTERPRISE_CACHE_PASSWORD')
|
||||
if (cacheUsername && cachePassword) {
|
||||
push = true
|
||||
credentials {
|
||||
username = cacheUsername
|
||||
password = cachePassword
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
addCustomJavaHomeMetadata()
|
||||
addCustomJavaSourceVersionMetadata()
|
||||
|
||||
void addCustomJavaHomeMetadata() {
|
||||
def customJavaHome = System.getProperty("customJavaHome")
|
||||
if (customJavaHome) {
|
||||
buildScan.value "Custom JAVA_HOME", customJavaHome
|
||||
}
|
||||
}
|
||||
|
||||
void addCustomJavaSourceVersionMetadata() {
|
||||
def customJavaSourceVersion = System.getProperty("customJavaSourceVersion")
|
||||
if (customJavaSourceVersion) {
|
||||
buildScan.value "Custom Java Source Version", customJavaSourceVersion
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -3,7 +3,7 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.4.0.RELEASE")
|
||||
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.4.2.RELEASE")
|
||||
}
|
||||
|
||||
repositories {
|
||||
@@ -110,7 +110,7 @@ dokka {
|
||||
}
|
||||
|
||||
task downloadResources(type: Download) {
|
||||
def version = "0.2.1.RELEASE"
|
||||
def version = "0.2.2.RELEASE"
|
||||
src "https://repo.spring.io/release/io/spring/docresources/" +
|
||||
"spring-doc-resources/$version/spring-doc-resources-${version}.zip"
|
||||
dest project.file("$buildDir/docs/spring-doc-resources.zip")
|
||||
@@ -145,7 +145,7 @@ asciidoctor {
|
||||
outputDir "$buildDir/docs/ref-docs/"
|
||||
resources {
|
||||
from(sourceDir) {
|
||||
include 'images/*', 'css/**', 'js/**'
|
||||
include 'images/*.png', 'css/**', 'js/**'
|
||||
}
|
||||
from extractDocResources
|
||||
}
|
||||
@@ -164,7 +164,7 @@ asciidoctor {
|
||||
sectnums: '',
|
||||
'source-highlighter': 'highlight.js',
|
||||
highlightjsdir: 'js/highlight',
|
||||
'highlightjs-theme': 'github', // 'googlecode',
|
||||
'highlightjs-theme': 'googlecode',
|
||||
stylesdir: 'css/',
|
||||
stylesheet: 'stylesheet.css',
|
||||
'spring-version': project.version
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
apply plugin: "maven-publish"
|
||||
apply plugin: 'com.jfrog.artifactory'
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
@@ -50,6 +49,16 @@ publishing {
|
||||
}
|
||||
}
|
||||
|
||||
artifactoryPublish {
|
||||
publications(publishing.publications.mavenJava)
|
||||
configureDeploymentRepository(project)
|
||||
|
||||
void configureDeploymentRepository(Project project) {
|
||||
project.plugins.withType(MavenPublishPlugin.class).all {
|
||||
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
|
||||
if (project.hasProperty("deploymentRepository")) {
|
||||
publishing.repositories.maven {
|
||||
it.url = project.property("deploymentRepository")
|
||||
it.name = "deployment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,17 @@
|
||||
apply plugin: 'org.springframework.build.compile'
|
||||
apply plugin: 'org.springframework.build.optional-dependencies'
|
||||
apply plugin: 'me.champeau.gradle.jmh'
|
||||
apply from: "$rootDir/gradle/publications.gradle"
|
||||
|
||||
dependencies {
|
||||
jmh 'org.openjdk.jmh:jmh-core:1.23'
|
||||
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.23'
|
||||
jmh 'net.sf.jopt-simple:jopt-simple:4.6'
|
||||
}
|
||||
jmh {
|
||||
duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest.attributes["Implementation-Title"] = project.name
|
||||
manifest.attributes["Implementation-Version"] = project.version
|
||||
@@ -63,9 +73,5 @@ publishing {
|
||||
}
|
||||
|
||||
// Disable publication of test fixture artifacts.
|
||||
//
|
||||
// Once we upgrade to Gradle 6.x, we will need to delete the following line ...
|
||||
components.java.variants.removeAll { it.outgoingConfiguration.name.startsWith("testFixtures") }
|
||||
// ... and uncomment the following two lines.
|
||||
// components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() }
|
||||
// components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() }
|
||||
components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() }
|
||||
components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() }
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -82,6 +82,7 @@ esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
@@ -129,6 +130,7 @@ fi
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
@@ -154,19 +156,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,14 +177,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
Vendored
+4
@@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@@ -81,6 +84,7 @@ set CMD_LINE_ARGS=%*
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ class AopNamespaceHandlerScopeIntegrationTests {
|
||||
assertThat(singletonScoped.getName()).isEqualTo(rob);
|
||||
singletonScoped.setName(bram);
|
||||
assertThat(singletonScoped.getName()).isEqualTo(bram);
|
||||
ITestBean deserialized = (ITestBean) SerializationTestUtils.serializeAndDeserialize(singletonScoped);
|
||||
ITestBean deserialized = SerializationTestUtils.serializeAndDeserialize(singletonScoped);
|
||||
assertThat(deserialized.getName()).isEqualTo(bram);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
||||
ctx.register(Config.class, JdkProxyTxConfig.class, RepoConfigA.class);
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(ctx::refresh)
|
||||
.satisfies(ex -> assertThat(ex.getRootCause()).isInstanceOf(IllegalStateException.class));
|
||||
.withCauseInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+29
-3
@@ -4,14 +4,18 @@ pluginManagement {
|
||||
maven { url 'https://repo.spring.io/plugins-release' }
|
||||
}
|
||||
}
|
||||
apply from: "$rootDir/gradle/build-cache-settings.gradle"
|
||||
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.2"
|
||||
id "io.spring.gradle-enterprise-conventions" version "0.0.2"
|
||||
}
|
||||
|
||||
include "spring-aop"
|
||||
include "spring-aspects"
|
||||
include "spring-beans"
|
||||
include "spring-context"
|
||||
include "spring-context-support"
|
||||
include "spring-context-indexer"
|
||||
include "spring-context-support"
|
||||
include "spring-core"
|
||||
include "kotlin-coroutines"
|
||||
project(':kotlin-coroutines').projectDir = file('spring-core/kotlin-coroutines')
|
||||
@@ -23,11 +27,12 @@ include "spring-jms"
|
||||
include "spring-messaging"
|
||||
include "spring-orm"
|
||||
include "spring-oxm"
|
||||
include "spring-r2dbc"
|
||||
include "spring-test"
|
||||
include "spring-tx"
|
||||
include "spring-web"
|
||||
include "spring-webmvc"
|
||||
include "spring-webflux"
|
||||
include "spring-webmvc"
|
||||
include "spring-websocket"
|
||||
include "framework-bom"
|
||||
include "integration-tests"
|
||||
@@ -36,3 +41,24 @@ rootProject.name = "spring"
|
||||
rootProject.children.each {project ->
|
||||
project.buildFileName = "${project.name}.gradle"
|
||||
}
|
||||
|
||||
settings.gradle.projectsLoaded {
|
||||
gradleEnterprise {
|
||||
buildScan {
|
||||
if (settings.gradle.rootProject.hasProperty('customJavaHome')) {
|
||||
value("Custom JAVA_HOME", settings.gradle.rootProject.getProperty('customJavaHome'))
|
||||
}
|
||||
if (settings.gradle.rootProject.hasProperty('customJavaSourceVersion')) {
|
||||
value("Custom Java Source Version", settings.gradle.rootProject.getProperty('customJavaSourceVersion'))
|
||||
}
|
||||
File buildDir = settings.gradle.rootProject.getBuildDir()
|
||||
buildDir.mkdirs()
|
||||
new File(buildDir, "build-scan-uri.txt").text = "(build scan not generated)"
|
||||
buildScanPublished { scan ->
|
||||
if (buildDir.exists()) {
|
||||
new File(buildDir, "build-scan-uri.txt").text = "${scan.buildScanUri}\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Intercepts the construction of a new object.
|
||||
*
|
||||
@@ -54,6 +56,7 @@ public interface ConstructorInterceptor extends Interceptor {
|
||||
* @throws Throwable if the interceptors or the target object
|
||||
* throws an exception
|
||||
*/
|
||||
@Nonnull
|
||||
Object construct(ConstructorInvocation invocation) throws Throwable;
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.aopalliance.intercept;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Description of an invocation to a constructor, given to an
|
||||
* interceptor upon constructor-call.
|
||||
@@ -36,6 +38,7 @@ public interface ConstructorInvocation extends Invocation {
|
||||
* {@link Joinpoint#getStaticPart()} method (same result).
|
||||
* @return the constructor being called
|
||||
*/
|
||||
@Nonnull
|
||||
Constructor<?> getConstructor();
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* This interface represents an invocation in the program.
|
||||
*
|
||||
@@ -32,6 +34,7 @@ public interface Invocation extends Joinpoint {
|
||||
* array to change the arguments.
|
||||
* @return the argument of the invocation
|
||||
*/
|
||||
@Nonnull
|
||||
Object[] getArguments();
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.aopalliance.intercept;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This interface represents a generic runtime joinpoint (in the AOP
|
||||
* terminology).
|
||||
@@ -46,6 +49,7 @@ public interface Joinpoint {
|
||||
* @return see the children interfaces' proceed definition
|
||||
* @throws Throwable if the joinpoint throws an exception
|
||||
*/
|
||||
@Nullable
|
||||
Object proceed() throws Throwable;
|
||||
|
||||
/**
|
||||
@@ -53,6 +57,7 @@ public interface Joinpoint {
|
||||
* <p>For instance, the target object for an invocation.
|
||||
* @return the object (can be null if the accessible object is static)
|
||||
*/
|
||||
@Nullable
|
||||
Object getThis();
|
||||
|
||||
/**
|
||||
@@ -60,6 +65,7 @@ public interface Joinpoint {
|
||||
* <p>The static part is an accessible object on which a chain of
|
||||
* interceptors are installed.
|
||||
*/
|
||||
@Nonnull
|
||||
AccessibleObject getStaticPart();
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.aopalliance.intercept;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Intercepts calls on an interface on its way to the target. These
|
||||
* are nested "on top" of the target.
|
||||
@@ -52,6 +55,7 @@ public interface MethodInterceptor extends Interceptor {
|
||||
* @throws Throwable if the interceptors or the target object
|
||||
* throws an exception
|
||||
*/
|
||||
Object invoke(MethodInvocation invocation) throws Throwable;
|
||||
@Nullable
|
||||
Object invoke(@Nonnull MethodInvocation invocation) throws Throwable;
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.aopalliance.intercept;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Description of an invocation to a method, given to an interceptor
|
||||
* upon method-call.
|
||||
@@ -36,6 +38,7 @@ public interface MethodInvocation extends Invocation {
|
||||
* {@link Joinpoint#getStaticPart()} method (same result).
|
||||
* @return the method being called
|
||||
*/
|
||||
@Nonnull
|
||||
Method getMethod();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2020 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,6 +23,7 @@ import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.AfterAdvice;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Spring AOP advice wrapping an AspectJ after advice method.
|
||||
@@ -42,6 +43,7 @@ public class AspectJAfterAdvice extends AbstractAspectJAdvice
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
return mi.proceed();
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2020 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,6 +23,7 @@ import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.AfterAdvice;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Spring AOP advice wrapping an AspectJ after-throwing advice method.
|
||||
@@ -57,6 +58,7 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
return mi.proceed();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -25,6 +25,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.weaver.tools.JoinPointMatch;
|
||||
|
||||
import org.springframework.aop.ProxyMethodInvocation;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Spring AOP around advice (MethodInterceptor) that wraps
|
||||
@@ -60,6 +61,7 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
if (!(mi instanceof ProxyMethodInvocation)) {
|
||||
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -84,11 +84,13 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object proceed() throws Throwable {
|
||||
return this.methodInvocation.invocableClone().proceed();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object proceed(Object[] arguments) throws Throwable {
|
||||
Assert.notNull(arguments, "Argument array passed to proceed cannot be null");
|
||||
if (arguments.length != this.methodInvocation.getArguments().length) {
|
||||
|
||||
+11
-1
@@ -38,6 +38,7 @@ import org.springframework.aop.SpringProxy;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sebastien Deleuze
|
||||
* @since 12.03.2004
|
||||
* @see AdvisedSupport#setOptimize
|
||||
* @see AdvisedSupport#setProxyTargetClass
|
||||
@@ -46,9 +47,18 @@ import org.springframework.aop.SpringProxy;
|
||||
@SuppressWarnings("serial")
|
||||
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
|
||||
/**
|
||||
* Whether this environment lives within a native image.
|
||||
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
|
||||
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
|
||||
*/
|
||||
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
|
||||
|
||||
|
||||
@Override
|
||||
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
|
||||
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
|
||||
if (!IN_NATIVE_IMAGE &&
|
||||
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
|
||||
Class<?> targetClass = config.getTargetClass();
|
||||
if (targetClass == null) {
|
||||
throw new AopConfigException("TargetSource cannot determine target class: " +
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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,6 +23,7 @@ import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.AfterAdvice;
|
||||
import org.springframework.aop.AfterReturningAdvice;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -51,6 +52,7 @@ public class AfterReturningAdviceInterceptor implements MethodInterceptor, After
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
Object retVal = mi.proceed();
|
||||
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
|
||||
|
||||
+2
@@ -23,6 +23,7 @@ import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.BeforeAdvice;
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -51,6 +52,7 @@ public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeA
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
|
||||
return mi.proceed();
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -107,6 +107,7 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
return mi.proceed();
|
||||
|
||||
+1
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -39,7 +39,6 @@ import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
|
||||
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
|
||||
import org.springframework.aop.target.SingletonTargetSource;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
@@ -271,21 +270,6 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
|
||||
return pvs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a proxy with the configured interceptors if the bean is
|
||||
* identified as one to proxy by the subclass.
|
||||
|
||||
+46
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -37,6 +37,7 @@ import org.springframework.util.StringUtils;
|
||||
* "interceptorNames" property.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 10.10.2003
|
||||
* @see #setBeanNames
|
||||
* @see #isMatch
|
||||
@@ -46,6 +47,8 @@ import org.springframework.util.StringUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
|
||||
private static final String[] NO_ALIASES = new String[0];
|
||||
|
||||
@Nullable
|
||||
private List<String> beanNames;
|
||||
|
||||
@@ -72,40 +75,70 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
|
||||
|
||||
/**
|
||||
* Identify as bean to proxy if the bean name is in the configured list of names.
|
||||
* Delegate to {@link AbstractAutoProxyCreator#getCustomTargetSource(Class, String)}
|
||||
* if the bean name matches one of the names in the configured list of supported
|
||||
* names, returning {@code null} otherwise.
|
||||
* @since 5.3
|
||||
* @see #setBeanNames(String...)
|
||||
*/
|
||||
@Override
|
||||
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
|
||||
return (isSupportedBeanName(beanClass, beanName) ?
|
||||
super.getCustomTargetSource(beanClass, beanName) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify as a bean to proxy if the bean name matches one of the names in
|
||||
* the configured list of supported names.
|
||||
* @see #setBeanNames(String...)
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
protected Object[] getAdvicesAndAdvisorsForBean(
|
||||
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
|
||||
|
||||
return (isSupportedBeanName(beanClass, beanName) ?
|
||||
PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS : DO_NOT_PROXY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the bean name for the given bean class matches one of the names
|
||||
* in the configured list of supported names.
|
||||
* @param beanClass the class of the bean to advise
|
||||
* @param beanName the name of the bean
|
||||
* @return {@code true} if the given bean name is supported
|
||||
* @see #setBeanNames(String...)
|
||||
*/
|
||||
private boolean isSupportedBeanName(Class<?> beanClass, String beanName) {
|
||||
if (this.beanNames != null) {
|
||||
boolean isFactoryBean = FactoryBean.class.isAssignableFrom(beanClass);
|
||||
for (String mappedName : this.beanNames) {
|
||||
if (FactoryBean.class.isAssignableFrom(beanClass)) {
|
||||
if (isFactoryBean) {
|
||||
if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
mappedName = mappedName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
|
||||
}
|
||||
if (isMatch(beanName, mappedName)) {
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
return true;
|
||||
}
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
if (beanFactory != null) {
|
||||
String[] aliases = beanFactory.getAliases(beanName);
|
||||
for (String alias : aliases) {
|
||||
if (isMatch(alias, mappedName)) {
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
}
|
||||
}
|
||||
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
String[] aliases = (beanFactory != null ? beanFactory.getAliases(beanName) : NO_ALIASES);
|
||||
for (String alias : aliases) {
|
||||
for (String mappedName : this.beanNames) {
|
||||
if (isMatch(alias, mappedName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return DO_NOT_PROXY;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the given bean name matches the mapped name.
|
||||
* Determine if the given bean name matches the mapped name.
|
||||
* <p>The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
|
||||
* as well as direct equality. Can be overridden in subclasses.
|
||||
* @param beanName the bean name to check
|
||||
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2020 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,30 +23,32 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* TargetSourceCreator that enforces a LazyInitTargetSource for each bean
|
||||
* that is defined as "lazy-init". This will lead to a proxy created for
|
||||
* each of those beans, allowing to fetch a reference to such a bean
|
||||
* without actually initializing the target bean instance.
|
||||
* {@code TargetSourceCreator} that enforces a {@link LazyInitTargetSource} for
|
||||
* each bean that is defined as "lazy-init". This will lead to a proxy created for
|
||||
* each of those beans, allowing to fetch a reference to such a bean without
|
||||
* actually initializing the target bean instance.
|
||||
*
|
||||
* <p>To be registered as custom TargetSourceCreator for an auto-proxy creator,
|
||||
* in combination with custom interceptors for specific beans or for the
|
||||
* creation of lazy-init proxies only. For example, as autodetected
|
||||
* <p>To be registered as custom {@code TargetSourceCreator} for an auto-proxy
|
||||
* creator, in combination with custom interceptors for specific beans or for the
|
||||
* creation of lazy-init proxies only. For example, as an autodetected
|
||||
* infrastructure bean in an XML application context definition:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
|
||||
* <property name="beanNames" value="*" /> <!-- apply to all beans -->
|
||||
* <property name="customTargetSourceCreators">
|
||||
* <list>
|
||||
* <bean class="org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator"/>
|
||||
* <bean class="org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator" />
|
||||
* </list>
|
||||
* </property>
|
||||
* </bean>
|
||||
*
|
||||
* <bean id="myLazyInitBean" class="mypackage.MyBeanClass" lazy-init="true">
|
||||
* ...
|
||||
* <!-- ... -->
|
||||
* </bean></pre>
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 1.2
|
||||
* @see org.springframework.beans.factory.config.BeanDefinition#isLazyInit
|
||||
* @see org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#setCustomTargetSourceCreators
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base {@code MethodInterceptor} implementation for tracing.
|
||||
@@ -151,6 +152,7 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
|
||||
}
|
||||
else {
|
||||
Object target = invocation.getThis();
|
||||
Assert.state(target != null, "Target must not be null");
|
||||
return LogFactory.getLog(getClassForLogging(target));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -21,6 +21,7 @@ import java.io.Serializable;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ConcurrencyThrottleSupport;
|
||||
|
||||
/**
|
||||
@@ -48,6 +49,7 @@ public class ConcurrencyThrottleInterceptor extends ConcurrencyThrottleSupport
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
|
||||
beforeAccess();
|
||||
try {
|
||||
|
||||
+4
-2
@@ -296,6 +296,8 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
@Nullable Object returnValue, @Nullable Throwable throwable, long invocationTime) {
|
||||
|
||||
Matcher matcher = PATTERN.matcher(message);
|
||||
Object target = methodInvocation.getThis();
|
||||
Assert.state(target != null, "Target must not be null");
|
||||
|
||||
StringBuffer output = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
@@ -304,11 +306,11 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(methodInvocation.getMethod().getName()));
|
||||
}
|
||||
else if (PLACEHOLDER_TARGET_CLASS_NAME.equals(match)) {
|
||||
String className = getClassForLogging(methodInvocation.getThis()).getName();
|
||||
String className = getClassForLogging(target).getName();
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(className));
|
||||
}
|
||||
else if (PLACEHOLDER_TARGET_CLASS_SHORT_NAME.equals(match)) {
|
||||
String shortName = ClassUtils.getShortName(getClassForLogging(methodInvocation.getThis()));
|
||||
String shortName = ClassUtils.getShortName(getClassForLogging(target));
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(shortName));
|
||||
}
|
||||
else if (PLACEHOLDER_ARGUMENTS.equals(match)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -18,6 +18,8 @@ package org.springframework.aop.interceptor;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* AOP Alliance {@code MethodInterceptor} that can be introduced in a chain
|
||||
* to display verbose information about intercepted invocations to the logger.
|
||||
@@ -56,6 +58,7 @@ public class DebugInterceptor extends SimpleTraceInterceptor {
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
synchronized (this) {
|
||||
this.count++;
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -25,6 +25,7 @@ import org.springframework.aop.support.DefaultIntroductionAdvisor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
||||
import org.springframework.beans.factory.NamedBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Convenient methods for creating advisors that may be used when autoproxying beans
|
||||
@@ -110,6 +111,7 @@ public abstract class ExposeBeanNameAdvisors {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
if (!(mi instanceof ProxyMethodInvocation)) {
|
||||
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
|
||||
@@ -134,6 +136,7 @@ public abstract class ExposeBeanNameAdvisors {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
if (!(mi instanceof ProxyMethodInvocation)) {
|
||||
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
|
||||
|
||||
+2
@@ -25,6 +25,7 @@ import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
import org.springframework.core.PriorityOrdered;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Interceptor that exposes the current {@link org.aopalliance.intercept.MethodInvocation}
|
||||
@@ -88,6 +89,7 @@ public final class ExposeInvocationInterceptor implements MethodInterceptor, Pri
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
MethodInvocation oldInvocation = invocation.get();
|
||||
invocation.set(mi);
|
||||
|
||||
+6
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 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,6 +19,8 @@ package org.springframework.aop.interceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple AOP Alliance {@code MethodInterceptor} that can be introduced
|
||||
* in a chain to display verbose trace information about intercepted method
|
||||
@@ -73,7 +75,9 @@ public class SimpleTraceInterceptor extends AbstractTraceInterceptor {
|
||||
* @return the description
|
||||
*/
|
||||
protected String getInvocationDescription(MethodInvocation invocation) {
|
||||
String className = invocation.getThis().getClass().getName();
|
||||
Object target = invocation.getThis();
|
||||
Assert.state(target != null, "Target must not be null");
|
||||
String className = target.getClass().getName();
|
||||
return "method '" + invocation.getMethod().getName() + "' of class [" + className + "]";
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -114,12 +114,13 @@ public class DelegatePerTargetObjectIntroductionInterceptor extends Introduction
|
||||
* that it is introduced into. This method is <strong>never</strong> called for
|
||||
* {@link MethodInvocation MethodInvocations} on the introduced interfaces.
|
||||
*/
|
||||
@Nullable
|
||||
protected Object doProceed(MethodInvocation mi) throws Throwable {
|
||||
// If we get here, just pass the invocation on.
|
||||
return mi.proceed();
|
||||
}
|
||||
|
||||
private Object getIntroductionDelegateFor(Object targetObject) {
|
||||
private Object getIntroductionDelegateFor(@Nullable Object targetObject) {
|
||||
synchronized (this.delegateMap) {
|
||||
if (this.delegateMap.containsKey(targetObject)) {
|
||||
return this.delegateMap.get(targetObject);
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -131,6 +131,7 @@ public class DelegatingIntroductionInterceptor extends IntroductionInfoSupport
|
||||
* that it is introduced into. This method is <strong>never</strong> called for
|
||||
* {@link MethodInvocation MethodInvocations} on the introduced interfaces.
|
||||
*/
|
||||
@Nullable
|
||||
protected Object doProceed(MethodInvocation mi) throws Throwable {
|
||||
// If we get here, just pass the invocation on.
|
||||
return mi.proceed();
|
||||
|
||||
+1
-1
@@ -275,7 +275,7 @@ public class AspectJAdviceParameterNameDiscovererTests {
|
||||
|
||||
|
||||
private static String format(String[] names) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
sb.append(names[i]);
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -198,8 +198,8 @@ public class AspectJExpressionPointcutTests {
|
||||
// not currently testable in a reliable fashion
|
||||
//assertDoesNotMatchStringClass(classFilter);
|
||||
|
||||
assertThat(methodMatcher.matches(setSomeNumber, TestBean.class, new Double(12))).as("Should match with setSomeNumber with Double input").isTrue();
|
||||
assertThat(methodMatcher.matches(setSomeNumber, TestBean.class, new Integer(11))).as("Should not match setSomeNumber with Integer input").isFalse();
|
||||
assertThat(methodMatcher.matches(setSomeNumber, TestBean.class, 12D)).as("Should match with setSomeNumber with Double input").isTrue();
|
||||
assertThat(methodMatcher.matches(setSomeNumber, TestBean.class, 11)).as("Should not match setSomeNumber with Integer input").isFalse();
|
||||
assertThat(methodMatcher.matches(getAge, TestBean.class)).as("Should not match getAge").isFalse();
|
||||
assertThat(methodMatcher.isRuntime()).as("Should be a runtime match").isTrue();
|
||||
}
|
||||
@@ -224,10 +224,10 @@ public class AspectJExpressionPointcutTests {
|
||||
TestBean testBean = getAdvisedProxy(expression, interceptor);
|
||||
|
||||
assertThat(interceptor.getCount()).as("Calls should be 0").isEqualTo(0);
|
||||
testBean.setSomeNumber(new Double(30));
|
||||
testBean.setSomeNumber(30D);
|
||||
assertThat(interceptor.getCount()).as("Calls should be 1").isEqualTo(1);
|
||||
|
||||
testBean.setSomeNumber(new Integer(90));
|
||||
testBean.setSomeNumber(90);
|
||||
assertThat(interceptor.getCount()).as("Calls should be 1").isEqualTo(1);
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -91,9 +91,8 @@ public class TrickyAspectJPointcutExpressionTests {
|
||||
// Make sure the interface is loaded from the parent class loader
|
||||
loader.excludeClass(TestService.class.getName());
|
||||
loader.excludeClass(TestException.class.getName());
|
||||
TestService other = (TestService) loader.loadClass(TestServiceImpl.class.getName()).newInstance();
|
||||
TestService other = (TestService) loader.loadClass(TestServiceImpl.class.getName()).getDeclaredConstructor().newInstance();
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, other, "TestServiceImpl");
|
||||
|
||||
}
|
||||
|
||||
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message)
|
||||
@@ -127,7 +126,6 @@ public class TrickyAspectJPointcutExpressionTests {
|
||||
public SimpleThrowawayClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -89,7 +89,7 @@ public class AspectProxyFactoryTests {
|
||||
proxyFactory.addAspect(LoggingAspectOnVarargs.class);
|
||||
ITestBean proxy = proxyFactory.getProxy();
|
||||
assertThat(proxy.doWithVarargs(MyEnum.A, MyOtherEnum.C)).isTrue();
|
||||
ITestBean tb = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
|
||||
ITestBean tb = SerializationTestUtils.serializeAndDeserialize(proxy);
|
||||
assertThat(tb.doWithVarargs(MyEnum.A, MyOtherEnum.C)).isTrue();
|
||||
}
|
||||
|
||||
@@ -108,15 +108,14 @@ public class AspectProxyFactoryTests {
|
||||
ITestBean proxy = proxyFactory.getProxy();
|
||||
assertThat(proxy.getAge()).isEqualTo((target.getAge() * multiple));
|
||||
|
||||
ITestBean serializedProxy = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
|
||||
ITestBean serializedProxy = SerializationTestUtils.serializeAndDeserialize(proxy);
|
||||
assertThat(serializedProxy.getAge()).isEqualTo((target.getAge() * multiple));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithNonSingletonAspectInstance() throws Exception {
|
||||
AspectJProxyFactory pf = new AspectJProxyFactory();
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
pf.addAspect(new PerThisAspect()));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> pf.addAspect(new PerThisAspect()));
|
||||
}
|
||||
|
||||
@Test // SPR-13328
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -54,7 +54,7 @@ public class ConcurrencyThrottleInterceptorTests {
|
||||
ITestBean proxy = (ITestBean) proxyFactory.getProxy();
|
||||
proxy.getAge();
|
||||
|
||||
ITestBean serializedProxy = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
|
||||
ITestBean serializedProxy = SerializationTestUtils.serializeAndDeserialize(proxy);
|
||||
Advised advised = (Advised) serializedProxy;
|
||||
ConcurrencyThrottleInterceptor serializedCti =
|
||||
(ConcurrencyThrottleInterceptor) advised.getAdvisors()[0].getAdvice();
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@ public class CustomizableTraceInterceptorTests {
|
||||
|
||||
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString", new Class[0]));
|
||||
given(methodInvocation.getThis()).willReturn(this);
|
||||
given(methodInvocation.getArguments()).willReturn(new Object[]{"$ One \\$", new Long(2)});
|
||||
given(methodInvocation.getArguments()).willReturn(new Object[]{"$ One \\$", 2L});
|
||||
given(methodInvocation.proceed()).willReturn("Hello!");
|
||||
|
||||
Log log = mock(Log.class);
|
||||
|
||||
+1
-33
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -16,13 +16,11 @@
|
||||
|
||||
package org.springframework.aop.interceptor;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifiedResource;
|
||||
@@ -48,33 +46,3 @@ public class ExposeInvocationInterceptorTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
abstract class ExposedInvocationTestBean extends TestBean {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
MethodInvocation invocation = ExposeInvocationInterceptor.currentInvocation();
|
||||
assertions(invocation);
|
||||
return super.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void absquatulate() {
|
||||
MethodInvocation invocation = ExposeInvocationInterceptor.currentInvocation();
|
||||
assertions(invocation);
|
||||
super.absquatulate();
|
||||
}
|
||||
|
||||
protected abstract void assertions(MethodInvocation invocation);
|
||||
}
|
||||
|
||||
|
||||
class InvocationCheckExposedInvocationTestBean extends ExposedInvocationTestBean {
|
||||
|
||||
@Override
|
||||
protected void assertions(MethodInvocation invocation) {
|
||||
assertThat(invocation.getThis() == this).isTrue();
|
||||
assertThat(ITestBean.class.isAssignableFrom(invocation.getMethod().getDeclaringClass())).as("Invocation should be on ITestBean: " + invocation.getMethod()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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.interceptor;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
abstract class ExposedInvocationTestBean extends TestBean {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
MethodInvocation invocation = ExposeInvocationInterceptor.currentInvocation();
|
||||
assertions(invocation);
|
||||
return super.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void absquatulate() {
|
||||
MethodInvocation invocation = ExposeInvocationInterceptor.currentInvocation();
|
||||
assertions(invocation);
|
||||
super.absquatulate();
|
||||
}
|
||||
|
||||
protected abstract void assertions(MethodInvocation invocation);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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.interceptor;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class InvocationCheckExposedInvocationTestBean extends ExposedInvocationTestBean {
|
||||
|
||||
@Override
|
||||
protected void assertions(MethodInvocation invocation) {
|
||||
assertThat(invocation.getThis() == this).isTrue();
|
||||
assertThat(ITestBean.class.isAssignableFrom(invocation.getMethod().getDeclaringClass())).as("Invocation should be on ITestBean: " + invocation.getMethod()).isTrue();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -49,7 +49,7 @@ public abstract class AbstractRegexpMethodPointcutTests {
|
||||
|
||||
@Test
|
||||
public void testSerializationWithNoPatternSupplied() throws Exception {
|
||||
rpc = (AbstractRegexpMethodPointcut) SerializationTestUtils.serializeAndDeserialize(rpc);
|
||||
rpc = SerializationTestUtils.serializeAndDeserialize(rpc);
|
||||
noPatternSuppliedTests(rpc);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public abstract class AbstractRegexpMethodPointcutTests {
|
||||
public void testExactMatch() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.hashCode");
|
||||
exactMatchTests(rpc);
|
||||
rpc = (AbstractRegexpMethodPointcut) SerializationTestUtils.serializeAndDeserialize(rpc);
|
||||
rpc = SerializationTestUtils.serializeAndDeserialize(rpc);
|
||||
exactMatchTests(rpc);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -239,7 +239,7 @@ public class DelegatingIntroductionInterceptorTests {
|
||||
assertThat(p.getName()).isEqualTo(name);
|
||||
assertThat(((TimeStamped) p).getTimeStamp()).isEqualTo(time);
|
||||
|
||||
Person p1 = (Person) SerializationTestUtils.serializeAndDeserialize(p);
|
||||
Person p1 = SerializationTestUtils.serializeAndDeserialize(p);
|
||||
assertThat(p1.getName()).isEqualTo(name);
|
||||
assertThat(((TimeStamped) p1).getTimeStamp()).isEqualTo(time);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -109,7 +109,7 @@ public class NameMatchMethodPointcutTests {
|
||||
public void testSerializable() throws Throwable {
|
||||
testSets();
|
||||
// Count is now 2
|
||||
Person p2 = (Person) SerializationTestUtils.serializeAndDeserialize(proxied);
|
||||
Person p2 = SerializationTestUtils.serializeAndDeserialize(proxied);
|
||||
NopInterceptor nop2 = (NopInterceptor) ((Advised) p2).getAdvisors()[0].getAdvice();
|
||||
p2.getName();
|
||||
assertThat(nop2.getCount()).isEqualTo(2);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -109,7 +109,7 @@ public class RegexpMethodPointcutAdvisorIntegrationTests {
|
||||
assertThat(nop.getCount()).isEqualTo(2);
|
||||
|
||||
// Serialize and continue...
|
||||
p = (Person) SerializationTestUtils.serializeAndDeserialize(p);
|
||||
p = SerializationTestUtils.serializeAndDeserialize(p);
|
||||
assertThat(p.getAge()).isEqualTo(newAge);
|
||||
// Remembers count, but we need to get a new reference to nop...
|
||||
nop = (SerializableNopInterceptor) ((Advised) p).getAdvisors()[0].getAdvice();
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -134,7 +134,7 @@ public class HotSwappableTargetSourceTests {
|
||||
hts.swap(sp2);
|
||||
assertThat(p.getName()).isEqualTo(sp2.getName());
|
||||
|
||||
p = (Person) SerializationTestUtils.serializeAndDeserialize(p);
|
||||
p = SerializationTestUtils.serializeAndDeserialize(p);
|
||||
// We need to get a reference to the client-side targetsource
|
||||
hts = (HotSwappableTargetSource) ((Advised) p).getTargetSource();
|
||||
assertThat(p.getName()).isEqualTo(sp2.getName());
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -55,7 +55,7 @@ public class PrototypeBasedTargetSourceTests {
|
||||
bf.registerBeanDefinition("person", bd);
|
||||
|
||||
TestTargetSource cpts = (TestTargetSource) bf.getBean("ts");
|
||||
TargetSource serialized = (TargetSource) SerializationTestUtils.serializeAndDeserialize(cpts);
|
||||
TargetSource serialized = SerializationTestUtils.serializeAndDeserialize(cpts);
|
||||
boolean condition = serialized instanceof SingletonTargetSource;
|
||||
assertThat(condition).as("Changed to SingletonTargetSource on deserialization").isTrue();
|
||||
SingletonTargetSource sts = (SingletonTargetSource) serialized;
|
||||
|
||||
Vendored
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.Role;
|
||||
* @see org.springframework.cache.annotation.EnableCaching
|
||||
* @see org.springframework.cache.annotation.CachingConfigurationSelector
|
||||
*/
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
|
||||
|
||||
|
||||
Vendored
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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,6 +19,7 @@ package org.springframework.cache.aspectj;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.cache.config.CacheManagementConfigUtils;
|
||||
import org.springframework.cache.jcache.config.AbstractJCacheConfiguration;
|
||||
import org.springframework.cache.jcache.interceptor.JCacheOperationSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
@@ -33,15 +34,15 @@ import org.springframework.context.annotation.Role;
|
||||
* @see org.springframework.cache.annotation.EnableCaching
|
||||
* @see org.springframework.cache.annotation.CachingConfigurationSelector
|
||||
*/
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJJCacheConfiguration extends AbstractJCacheConfiguration {
|
||||
|
||||
@Bean(name = CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public JCacheCacheAspect cacheAspect() {
|
||||
public JCacheCacheAspect cacheAspect(JCacheOperationSource jCacheOperationSource) {
|
||||
JCacheCacheAspect cacheAspect = JCacheCacheAspect.aspectOf();
|
||||
cacheAspect.setCacheOperationSource(cacheOperationSource());
|
||||
cacheAspect.setCacheOperationSource(jCacheOperationSource);
|
||||
return cacheAspect;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import org.springframework.scheduling.config.TaskManagementConfigUtils;
|
||||
* @see org.springframework.scheduling.annotation.AsyncConfigurationSelector
|
||||
* @see org.springframework.scheduling.annotation.ProxyAsyncConfiguration
|
||||
*/
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJAsyncConfiguration extends AbstractAsyncConfiguration {
|
||||
|
||||
|
||||
Vendored
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -412,15 +412,15 @@ public abstract class AbstractCacheAnnotationTests {
|
||||
}
|
||||
|
||||
protected void testConditionalCacheUpdate(CacheableService<?> service) {
|
||||
Integer one = 1;
|
||||
Integer three = 3;
|
||||
int one = 1;
|
||||
int three = 3;
|
||||
|
||||
Cache cache = this.cm.getCache("testCache");
|
||||
assertThat((int) Integer.valueOf(service.conditionalUpdate(one).toString())).isEqualTo((int) one);
|
||||
assertThat(Integer.parseInt(service.conditionalUpdate(one).toString())).isEqualTo(one);
|
||||
assertThat(cache.get(one)).isNull();
|
||||
|
||||
assertThat((int) Integer.valueOf(service.conditionalUpdate(three).toString())).isEqualTo((int) three);
|
||||
assertThat((int) Integer.valueOf(cache.get(three).get().toString())).isEqualTo((int) three);
|
||||
assertThat(Integer.parseInt(service.conditionalUpdate(three).toString())).isEqualTo(three);
|
||||
assertThat(Integer.parseInt(cache.get(three).get().toString())).isEqualTo(three);
|
||||
}
|
||||
|
||||
protected void testMultiCache(CacheableService<?> service) {
|
||||
|
||||
@@ -29,7 +29,11 @@ compileGroovy {
|
||||
|
||||
// This module also builds Kotlin code and the compileKotlin task naturally depends on
|
||||
// compileJava. We need to redefine dependencies to break task cycles.
|
||||
def deps = compileGroovy.taskDependencies.immutableValues + compileGroovy.taskDependencies.mutableValues
|
||||
compileGroovy.dependsOn = deps - "compileJava"
|
||||
compileKotlin.dependsOn(compileGroovy)
|
||||
compileKotlin.classpath += files(compileGroovy.destinationDir)
|
||||
tasks.named('compileGroovy') {
|
||||
// Groovy only needs the declared dependencies (and not the result of Java compilation)
|
||||
classpath = sourceSets.main.compileClasspath
|
||||
}
|
||||
tasks.named('compileKotlin') {
|
||||
// Kotlin also depends on the result of Groovy compilation
|
||||
classpath += files(sourceSets.main.groovy.classesDirectory)
|
||||
}
|
||||
|
||||
-1
@@ -806,7 +806,6 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
* @param propertyPath property path, which may be nested
|
||||
* @return a property accessor for the target bean
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // avoid nested generic
|
||||
protected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(String propertyPath) {
|
||||
int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
|
||||
// Handle nested properties recursively.
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.KotlinDetector;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -227,7 +228,6 @@ public abstract class BeanUtils {
|
||||
* @since 5.0
|
||||
* @see <a href="https://kotlinlang.org/docs/reference/classes.html#constructors">Kotlin docs</a>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public static <T> Constructor<T> findPrimaryConstructor(Class<T> clazz) {
|
||||
Assert.notNull(clazz, "Class must not be null");
|
||||
@@ -685,6 +685,8 @@ public abstract class BeanUtils {
|
||||
* <p>Note: The source and target classes do not have to match or even be derived
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param editable the class (or interface) to restrict property setting to
|
||||
@@ -715,21 +717,24 @@ public abstract class BeanUtils {
|
||||
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
|
||||
if (sourcePd != null) {
|
||||
Method readMethod = sourcePd.getReadMethod();
|
||||
if (readMethod != null &&
|
||||
ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
|
||||
try {
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
|
||||
readMethod.setAccessible(true);
|
||||
if (readMethod != null) {
|
||||
ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readMethod);
|
||||
ResolvableType targetResolvableType = ResolvableType.forMethodParameter(writeMethod, 0);
|
||||
if (targetResolvableType.isAssignableFrom(sourceResolvableType)) {
|
||||
try {
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
|
||||
readMethod.setAccessible(true);
|
||||
}
|
||||
Object value = readMethod.invoke(source);
|
||||
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
|
||||
writeMethod.setAccessible(true);
|
||||
}
|
||||
writeMethod.invoke(target, value);
|
||||
}
|
||||
Object value = readMethod.invoke(source);
|
||||
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
|
||||
writeMethod.setAccessible(true);
|
||||
catch (Throwable ex) {
|
||||
throw new FatalBeanException(
|
||||
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
|
||||
}
|
||||
writeMethod.invoke(target, value);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new FatalBeanException(
|
||||
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -49,7 +49,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
@Nullable
|
||||
private Set<String> processedProperties;
|
||||
|
||||
private volatile boolean converted = false;
|
||||
private volatile boolean converted;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+14
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -71,6 +71,7 @@ import org.springframework.beans.propertyeditors.URIEditor;
|
||||
import org.springframework.beans.propertyeditors.URLEditor;
|
||||
import org.springframework.beans.propertyeditors.UUIDEditor;
|
||||
import org.springframework.beans.propertyeditors.ZoneIdEditor;
|
||||
import org.springframework.core.SpringProperties;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.ResourceArrayPropertyEditor;
|
||||
@@ -84,6 +85,7 @@ import org.springframework.util.ClassUtils;
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Sebastien Deleuze
|
||||
* @since 1.2.6
|
||||
* @see java.beans.PropertyEditorManager
|
||||
* @see java.beans.PropertyEditorSupport#setAsText
|
||||
@@ -91,6 +93,14 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
|
||||
|
||||
/**
|
||||
* Boolean flag controlled by a {@code spring.xml.ignore} system property that instructs Spring to
|
||||
* ignore XML, i.e. to not initialize the XML-related infrastructure.
|
||||
* <p>The default is "false".
|
||||
*/
|
||||
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");
|
||||
|
||||
|
||||
@Nullable
|
||||
private ConversionService conversionService;
|
||||
|
||||
@@ -208,7 +218,9 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
|
||||
this.defaultEditors.put(Currency.class, new CurrencyEditor());
|
||||
this.defaultEditors.put(File.class, new FileEditor());
|
||||
this.defaultEditors.put(InputStream.class, new InputStreamEditor());
|
||||
this.defaultEditors.put(InputSource.class, new InputSourceEditor());
|
||||
if (!shouldIgnoreXml) {
|
||||
this.defaultEditors.put(InputSource.class, new InputSourceEditor());
|
||||
}
|
||||
this.defaultEditors.put(Locale.class, new LocaleEditor());
|
||||
this.defaultEditors.put(Path.class, new PathEditor());
|
||||
this.defaultEditors.put(Pattern.class, new PatternEditor());
|
||||
|
||||
@@ -87,6 +87,43 @@ public interface ListableBeanFactory extends BeanFactory {
|
||||
*/
|
||||
String[] getBeanDefinitionNames();
|
||||
|
||||
/**
|
||||
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
|
||||
* of instances, including availability and uniqueness options.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass
|
||||
* @param allowEagerInit whether stream-based access may initialize <i>lazy-init
|
||||
* singletons</i> and <i>objects created by FactoryBeans</i> (or by factory methods
|
||||
* with a "factory-bean" reference) for the type check
|
||||
* @return a corresponding provider handle
|
||||
* @since 5.3
|
||||
* @see #getBeanProvider(ResolvableType, boolean)
|
||||
* @see #getBeanProvider(Class)
|
||||
* @see #getBeansOfType(Class, boolean, boolean)
|
||||
* @see #getBeanNamesForType(Class, boolean, boolean)
|
||||
*/
|
||||
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit);
|
||||
|
||||
/**
|
||||
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
|
||||
* of instances, including availability and uniqueness options.
|
||||
* @param requiredType type the bean must match; can be a generic type declaration.
|
||||
* Note that collection types are not supported here, in contrast to reflective
|
||||
* injection points. For programmatically retrieving a list of beans matching a
|
||||
* specific type, specify the actual bean type as an argument here and subsequently
|
||||
* use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options.
|
||||
* @param allowEagerInit whether stream-based access may initialize <i>lazy-init
|
||||
* singletons</i> and <i>objects created by FactoryBeans</i> (or by factory methods
|
||||
* with a "factory-bean" reference) for the type check
|
||||
* @return a corresponding provider handle
|
||||
* @since 5.3
|
||||
* @see #getBeanProvider(ResolvableType)
|
||||
* @see ObjectProvider#iterator()
|
||||
* @see ObjectProvider#stream()
|
||||
* @see ObjectProvider#orderedStream()
|
||||
* @see #getBeanNamesForType(ResolvableType, boolean, boolean)
|
||||
*/
|
||||
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit);
|
||||
|
||||
/**
|
||||
* Return the names of beans matching the given type (including subclasses),
|
||||
* judging from either bean definitions or the value of {@code getObjectType}
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
|
||||
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.LookupOverride;
|
||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
@@ -128,8 +128,8 @@ import org.springframework.util.StringUtils;
|
||||
* @see Autowired
|
||||
* @see Value
|
||||
*/
|
||||
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
|
||||
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
|
||||
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
|
||||
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@@ -613,7 +613,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
private final boolean required;
|
||||
|
||||
private volatile boolean cached = false;
|
||||
private volatile boolean cached;
|
||||
|
||||
@Nullable
|
||||
private volatile Object cachedFieldValue;
|
||||
@@ -678,7 +678,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
private final boolean required;
|
||||
|
||||
private volatile boolean cached = false;
|
||||
private volatile boolean cached;
|
||||
|
||||
@Nullable
|
||||
private volatile Object[] cachedMethodArguments;
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -31,7 +31,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
|
||||
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.core.Conventions;
|
||||
@@ -75,8 +75,8 @@ import org.springframework.util.Assert;
|
||||
* (or a custom {@link org.springframework.beans.factory.InitializingBean} implementation)
|
||||
*/
|
||||
@Deprecated
|
||||
public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
|
||||
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
|
||||
public class RequiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
|
||||
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
|
||||
|
||||
/**
|
||||
* Bean definition attribute that may indicate whether a given bean is supposed
|
||||
|
||||
+16
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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,6 +27,7 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.HierarchicalBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.metrics.ApplicationStartup;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
@@ -276,6 +277,20 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
|
||||
@Nullable
|
||||
Scope getRegisteredScope(String scopeName);
|
||||
|
||||
/**
|
||||
* Set the {@code ApplicationStartup} for this bean factory.
|
||||
* <p>This allows the application context to record metrics during application startup.
|
||||
* @param applicationStartup the new application startup
|
||||
* @since 5.3
|
||||
*/
|
||||
void setApplicationStartup(ApplicationStartup applicationStartup);
|
||||
|
||||
/**
|
||||
* Return the {@code ApplicationStartup} for this bean factory.
|
||||
* @since 5.3
|
||||
*/
|
||||
ApplicationStartup getApplicationStartup();
|
||||
|
||||
/**
|
||||
* Provides a security access control context relevant to this factory.
|
||||
* @return the applicable AccessControlContext (never {@code null})
|
||||
|
||||
+4
-61
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -16,13 +16,6 @@
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Adapter that implements all methods on {@link SmartInstantiationAwareBeanPostProcessor}
|
||||
* as no-ops, which will not change normal processing of each bean instantiated
|
||||
@@ -37,60 +30,10 @@ import org.springframework.lang.Nullable;
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
* @deprecated as of 5.3 in favor of implementing {@link InstantiationAwareBeanPostProcessor}
|
||||
* or {@link SmartInstantiationAwareBeanPostProcessor} directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
|
||||
throws BeansException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
return pvs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+47
-53
@@ -123,8 +123,16 @@ import org.springframework.util.StringUtils;
|
||||
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
|
||||
implements AutowireCapableBeanFactory {
|
||||
|
||||
/**
|
||||
* Whether this environment lives within a native image.
|
||||
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
|
||||
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
|
||||
*/
|
||||
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
|
||||
|
||||
|
||||
/** Strategy for creating bean instances. */
|
||||
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
|
||||
private InstantiationStrategy instantiationStrategy;
|
||||
|
||||
/** Resolver strategy for method parameter names. */
|
||||
@Nullable
|
||||
@@ -176,6 +184,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
ignoreDependencyInterface(BeanNameAware.class);
|
||||
ignoreDependencyInterface(BeanFactoryAware.class);
|
||||
ignoreDependencyInterface(BeanClassLoaderAware.class);
|
||||
if (IN_NATIVE_IMAGE) {
|
||||
this.instantiationStrategy = new SimpleInstantiationStrategy();
|
||||
}
|
||||
else {
|
||||
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,7 +452,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
@Override
|
||||
public void destroyBean(Object existingBean) {
|
||||
new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
|
||||
new DisposableBeanAdapter(
|
||||
existingBean, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -650,14 +665,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
// eventual type after a before-instantiation shortcut.
|
||||
if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
|
||||
boolean matchingOnlyFactoryBean = typesToMatch.length == 1 && typesToMatch[0] == FactoryBean.class;
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
|
||||
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
|
||||
Class<?> predicted = ibp.predictBeanType(targetType, beanName);
|
||||
if (predicted != null &&
|
||||
(!matchingOnlyFactoryBean || FactoryBean.class.isAssignableFrom(predicted))) {
|
||||
return predicted;
|
||||
}
|
||||
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
|
||||
Class<?> predicted = bp.predictBeanType(targetType, beanName);
|
||||
if (predicted != null &&
|
||||
(!matchingOnlyFactoryBean || FactoryBean.class.isAssignableFrom(predicted))) {
|
||||
return predicted;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -958,11 +970,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
|
||||
Object exposedObject = bean;
|
||||
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
|
||||
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
|
||||
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
|
||||
}
|
||||
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
|
||||
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
|
||||
}
|
||||
}
|
||||
return exposedObject;
|
||||
@@ -1087,11 +1096,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
|
||||
*/
|
||||
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof MergedBeanDefinitionPostProcessor) {
|
||||
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
|
||||
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
|
||||
}
|
||||
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
|
||||
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1134,13 +1140,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
*/
|
||||
@Nullable
|
||||
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof InstantiationAwareBeanPostProcessor) {
|
||||
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
|
||||
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
|
||||
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -1279,13 +1282,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
throws BeansException {
|
||||
|
||||
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
|
||||
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
|
||||
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
|
||||
if (ctors != null) {
|
||||
return ctors;
|
||||
}
|
||||
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
|
||||
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
|
||||
if (ctors != null) {
|
||||
return ctors;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1380,12 +1380,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
// state of the bean before properties are set. This can be used, for example,
|
||||
// to support styles of field injection.
|
||||
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof InstantiationAwareBeanPostProcessor) {
|
||||
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
|
||||
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
|
||||
return;
|
||||
}
|
||||
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
|
||||
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1414,21 +1411,18 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (pvs == null) {
|
||||
pvs = mbd.getPropertyValues();
|
||||
}
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof InstantiationAwareBeanPostProcessor) {
|
||||
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
|
||||
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
|
||||
if (pvsToUse == null) {
|
||||
if (filteredPds == null) {
|
||||
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
|
||||
}
|
||||
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
|
||||
if (pvsToUse == null) {
|
||||
return;
|
||||
}
|
||||
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
|
||||
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
|
||||
if (pvsToUse == null) {
|
||||
if (filteredPds == null) {
|
||||
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
|
||||
}
|
||||
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
|
||||
if (pvsToUse == null) {
|
||||
return;
|
||||
}
|
||||
pvs = pvsToUse;
|
||||
}
|
||||
pvs = pvsToUse;
|
||||
}
|
||||
}
|
||||
if (needsDepCheck) {
|
||||
|
||||
+194
-32
@@ -24,6 +24,7 @@ import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -34,6 +35,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
@@ -65,12 +68,15 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.Scope;
|
||||
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.core.AttributeAccessor;
|
||||
import org.springframework.core.DecoratingClassLoader;
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.core.metrics.ApplicationStartup;
|
||||
import org.springframework.core.metrics.StartupStep;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -151,13 +157,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>();
|
||||
|
||||
/** BeanPostProcessors to apply. */
|
||||
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
|
||||
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();
|
||||
|
||||
/** Indicates whether any InstantiationAwareBeanPostProcessors have been registered. */
|
||||
private volatile boolean hasInstantiationAwareBeanPostProcessors;
|
||||
|
||||
/** Indicates whether any DestructionAwareBeanPostProcessors have been registered. */
|
||||
private volatile boolean hasDestructionAwareBeanPostProcessors;
|
||||
/** Cache of pre-filtered post-processors. */
|
||||
@Nullable
|
||||
private volatile BeanPostProcessorCache beanPostProcessorCache;
|
||||
|
||||
/** Map from scope identifier String to corresponding Scope. */
|
||||
private final Map<String, Scope> scopes = new LinkedHashMap<>(8);
|
||||
@@ -176,6 +180,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
|
||||
new NamedThreadLocal<>("Prototype beans currently in creation");
|
||||
|
||||
/** Application startup metrics. **/
|
||||
private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;
|
||||
|
||||
/**
|
||||
* Create a new AbstractBeanFactory.
|
||||
@@ -295,6 +301,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
}
|
||||
|
||||
try {
|
||||
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
|
||||
.tag("beanName", name);
|
||||
if (requiredType != null) {
|
||||
beanCreation.tag("beanType", requiredType::toString);
|
||||
}
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
checkMergedBeanDefinition(mbd, beanName, args);
|
||||
|
||||
@@ -369,12 +380,10 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
throw new BeanCreationException(beanName,
|
||||
"Scope '" + scopeName + "' is not active for the current thread; consider " +
|
||||
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
|
||||
ex);
|
||||
throw new ScopeNotActiveException(beanName, scopeName, ex);
|
||||
}
|
||||
}
|
||||
beanCreation.end();
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
cleanupAfterBeanCreationFailure(beanName);
|
||||
@@ -928,17 +937,21 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
|
||||
// Remove from old position, if any
|
||||
this.beanPostProcessors.remove(beanPostProcessor);
|
||||
// Track whether it is instantiation/destruction aware
|
||||
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
|
||||
this.hasInstantiationAwareBeanPostProcessors = true;
|
||||
}
|
||||
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
|
||||
this.hasDestructionAwareBeanPostProcessors = true;
|
||||
}
|
||||
// Add to end of list
|
||||
this.beanPostProcessors.add(beanPostProcessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new BeanPostProcessors that will get applied to beans created
|
||||
* by this factory. To be invoked during factory configuration.
|
||||
* @since 5.3
|
||||
* @see #addBeanPostProcessor
|
||||
*/
|
||||
public void addBeanPostProcessors(Collection<? extends BeanPostProcessor> beanPostProcessors) {
|
||||
this.beanPostProcessors.removeAll(beanPostProcessors);
|
||||
this.beanPostProcessors.addAll(beanPostProcessors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanPostProcessorCount() {
|
||||
return this.beanPostProcessors.size();
|
||||
@@ -952,6 +965,34 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
return this.beanPostProcessors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the internal cache of pre-filtered post-processors,
|
||||
* freshly (re-)building it if necessary.
|
||||
* @since 5.3
|
||||
*/
|
||||
BeanPostProcessorCache getBeanPostProcessorCache() {
|
||||
BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
|
||||
if (bpCache == null) {
|
||||
bpCache = new BeanPostProcessorCache();
|
||||
for (BeanPostProcessor bp : this.beanPostProcessors) {
|
||||
if (bp instanceof InstantiationAwareBeanPostProcessor) {
|
||||
bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
|
||||
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
|
||||
bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
|
||||
}
|
||||
}
|
||||
if (bp instanceof DestructionAwareBeanPostProcessor) {
|
||||
bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
|
||||
}
|
||||
if (bp instanceof MergedBeanDefinitionPostProcessor) {
|
||||
bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
|
||||
}
|
||||
}
|
||||
this.beanPostProcessorCache = bpCache;
|
||||
}
|
||||
return bpCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this factory holds a InstantiationAwareBeanPostProcessor
|
||||
* that will get applied to singleton beans on creation.
|
||||
@@ -959,7 +1000,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
|
||||
*/
|
||||
protected boolean hasInstantiationAwareBeanPostProcessors() {
|
||||
return this.hasInstantiationAwareBeanPostProcessors;
|
||||
return !getBeanPostProcessorCache().instantiationAware.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -969,7 +1010,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
|
||||
*/
|
||||
protected boolean hasDestructionAwareBeanPostProcessors() {
|
||||
return this.hasDestructionAwareBeanPostProcessors;
|
||||
return !getBeanPostProcessorCache().destructionAware.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1013,6 +1054,17 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
this.securityContextProvider = securityProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationStartup(ApplicationStartup applicationStartup) {
|
||||
Assert.notNull(applicationStartup, "applicationStartup should not be null");
|
||||
this.applicationStartup = applicationStartup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationStartup getApplicationStartup() {
|
||||
return this.applicationStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate the creation of the access control context to the
|
||||
* {@link #setSecurityContextProvider SecurityContextProvider}.
|
||||
@@ -1037,10 +1089,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
this.customEditors.putAll(otherAbstractFactory.customEditors);
|
||||
this.typeConverter = otherAbstractFactory.typeConverter;
|
||||
this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors);
|
||||
this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors ||
|
||||
otherAbstractFactory.hasInstantiationAwareBeanPostProcessors;
|
||||
this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors ||
|
||||
otherAbstractFactory.hasDestructionAwareBeanPostProcessors;
|
||||
this.scopes.putAll(otherAbstractFactory.scopes);
|
||||
this.securityContextProvider = otherAbstractFactory.securityContextProvider;
|
||||
}
|
||||
@@ -1164,7 +1212,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @param mbd the merged bean definition
|
||||
*/
|
||||
protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
|
||||
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
|
||||
new DisposableBeanAdapter(
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1352,7 +1401,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(parentBeanName,
|
||||
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
|
||||
"': cannot be resolved without a ConfigurableBeanFactory parent");
|
||||
"': cannot be resolved without a ConfigurableBeanFactory parent");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1851,9 +1900,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
|
||||
*/
|
||||
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
|
||||
return (bean.getClass() != NullBean.class &&
|
||||
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
|
||||
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
|
||||
return (bean.getClass() != NullBean.class && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) ||
|
||||
(hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(
|
||||
bean, getBeanPostProcessorCache().destructionAware))));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1875,8 +1924,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
// Register a DisposableBean implementation that performs all destruction
|
||||
// work for the given bean: DestructionAwareBeanPostProcessors,
|
||||
// DisposableBean interface, custom destroy method.
|
||||
registerDisposableBean(beanName,
|
||||
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
|
||||
registerDisposableBean(beanName, new DisposableBeanAdapter(
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
|
||||
}
|
||||
else {
|
||||
// A bean with a custom scope...
|
||||
@@ -1884,8 +1933,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
if (scope == null) {
|
||||
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
|
||||
}
|
||||
scope.registerDestructionCallback(beanName,
|
||||
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
|
||||
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1947,4 +1996,117 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
|
||||
throws BeanCreationException;
|
||||
|
||||
|
||||
/**
|
||||
* CopyOnWriteArrayList which resets the beanPostProcessorCache field on modification.
|
||||
*
|
||||
* @since 5.3
|
||||
*/
|
||||
private class BeanPostProcessorCacheAwareList extends CopyOnWriteArrayList<BeanPostProcessor> {
|
||||
|
||||
@Override
|
||||
public BeanPostProcessor set(int index, BeanPostProcessor element) {
|
||||
BeanPostProcessor result = super.set(index, element);
|
||||
beanPostProcessorCache = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(BeanPostProcessor o) {
|
||||
boolean success = super.add(o);
|
||||
beanPostProcessorCache = null;
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, BeanPostProcessor element) {
|
||||
super.add(index, element);
|
||||
beanPostProcessorCache = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanPostProcessor remove(int index) {
|
||||
BeanPostProcessor result = super.remove(index);
|
||||
beanPostProcessorCache = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
boolean success = super.remove(o);
|
||||
if (success) {
|
||||
beanPostProcessorCache = null;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
boolean success = super.removeAll(c);
|
||||
if (success) {
|
||||
beanPostProcessorCache = null;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
boolean success = super.retainAll(c);
|
||||
if (success) {
|
||||
beanPostProcessorCache = null;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends BeanPostProcessor> c) {
|
||||
boolean success = super.addAll(c);
|
||||
if (success) {
|
||||
beanPostProcessorCache = null;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends BeanPostProcessor> c) {
|
||||
boolean success = super.addAll(index, c);
|
||||
if (success) {
|
||||
beanPostProcessorCache = null;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeIf(Predicate<? super BeanPostProcessor> filter) {
|
||||
boolean success = super.removeIf(filter);
|
||||
if (success) {
|
||||
beanPostProcessorCache = null;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(UnaryOperator<BeanPostProcessor> operator) {
|
||||
super.replaceAll(operator);
|
||||
beanPostProcessorCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal cache of pre-filtered post-processors.
|
||||
*
|
||||
* @since 5.3
|
||||
*/
|
||||
static class BeanPostProcessorCache {
|
||||
|
||||
final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>();
|
||||
|
||||
final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>();
|
||||
|
||||
final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>();
|
||||
|
||||
final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -272,23 +272,21 @@ abstract class AutowireUtils {
|
||||
|
||||
private final ObjectFactory<?> objectFactory;
|
||||
|
||||
public ObjectFactoryDelegatingInvocationHandler(ObjectFactory<?> objectFactory) {
|
||||
ObjectFactoryDelegatingInvocationHandler(ObjectFactory<?> objectFactory) {
|
||||
this.objectFactory = objectFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String methodName = method.getName();
|
||||
if (methodName.equals("equals")) {
|
||||
// Only consider equal when proxies are identical.
|
||||
return (proxy == args[0]);
|
||||
}
|
||||
else if (methodName.equals("hashCode")) {
|
||||
// Use hashCode of proxy.
|
||||
return System.identityHashCode(proxy);
|
||||
}
|
||||
else if (methodName.equals("toString")) {
|
||||
return this.objectFactory.toString();
|
||||
switch (method.getName()) {
|
||||
case "equals":
|
||||
// Only consider equal when proxies are identical.
|
||||
return (proxy == args[0]);
|
||||
case "hashCode":
|
||||
// Use hashCode of proxy.
|
||||
return System.identityHashCode(proxy);
|
||||
case "toString":
|
||||
return this.objectFactory.toString();
|
||||
}
|
||||
try {
|
||||
return method.invoke(this.objectFactory.getObject(), args);
|
||||
|
||||
+152
-53
@@ -67,7 +67,6 @@ import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
@@ -78,6 +77,7 @@ import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.core.metrics.StartupStep;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -356,11 +356,49 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) {
|
||||
Assert.notNull(requiredType, "Required type must not be null");
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType));
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
|
||||
return getBeanProvider(requiredType, true);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of ListableBeanFactory interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean containsBeanDefinition(String beanName) {
|
||||
Assert.notNull(beanName, "Bean name must not be null");
|
||||
return this.beanDefinitionMap.containsKey(beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanDefinitionCount() {
|
||||
return this.beanDefinitionMap.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBeanDefinitionNames() {
|
||||
String[] frozenNames = this.frozenBeanDefinitionNames;
|
||||
if (frozenNames != null) {
|
||||
return frozenNames.clone();
|
||||
}
|
||||
else {
|
||||
return StringUtils.toStringArray(this.beanDefinitionNames);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit) {
|
||||
Assert.notNull(requiredType, "Required type must not be null");
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType), allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
return new BeanObjectProvider<T>() {
|
||||
@Override
|
||||
public T getObject() throws BeansException {
|
||||
@@ -381,24 +419,60 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfAvailable() throws BeansException {
|
||||
return resolveBean(requiredType, null, false);
|
||||
try {
|
||||
return resolveBean(requiredType, null, false);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void ifAvailable(Consumer<T> dependencyConsumer) throws BeansException {
|
||||
T dependency = getIfAvailable();
|
||||
if (dependency != null) {
|
||||
try {
|
||||
dependencyConsumer.accept(dependency);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfUnique() throws BeansException {
|
||||
return resolveBean(requiredType, null, true);
|
||||
try {
|
||||
return resolveBean(requiredType, null, true);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void ifUnique(Consumer<T> dependencyConsumer) throws BeansException {
|
||||
T dependency = getIfUnique();
|
||||
if (dependency != null) {
|
||||
try {
|
||||
dependencyConsumer.accept(dependency);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||
}
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
return Arrays.stream(getBeanNamesForTypedStream(requiredType))
|
||||
return Arrays.stream(getBeanNamesForTypedStream(requiredType, allowEagerInit))
|
||||
.map(name -> (T) getBean(name))
|
||||
.filter(bean -> !(bean instanceof NullBean));
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Stream<T> orderedStream() {
|
||||
String[] beanNames = getBeanNamesForTypedStream(requiredType);
|
||||
String[] beanNames = getBeanNamesForTypedStream(requiredType, allowEagerInit);
|
||||
if (beanNames.length == 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
@@ -437,35 +511,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getBeanNamesForTypedStream(ResolvableType requiredType) {
|
||||
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of ListableBeanFactory interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean containsBeanDefinition(String beanName) {
|
||||
Assert.notNull(beanName, "Bean name must not be null");
|
||||
return this.beanDefinitionMap.containsKey(beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanDefinitionCount() {
|
||||
return this.beanDefinitionMap.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBeanDefinitionNames() {
|
||||
String[] frozenNames = this.frozenBeanDefinitionNames;
|
||||
if (frozenNames != null) {
|
||||
return frozenNames.clone();
|
||||
}
|
||||
else {
|
||||
return StringUtils.toStringArray(this.beanDefinitionNames);
|
||||
}
|
||||
private String[] getBeanNamesForTypedStream(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -903,6 +950,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
for (String beanName : beanNames) {
|
||||
Object singletonInstance = getSingleton(beanName);
|
||||
if (singletonInstance instanceof SmartInitializingSingleton) {
|
||||
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
|
||||
.tag("beanName", beanName);
|
||||
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
@@ -913,6 +962,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
else {
|
||||
smartSingleton.afterSingletonsInstantiated();
|
||||
}
|
||||
smartInitialize.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1047,10 +1097,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
destroySingleton(beanName);
|
||||
|
||||
// Notify all post-processors that the specified bean definition has been reset.
|
||||
for (BeanPostProcessor processor : getBeanPostProcessors()) {
|
||||
if (processor instanceof MergedBeanDefinitionPostProcessor) {
|
||||
((MergedBeanDefinitionPostProcessor) processor).resetBeanDefinition(beanName);
|
||||
}
|
||||
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
|
||||
processor.resetBeanDefinition(beanName);
|
||||
}
|
||||
|
||||
// Reset all bean definitions that have the given bean as parent (recursively).
|
||||
@@ -1073,6 +1121,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return isAllowBeanDefinitionOverriding();
|
||||
}
|
||||
|
||||
/**
|
||||
* Also checks for an alias overriding a bean definition of the same name.
|
||||
*/
|
||||
@Override
|
||||
protected void checkForAliasCircle(String name, String alias) {
|
||||
super.checkForAliasCircle(name, alias);
|
||||
if (!isAllowBeanDefinitionOverriding() && containsBeanDefinition(alias)) {
|
||||
throw new IllegalStateException("Cannot register alias '" + alias +
|
||||
"' for name '" + name + "': Alias would override bean definition '" + alias + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
|
||||
super.registerSingleton(beanName, singletonObject);
|
||||
@@ -1934,17 +1994,36 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getIfAvailable() throws BeansException {
|
||||
if (this.optional) {
|
||||
return createOptionalDependency(this.descriptor, this.beanName);
|
||||
try {
|
||||
if (this.optional) {
|
||||
return createOptionalDependency(this.descriptor, this.beanName);
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ifAvailable(Consumer<Object> dependencyConsumer) throws BeansException {
|
||||
Object dependency = getIfAvailable();
|
||||
if (dependency != null) {
|
||||
try {
|
||||
dependencyConsumer.accept(dependency);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1956,17 +2035,37 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object resolveNotUnique(ResolvableType type, Map<String, Object> matchingBeans) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
if (this.optional) {
|
||||
return createOptionalDependency(descriptorToUse, this.beanName);
|
||||
try {
|
||||
if (this.optional) {
|
||||
return createOptionalDependency(descriptorToUse, this.beanName);
|
||||
}
|
||||
else {
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ifUnique(Consumer<Object> dependencyConsumer) throws BeansException {
|
||||
Object dependency = getIfUnique();
|
||||
if (dependency != null) {
|
||||
try {
|
||||
dependencyConsumer.accept(dependency);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -32,7 +32,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -87,7 +86,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
private transient Method destroyMethod;
|
||||
|
||||
@Nullable
|
||||
private List<DestructionAwareBeanPostProcessor> beanPostProcessors;
|
||||
private final List<DestructionAwareBeanPostProcessor> beanPostProcessors;
|
||||
|
||||
|
||||
/**
|
||||
@@ -99,7 +98,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
* (potentially DestructionAwareBeanPostProcessor), if any
|
||||
*/
|
||||
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
|
||||
List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
|
||||
List<DestructionAwareBeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
|
||||
|
||||
Assert.notNull(bean, "Disposable bean must not be null");
|
||||
this.bean = bean;
|
||||
@@ -142,7 +141,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
* @param postProcessors the List of BeanPostProcessors
|
||||
* (potentially DestructionAwareBeanPostProcessor), if any
|
||||
*/
|
||||
public DisposableBeanAdapter(Object bean, List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
|
||||
public DisposableBeanAdapter(
|
||||
Object bean, List<DestructionAwareBeanPostProcessor> postProcessors, AccessControlContext acc) {
|
||||
|
||||
Assert.notNull(bean, "Disposable bean must not be null");
|
||||
this.bean = bean;
|
||||
this.beanName = bean.getClass().getName();
|
||||
@@ -213,16 +214,15 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
* @return the filtered List of DestructionAwareBeanPostProcessors
|
||||
*/
|
||||
@Nullable
|
||||
private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {
|
||||
private List<DestructionAwareBeanPostProcessor> filterPostProcessors(
|
||||
List<DestructionAwareBeanPostProcessor> processors, Object bean) {
|
||||
|
||||
List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
|
||||
if (!CollectionUtils.isEmpty(processors)) {
|
||||
filteredPostProcessors = new ArrayList<>(processors.size());
|
||||
for (BeanPostProcessor processor : processors) {
|
||||
if (processor instanceof DestructionAwareBeanPostProcessor) {
|
||||
DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
|
||||
if (dabpp.requiresDestruction(bean)) {
|
||||
filteredPostProcessors.add(dabpp);
|
||||
}
|
||||
for (DestructionAwareBeanPostProcessor processor : processors) {
|
||||
if (processor.requiresDestruction(bean)) {
|
||||
filteredPostProcessors.add(processor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,14 +397,11 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
* @param bean the bean instance
|
||||
* @param postProcessors the post-processor candidates
|
||||
*/
|
||||
public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
|
||||
public static boolean hasApplicableProcessors(Object bean, List<DestructionAwareBeanPostProcessor> postProcessors) {
|
||||
if (!CollectionUtils.isEmpty(postProcessors)) {
|
||||
for (BeanPostProcessor processor : postProcessors) {
|
||||
if (processor instanceof DestructionAwareBeanPostProcessor) {
|
||||
DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
|
||||
if (dabpp.requiresDestruction(bean)) {
|
||||
return true;
|
||||
}
|
||||
for (DestructionAwareBeanPostProcessor processor : postProcessors) {
|
||||
if (processor.requiresDestruction(bean)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-5
@@ -35,8 +35,8 @@ import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.core.io.support.ResourcePropertiesPersister;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.DefaultPropertiesPersister;
|
||||
import org.springframework.util.PropertiesPersister;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -74,7 +74,10 @@ import org.springframework.util.StringUtils;
|
||||
* @author Rob Harrop
|
||||
* @since 26.11.2003
|
||||
* @see DefaultListableBeanFactory
|
||||
* @deprecated as of 5.3, in favor of Spring's common bean definition formats
|
||||
* and/or custom reader implementations
|
||||
*/
|
||||
@Deprecated
|
||||
public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
|
||||
/**
|
||||
@@ -145,7 +148,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
|
||||
@Nullable
|
||||
private String defaultParentBean;
|
||||
|
||||
private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
|
||||
private PropertiesPersister propertiesPersister = ResourcePropertiesPersister.INSTANCE;
|
||||
|
||||
|
||||
/**
|
||||
@@ -184,12 +187,12 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
|
||||
|
||||
/**
|
||||
* Set the PropertiesPersister to use for parsing properties files.
|
||||
* The default is DefaultPropertiesPersister.
|
||||
* @see org.springframework.util.DefaultPropertiesPersister
|
||||
* The default is ResourcePropertiesPersister.
|
||||
* @see ResourcePropertiesPersister#INSTANCE
|
||||
*/
|
||||
public void setPropertiesPersister(@Nullable PropertiesPersister propertiesPersister) {
|
||||
this.propertiesPersister =
|
||||
(propertiesPersister != null ? propertiesPersister : new DefaultPropertiesPersister());
|
||||
(propertiesPersister != null ? propertiesPersister : ResourcePropertiesPersister.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -65,7 +65,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
|
||||
boolean allowCaching = true;
|
||||
|
||||
boolean isFactoryMethodUnique = false;
|
||||
boolean isFactoryMethodUnique;
|
||||
|
||||
@Nullable
|
||||
volatile ResolvableType targetType;
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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.beans.factory.support;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
|
||||
/**
|
||||
* A subclass of {@link BeanCreationException} which indicates that the target scope
|
||||
* is not active, e.g. in case of request or session scope.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 5.3
|
||||
* @see org.springframework.beans.factory.BeanFactory#getBean
|
||||
* @see org.springframework.beans.factory.config.Scope
|
||||
* @see AbstractBeanDefinition#setScope
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ScopeNotActiveException extends BeanCreationException {
|
||||
|
||||
/**
|
||||
* Create a new ScopeNotActiveException.
|
||||
* @param beanName the name of the bean requested
|
||||
* @param scopeName the name of the target scope
|
||||
* @param cause the root cause, typically from {@link org.springframework.beans.factory.config.Scope#get}
|
||||
*/
|
||||
public ScopeNotActiveException(String beanName, String scopeName, IllegalStateException cause) {
|
||||
super(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " +
|
||||
"defining a scoped proxy for this bean if you intend to refer to it from a singleton", cause);
|
||||
}
|
||||
|
||||
}
|
||||
+73
-63
@@ -186,73 +186,12 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) throws BeansException {
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType));
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType), true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
|
||||
return new ObjectProvider<T>() {
|
||||
@Override
|
||||
public T getObject() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0], requiredType);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public T getObject(Object... args) throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0], args);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfAvailable() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0]);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfUnique() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0]);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
return Arrays.stream(getBeanNamesForType(requiredType)).map(name -> (T) getBean(name));
|
||||
}
|
||||
@Override
|
||||
public Stream<T> orderedStream() {
|
||||
return stream().sorted(OrderComparator.INSTANCE);
|
||||
}
|
||||
};
|
||||
return getBeanProvider(requiredType, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -337,6 +276,77 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
return StringUtils.toStringArray(this.beans.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit) {
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType), allowEagerInit);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
return new ObjectProvider<T>() {
|
||||
@Override
|
||||
public T getObject() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0], requiredType);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public T getObject(Object... args) throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0], args);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfAvailable() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0]);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfUnique() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0]);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
return Arrays.stream(getBeanNamesForType(requiredType)).map(name -> (T) getBean(name));
|
||||
}
|
||||
@Override
|
||||
public Stream<T> orderedStream() {
|
||||
return stream().sorted(OrderComparator.INSTANCE);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBeanNamesForType(@Nullable ResolvableType type) {
|
||||
return getBeanNamesForType(type, true, true);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user