mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
426 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 03e695ad5f | |||
| 29d98285be | |||
| ad708780ed | |||
| 8789b34ef8 | |||
| c9cd53f469 | |||
| c462fe30ed | |||
| 8a0c4caff6 | |||
| 46363c337b | |||
| c1261f2860 | |||
| c4c124b16d | |||
| ee7f60000e | |||
| f1fdc11fab | |||
| 21d61316be | |||
| cb39b07088 | |||
| 50771237cc | |||
| 9fbf5dc945 | |||
| a683e9e81b | |||
| 6e2e45d18f | |||
| 887389d341 | |||
| d9c22e657f | |||
| 8a510db00d | |||
| 9eec6d0834 | |||
| a3e23cd5fc | |||
| af977c0891 | |||
| 1bbcd706be | |||
| 83ac659158 | |||
| a2f02dbfc0 | |||
| 8cbb188455 | |||
| bc973d7001 | |||
| fa3130d716 | |||
| b3e5f86277 | |||
| 340f41af6d | |||
| 25aa295c2c | |||
| 67b91b2390 | |||
| d67034f99b | |||
| dcdea986f6 | |||
| a524857bd5 | |||
| af14eea1ef | |||
| f96872404d | |||
| a7d5fbfbea | |||
| 84de100fc6 | |||
| beab8ab4e7 | |||
| 6f41180cc5 | |||
| 7e2106b850 | |||
| 453c6d41f7 | |||
| 84b4cebb39 | |||
| 5689395678 | |||
| 071c2988d5 | |||
| 94af2ca06b | |||
| ff20a06876 | |||
| 2ffefbb211 | |||
| 4571626839 | |||
| f8a59c267f | |||
| 1166577d2c | |||
| 36dc4e4c5f | |||
| 3ac60147f3 | |||
| e3ceb9b23d | |||
| 5ab966fbde | |||
| 7276752e7c | |||
| 685a195ba1 | |||
| 3188c0f7db | |||
| 3ea540adbc | |||
| ec03e8830e | |||
| 11cb938232 | |||
| f004bb1b64 | |||
| 88f73bffa0 | |||
| 0ab054c7b9 | |||
| 8eb618b480 | |||
| 2f78abd56e | |||
| 3ec612aaf8 | |||
| 4eaee1e738 | |||
| eca755ec88 | |||
| 4201479546 | |||
| b60340b102 | |||
| 2fd39839f8 | |||
| ce87285be5 | |||
| 97582fd0a1 | |||
| d2c7dfb79e | |||
| 7139a877f4 | |||
| 669b05dc1d | |||
| 038b88e2a1 | |||
| eb84c84373 | |||
| 920be8e1b2 | |||
| a13ad3e969 | |||
| 874432b38a | |||
| 4ab03fede8 | |||
| 5bbdd36e19 | |||
| a22feac803 | |||
| bc9cd9a687 | |||
| a71a45e719 | |||
| 132d8c7f45 | |||
| 5d7a632965 | |||
| 6bc7d41734 | |||
| 05d3e820f9 | |||
| f8a5a8d7be | |||
| 82a2544918 | |||
| e702c22da4 | |||
| c4e362500b | |||
| 8d5a6520ce | |||
| 4effca35b5 | |||
| 8f9a1cdc0c | |||
| 136bd2002e | |||
| a749a6bf54 | |||
| 7072aab53b | |||
| dbeae27d3c | |||
| fb312d0ed5 | |||
| 0e670b1c15 | |||
| fadfcf4e43 | |||
| caa13690e8 | |||
| 6647023151 | |||
| e32f94bf8c | |||
| bd6d697395 | |||
| 7f65e17ff2 | |||
| 9095f1d584 | |||
| 4f16d5b5b2 | |||
| 6a6c7df824 | |||
| 5c9fbcc23c | |||
| f4f5cee76c | |||
| bf1cf549b1 | |||
| 1272cd557d | |||
| 993b6d1351 | |||
| 0a92d84778 | |||
| 652c13a6ea | |||
| cb3fa89946 | |||
| d01dca14e9 | |||
| d698446f7c | |||
| 5ef023afd2 | |||
| 316764cad0 | |||
| a681d6af22 | |||
| 7211912057 | |||
| 148eac0200 | |||
| 86be03945b | |||
| 537aced28b | |||
| 5c76ff5ef6 | |||
| d02d5adb54 | |||
| 71f7469578 | |||
| 420c4f3df3 | |||
| 420ff46b2a | |||
| 261bc2ad6a | |||
| c92b9bc7fe | |||
| 4b1b25496b | |||
| 9e8b6feb54 | |||
| 3631d2f36e | |||
| cfefcee788 | |||
| 5fb58e51e5 | |||
| 67c4b4182f | |||
| 6b3052200a | |||
| cf5b86369d | |||
| 7067461d71 | |||
| 34cb5df859 | |||
| 01231fe923 | |||
| 7665424ea8 | |||
| f63a106c85 | |||
| caaf48d4ec | |||
| e52fc2176d | |||
| e8e7fbba94 | |||
| bd1f34e174 | |||
| a490723f02 | |||
| df263d01b9 | |||
| 2a80b64d40 | |||
| e24043ab90 | |||
| 4078b73cec | |||
| dca155e438 | |||
| edabde8a11 | |||
| 8087eb69bf | |||
| e41d865193 | |||
| d68bb4eecd | |||
| 730ad4436f | |||
| 23ab9ca8ca | |||
| 51d263bd06 | |||
| 518dc6df65 | |||
| 59c6b7e445 | |||
| 3e75ec73ab | |||
| 709a41fd43 | |||
| 90072d06fb | |||
| 54bdab4553 | |||
| 75e1811470 | |||
| 18781e58ac | |||
| ed4e2289cd | |||
| ccf95413ed | |||
| fdd6e50721 | |||
| c04fa858fc | |||
| c3ce4f0f90 | |||
| e1200f34e7 | |||
| 999376f9f9 | |||
| c942d789c3 | |||
| 03668f9c10 | |||
| 3e14cdbc69 | |||
| f04e9a8366 | |||
| c1606c5a5e | |||
| 95fac2589f | |||
| 41c8bb4fe1 | |||
| 31a4c274b7 | |||
| d665977787 | |||
| 0b6a54dcc7 | |||
| 1885ab3e07 | |||
| de10bb69cb | |||
| c7642422c3 | |||
| 4c2e0ee5ff | |||
| 79804d92c2 | |||
| f191cf4eb3 | |||
| 0ebb1c5baa | |||
| 4b7d9b1f9c | |||
| ca84559588 | |||
| 1af21bb451 | |||
| ac581bed92 | |||
| 0802581aff | |||
| d7b9270672 | |||
| c44447f622 | |||
| 8b80d38c33 | |||
| b06d267232 | |||
| 8422d9d22f | |||
| c50a5096a0 | |||
| c25c550113 | |||
| 9e09d6cde4 | |||
| 31b8587ce6 | |||
| 00375df4e8 | |||
| b1352e1833 | |||
| b2e94f611f | |||
| ad7cdc5ce9 | |||
| 6cc9538ab9 | |||
| e9083d7d20 | |||
| 98ce171b30 | |||
| 57a5370eec | |||
| 99c7608ffe | |||
| c0f79ee00a | |||
| 9261766677 | |||
| 14f24f43d7 | |||
| d7e0eed8d2 | |||
| 7c834d98c2 | |||
| 70974e006e | |||
| 2f557d9583 | |||
| b84fe99d07 | |||
| 69df27a99f | |||
| 5649a6f8ef | |||
| be6eeafe78 | |||
| b77b45434f | |||
| 6582787678 | |||
| 8b89128c7b | |||
| 2a5713f389 | |||
| 40d2058b97 | |||
| 0d478ca8dd | |||
| 445c0def0c | |||
| ef696c787b | |||
| 27257fb82e | |||
| e209a460ca | |||
| d019c1f82b | |||
| 82d6e07090 | |||
| a1b2695c3a | |||
| 341f4882ed | |||
| 829bed03af | |||
| ce0aed216b | |||
| 0d7c562693 | |||
| 913cc079af | |||
| 3f7dec0b0d | |||
| 830cc3450f | |||
| 6f6d27f50f | |||
| 19a8b94b21 | |||
| 2c53e9e308 | |||
| 2271b6078e | |||
| e8eeb99ac8 | |||
| b67e97d388 | |||
| 656f0591c6 | |||
| 23babe27bb | |||
| bcb9f159ca | |||
| 8ca9187938 | |||
| 1e0bdf95d0 | |||
| 44da9451c4 | |||
| 544f357661 | |||
| ca4f338d75 | |||
| 8e8c88ea5c | |||
| 767299c6dd | |||
| 3290495222 | |||
| b4b3c2ead6 | |||
| dfd5374f02 | |||
| 722ab25f27 | |||
| c37d6c30a0 | |||
| 5fbdd6dcfe | |||
| 29572600dc | |||
| aaf626a537 | |||
| 9197f15a30 | |||
| 15a6373fed | |||
| 2a268701c4 | |||
| 11a0df3fd1 | |||
| b167e1a93f | |||
| 8d735e6e60 | |||
| 9bc09631d6 | |||
| 39be572a7a | |||
| 6ac780d595 | |||
| c6ce65ef56 | |||
| b5743966d6 | |||
| c5de5c9939 | |||
| ff1485fd8d | |||
| 1b4438caac | |||
| 0c7e000250 | |||
| 694db2273f | |||
| 47d3819eab | |||
| f295c8b2fb | |||
| 40d84c297b | |||
| 0416168d0e | |||
| c4c3d59d07 | |||
| 0268e76298 | |||
| 4ec8ae42f4 | |||
| 995aaa6159 | |||
| 2c89ff934d | |||
| c58853f5e5 | |||
| 66826ac960 | |||
| a603779f33 | |||
| e5475d698a | |||
| b728b4640b | |||
| bc657eb4d5 | |||
| 9b967775ed | |||
| 9af11ad5ce | |||
| 7a54ff2d21 | |||
| ec3f857bda | |||
| b3eb1a2ad7 | |||
| bce850aa12 | |||
| 3d6d8a947a | |||
| 6fa6bfe421 | |||
| 05ea991d62 | |||
| a248a52575 | |||
| 2a3c9e403f | |||
| bad87be306 | |||
| 346b755802 | |||
| 4978eeff7f | |||
| 052ed50f48 | |||
| 76c9306dda | |||
| 0853baaa3f | |||
| bf461ba0b2 | |||
| 0705454ce0 | |||
| a178bbe86f | |||
| fcf4315e02 | |||
| 89c7797ffb | |||
| 4dac8339ff | |||
| 0436dd04bf | |||
| 1e3996ea78 | |||
| 50b92118a9 | |||
| b1c7f7d127 | |||
| 0f36569d75 | |||
| 2cbba0923b | |||
| 800922266a | |||
| eda3ca5fbc | |||
| e4934a90eb | |||
| 715f300fa1 | |||
| b53275f2d2 | |||
| 1490d27d75 | |||
| a2c52a97ba | |||
| 5bd90538b3 | |||
| 50ccb1bfcd | |||
| 83eac9af18 | |||
| eb07dea795 | |||
| 114fa47171 | |||
| 63fac1b7c8 | |||
| e8f6cd10a5 | |||
| 47b8e8d528 | |||
| bdfd983bb4 | |||
| 87aaf5049b | |||
| 4b01370f54 | |||
| b6111d04a5 | |||
| 9bd989f1bb | |||
| d5597a75a6 | |||
| 90fdcf88d8 | |||
| 5d3b16cd3a | |||
| 41ae9632d1 | |||
| 47b0da6b25 | |||
| c99210c01f | |||
| 7b9848a352 | |||
| 0e83466023 | |||
| 48a507a993 | |||
| be3bc4c164 | |||
| e68219c1ac | |||
| 151852b164 | |||
| 49427b0c3c | |||
| bf373c5065 | |||
| 678fd8344e | |||
| f632165dec | |||
| fd11789db9 | |||
| d6ec6f0fe9 | |||
| 7311ae19be | |||
| f0aa4f4857 | |||
| f64f07049d | |||
| 24bcb52b2f | |||
| 4f44ae3f28 | |||
| a295a28e4b | |||
| bfa01b35df | |||
| 388c8e4aa5 | |||
| 96e4d3a530 | |||
| 040445612f | |||
| 86b010a6b2 | |||
| 2feedb98cc | |||
| 3be2b32e21 | |||
| 85bdea6f47 | |||
| bfdc99ab79 | |||
| 2567b20949 | |||
| 119c78b1c9 | |||
| d8e18f56e1 | |||
| 211f0bbf88 | |||
| b0c424b376 | |||
| 9ff0d717f2 | |||
| 93f8706dd3 | |||
| e29cfa3501 | |||
| 208fafa4a3 | |||
| 5cbc972a0d | |||
| 58898de542 | |||
| f9d63e7bb1 | |||
| 134c0e2916 | |||
| 1f8c233dfc | |||
| 0dc5d2794f | |||
| 49d003857d | |||
| eabe946a53 | |||
| 09a1b87d37 | |||
| 34abc8f577 | |||
| b0dceb484a | |||
| 65c1eac115 | |||
| a37dde9a1c | |||
| 28496059bc | |||
| 40c51efee8 | |||
| e439d6f64d | |||
| e29867b96e | |||
| 0b552a3534 | |||
| a50537fbaf | |||
| 0d6cc12274 | |||
| 008aa48d5c | |||
| 00eef79e5c | |||
| 7907478d36 | |||
| c7cca2e879 |
@@ -0,0 +1,3 @@
|
||||
# Enable auto-env through the sdkman_auto_env config
|
||||
# Add key=value pairs of SDKs to use below
|
||||
java=8.0.322-librca
|
||||
+1
-1
@@ -8,4 +8,4 @@ wiki page.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please see https://pivotal.io/security.
|
||||
Please see https://spring.io/security-policy.
|
||||
|
||||
+73
-66
@@ -1,17 +1,17 @@
|
||||
plugins {
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false
|
||||
id 'io.spring.nohttp' version '0.0.10'
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false
|
||||
id 'org.jetbrains.dokka' version '1.5.0' apply false
|
||||
id "io.freefair.aspectj" version '6.2.0' apply false
|
||||
id 'org.jetbrains.dokka' version '1.6.10' apply false
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.5.32' apply false
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.32" apply false
|
||||
id 'org.asciidoctor.jvm.convert' version '3.3.2'
|
||||
id 'org.asciidoctor.jvm.pdf' version '3.3.2'
|
||||
id 'de.undercouch.download' version '4.1.2'
|
||||
id "io.freefair.aspectj" version '6.1.0' apply false
|
||||
id "org.unbroken-dome.xjc" version '2.0.0' apply false
|
||||
id "com.github.ben-manes.versions" version '0.39.0'
|
||||
id "com.github.johnrengelman.shadow" version '7.0.0' apply false
|
||||
id 'de.undercouch.download' version '4.1.2'
|
||||
id "me.champeau.jmh" version "0.6.6" apply false
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.30" apply false
|
||||
id "org.unbroken-dome.xjc" version '2.0.0' apply false
|
||||
}
|
||||
|
||||
ext {
|
||||
@@ -27,25 +27,25 @@ configure(allprojects) { project ->
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5"
|
||||
mavenBom "io.netty:netty-bom:4.1.68.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.11"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10"
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
|
||||
mavenBom "io.netty:netty-bom:4.1.75.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.17"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.1"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.30"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
|
||||
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
|
||||
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
|
||||
mavenBom "org.junit:junit-bom:5.8.0"
|
||||
mavenBom "org.junit:junit-bom:5.8.2"
|
||||
}
|
||||
dependencies {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.1') {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.2') {
|
||||
entry 'log4j-api'
|
||||
entry 'log4j-core'
|
||||
entry 'log4j-jul'
|
||||
entry 'log4j-slf4j-impl'
|
||||
}
|
||||
dependency "org.slf4j:slf4j-api:1.7.30"
|
||||
dependency "org.slf4j:slf4j-api:1.7.36"
|
||||
dependency("com.google.code.findbugs:findbugs:3.0.1") {
|
||||
exclude group: "dom4j", name: "dom4j"
|
||||
}
|
||||
@@ -56,7 +56,7 @@ configure(allprojects) { project ->
|
||||
entry 'aspectjtools'
|
||||
entry 'aspectjweaver'
|
||||
}
|
||||
dependencySet(group: 'org.codehaus.groovy', version: '3.0.8') {
|
||||
dependencySet(group: 'org.codehaus.groovy', version: '3.0.9') {
|
||||
entry 'groovy'
|
||||
entry 'groovy-jsr223'
|
||||
entry 'groovy-templates' // requires findbugs for warning-free compilation
|
||||
@@ -67,23 +67,23 @@ configure(allprojects) { project ->
|
||||
dependency "io.reactivex:rxjava:1.3.8"
|
||||
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
|
||||
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.1.1"
|
||||
dependency "io.smallrye.reactive:mutiny:1.0.0"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.1.3"
|
||||
dependency "io.smallrye.reactive:mutiny:1.4.0"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
|
||||
|
||||
dependency "com.caucho:hessian:4.0.63"
|
||||
dependency "com.fasterxml:aalto-xml:1.3.0"
|
||||
dependency("com.fasterxml.woodstox:woodstox-core:6.2.6") {
|
||||
dependency "com.fasterxml:aalto-xml:1.3.1"
|
||||
dependency("com.fasterxml.woodstox:woodstox-core:6.2.8") {
|
||||
exclude group: "stax", name: "stax-api"
|
||||
}
|
||||
dependency "com.google.code.gson:gson:2.8.8"
|
||||
dependency "com.google.protobuf:protobuf-java-util:3.17.3"
|
||||
dependency "com.google.code.gson:gson:2.8.9"
|
||||
dependency "com.google.protobuf:protobuf-java-util:3.19.3"
|
||||
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
|
||||
dependency("com.thoughtworks.xstream:xstream:1.4.18") {
|
||||
exclude group: "xpp3", name: "xpp3_min"
|
||||
exclude group: "xmlpull", name: "xmlpull"
|
||||
}
|
||||
dependency "org.apache.johnzon:johnzon-jsonb:1.2.10"
|
||||
dependency "org.apache.johnzon:johnzon-jsonb:1.2.16"
|
||||
dependency("org.codehaus.jettison:jettison:1.3.8") {
|
||||
exclude group: "stax", name: "stax-api"
|
||||
}
|
||||
@@ -92,14 +92,14 @@ configure(allprojects) { project ->
|
||||
entry 'jibx-run'
|
||||
}
|
||||
dependency "org.ogce:xpp3:1.1.6"
|
||||
dependency "org.yaml:snakeyaml:1.29"
|
||||
dependency "org.yaml:snakeyaml:1.30"
|
||||
|
||||
dependency "com.h2database:h2:1.4.200"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:2.9.1"
|
||||
dependency "com.h2database:h2:2.1.210"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
|
||||
dependency "com.github.librepdf:openpdf:1.3.26"
|
||||
dependency "com.rometools:rome:1.15.0"
|
||||
dependency "com.rometools:rome:1.18.0"
|
||||
dependency "commons-io:commons-io:2.5"
|
||||
dependency "io.vavr:vavr:0.10.3"
|
||||
dependency "io.vavr:vavr:0.10.4"
|
||||
dependency "net.sf.jopt-simple:jopt-simple:5.0.4"
|
||||
dependencySet(group: 'org.apache.activemq', version: '5.16.2') {
|
||||
entry 'activemq-broker'
|
||||
@@ -123,48 +123,48 @@ configure(allprojects) { project ->
|
||||
dependency "net.sf.ehcache:ehcache:2.10.6"
|
||||
dependency "org.ehcache:jcache:1.0.1"
|
||||
dependency "org.ehcache:ehcache:3.4.0"
|
||||
dependency "org.hibernate:hibernate-core:5.4.32.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
|
||||
dependency "org.webjars:webjars-locator-core:0.47"
|
||||
dependency "org.hibernate:hibernate-core:5.4.33.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.2.3.Final"
|
||||
dependency "org.webjars:webjars-locator-core:0.48"
|
||||
dependency "org.webjars:underscorejs:1.8.3"
|
||||
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.52') {
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.60') {
|
||||
entry 'tomcat-util'
|
||||
entry('tomcat-websocket') {
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.52') {
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.60') {
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
dependencySet(group: 'io.undertow', version: '2.2.10.Final') {
|
||||
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
|
||||
entry 'undertow-core'
|
||||
entry('undertow-servlet') {
|
||||
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
|
||||
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.3_spec"
|
||||
}
|
||||
entry('undertow-websockets-jsr') {
|
||||
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
|
||||
}
|
||||
entry('undertow-servlet') {
|
||||
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_3.1_spec"
|
||||
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.2_spec"
|
||||
}
|
||||
}
|
||||
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.10"
|
||||
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1.3'
|
||||
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3'
|
||||
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.apache.httpcomponents:httpasyncclient:4.1.5") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependencySet(group: 'com.squareup.okhttp3', version: '3.14.9') {
|
||||
entry 'okhttp'
|
||||
entry 'mockwebserver'
|
||||
}
|
||||
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.apache.httpcomponents:httpasyncclient:4.1.4") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1'
|
||||
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.1'
|
||||
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.9"
|
||||
|
||||
dependency "org.jruby:jruby:9.2.19.0"
|
||||
dependency "org.jruby:jruby:9.2.20.1"
|
||||
dependency "org.python:jython-standalone:2.7.1"
|
||||
dependency "org.mozilla:rhino:1.7.11"
|
||||
|
||||
@@ -188,27 +188,28 @@ configure(allprojects) { project ->
|
||||
exclude group: "junit", name: "junit"
|
||||
}
|
||||
dependency "org.testng:testng:7.4.0"
|
||||
dependency "org.junit.support:testng-engine:1.0.1"
|
||||
dependency "org.hamcrest:hamcrest:2.1"
|
||||
dependency "org.awaitility:awaitility:3.1.6"
|
||||
dependency "org.assertj:assertj-core:3.20.2"
|
||||
dependencySet(group: 'org.xmlunit', version: '2.8.2') {
|
||||
dependency "org.assertj:assertj-core:3.22.0"
|
||||
dependencySet(group: 'org.xmlunit', version: '2.9.0') {
|
||||
entry 'xmlunit-assertj'
|
||||
entry('xmlunit-matchers') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.mockito', version: '3.12.4') {
|
||||
dependencySet(group: 'org.mockito', version: '4.4.0') {
|
||||
entry('mockito-core') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
entry 'mockito-junit-jupiter'
|
||||
}
|
||||
dependency "io.mockk:mockk:1.12.0"
|
||||
dependency "io.mockk:mockk:1.12.1"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.52.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.59.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.52.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.59.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
@@ -236,8 +237,8 @@ configure(allprojects) { project ->
|
||||
|
||||
dependency "com.ibm.websphere:uow:6.0.2.17"
|
||||
dependency "com.jamonapi:jamon:2.82"
|
||||
dependency "joda-time:joda-time:2.10.10"
|
||||
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.9"
|
||||
dependency "joda-time:joda-time:2.10.13"
|
||||
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.10"
|
||||
dependency "org.javamoney:moneta:1.3"
|
||||
|
||||
dependency "com.sun.activation:javax.activation:1.2.0"
|
||||
@@ -339,7 +340,7 @@ configure([rootProject] + javaProjects) { project ->
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "8.45.1"
|
||||
toolVersion = "9.3"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
@@ -352,16 +353,16 @@ configure([rootProject] + javaProjects) { project ->
|
||||
testImplementation("io.mockk:mockk")
|
||||
testImplementation("org.assertj:assertj-core")
|
||||
// Pull in the latest JUnit 5 Launcher API to ensure proper support in IDEs.
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-suite-engine")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
|
||||
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
|
||||
// JSR-305 only used for non-required meta-annotations
|
||||
compileOnly("com.google.code.findbugs:jsr305")
|
||||
testCompileOnly("com.google.code.findbugs:jsr305")
|
||||
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.15")
|
||||
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.31")
|
||||
}
|
||||
|
||||
ext.javadocLinks = [
|
||||
@@ -369,7 +370,6 @@ configure([rootProject] + javaProjects) { project ->
|
||||
"https://docs.oracle.com/javaee/7/api/",
|
||||
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
|
||||
"https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
|
||||
"https://glassfish.java.net/nonav/docs/v3/api/",
|
||||
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
|
||||
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
|
||||
"https://tiles.apache.org/tiles-request/apidocs/",
|
||||
@@ -383,10 +383,18 @@ configure([rootProject] + javaProjects) { project ->
|
||||
"https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/",
|
||||
"https://projectreactor.io/docs/test/release/api/",
|
||||
"https://junit.org/junit4/javadoc/4.13.2/",
|
||||
"https://junit.org/junit5/docs/5.8.0/api/",
|
||||
// Disabling linking to JUnit 5.8.2, since the `package-list` file no longer exists due to
|
||||
// https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003.
|
||||
// "https://junit.org/junit5/docs/5.8.2/api/",
|
||||
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
|
||||
"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/",
|
||||
"https://r2dbc.io/spec/0.8.5.RELEASE/api/"
|
||||
"https://r2dbc.io/spec/0.8.5.RELEASE/api/",
|
||||
// The external Javadoc link for JSR 305 must come last to ensure that types from
|
||||
// JSR 250 (such as @PostConstruct) are still supported. This is due to the fact
|
||||
// that JSR 250 and JSR 305 both define types in javax.annotation, which results
|
||||
// in a split package, and the javadoc tool does not support split packages
|
||||
// across multiple external Javadoc sites.
|
||||
"https://www.javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/"
|
||||
] as String[]
|
||||
}
|
||||
|
||||
@@ -397,7 +405,6 @@ configure(moduleProjects) { project ->
|
||||
configure(rootProject) {
|
||||
description = "Spring Framework"
|
||||
|
||||
apply plugin: "groovy"
|
||||
apply plugin: "kotlin"
|
||||
apply plugin: "io.spring.nohttp"
|
||||
apply plugin: 'org.springframework.build.api-diff'
|
||||
|
||||
@@ -8,8 +8,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.2.8"
|
||||
implementation "com.google.guava:guava:28.2-jre" // required by japicmp-gradle-plugin
|
||||
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.3.0"
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:focal-20210827
|
||||
FROM ubuntu:focal-20220302
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
@@ -6,6 +6,6 @@ RUN ./setup.sh java8
|
||||
|
||||
ENV JAVA_HOME /opt/openjdk/java8
|
||||
ENV JDK11 /opt/openjdk/java11
|
||||
ENV JDK16 /opt/openjdk/java16
|
||||
ENV JDK17 /opt/openjdk/java17
|
||||
|
||||
ENV PATH $JAVA_HOME/bin:$PATH
|
||||
|
||||
@@ -3,13 +3,16 @@ set -e
|
||||
|
||||
case "$1" in
|
||||
java8)
|
||||
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u302-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u302b08.tar.gz"
|
||||
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u322-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u322b06.tar.gz"
|
||||
;;
|
||||
java11)
|
||||
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.12%2B7/OpenJDK11U-jdk_x64_linux_hotspot_11.0.12_7.tar.gz"
|
||||
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.14.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.14.1_1.tar.gz"
|
||||
;;
|
||||
java16)
|
||||
echo "https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz"
|
||||
java17)
|
||||
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz"
|
||||
;;
|
||||
java18)
|
||||
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk18-2022-02-12-08-06-beta/OpenJDK18-jdk_x64_linux_hotspot_2022-02-12-08-06.tar.gz"
|
||||
;;
|
||||
*)
|
||||
echo $"Unknown java version"
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/
|
||||
|
||||
mkdir -p /opt/openjdk
|
||||
pushd /opt/openjdk > /dev/null
|
||||
for jdk in java8 java11 java16
|
||||
for jdk in java8 java11 java17
|
||||
do
|
||||
JDK_URL=$( /get-jdk-url.sh $jdk )
|
||||
mkdir $jdk
|
||||
|
||||
+1
-4
@@ -1,11 +1,8 @@
|
||||
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: "main"
|
||||
branch: "5.3.x"
|
||||
milestone: "5.3.x"
|
||||
build-name: "spring-framework"
|
||||
pipeline-name: "spring-framework"
|
||||
|
||||
+12
-7
@@ -46,6 +46,11 @@ resource_types:
|
||||
source:
|
||||
repository: springio/artifactory-resource
|
||||
tag: 0.0.17
|
||||
- name: github-release
|
||||
type: registry-image
|
||||
source:
|
||||
repository: concourse/github-release-resource
|
||||
tag: 1.5.5
|
||||
- name: github-status-resource
|
||||
type: registry-image
|
||||
source:
|
||||
@@ -119,14 +124,14 @@ resources:
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk11-build
|
||||
- name: repo-status-jdk16-build
|
||||
- name: repo-status-jdk17-build
|
||||
type: github-status-resource
|
||||
icon: eye-check-outline
|
||||
source:
|
||||
repository: ((github-repo-name))
|
||||
access_token: ((github-ci-status-token))
|
||||
branch: ((branch))
|
||||
context: jdk16-build
|
||||
context: jdk17-build
|
||||
- name: slack-alert
|
||||
type: slack-notification
|
||||
icon: slack
|
||||
@@ -244,7 +249,7 @@ jobs:
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk11-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: jdk16-build
|
||||
- name: jdk17-build
|
||||
serial: true
|
||||
public: true
|
||||
plan:
|
||||
@@ -252,7 +257,7 @@ jobs:
|
||||
- get: git-repo
|
||||
- get: every-morning
|
||||
trigger: true
|
||||
- put: repo-status-jdk16-build
|
||||
- put: repo-status-jdk17-build
|
||||
params: { state: "pending", commit: "git-repo" }
|
||||
- do:
|
||||
- task: check-project
|
||||
@@ -265,12 +270,12 @@ jobs:
|
||||
<<: *build-project-task-params
|
||||
on_failure:
|
||||
do:
|
||||
- put: repo-status-jdk16-build
|
||||
- put: repo-status-jdk17-build
|
||||
params: { state: "failure", commit: "git-repo" }
|
||||
- put: slack-alert
|
||||
params:
|
||||
<<: *slack-fail-params
|
||||
- put: repo-status-jdk16-build
|
||||
- put: repo-status-jdk17-build
|
||||
params: { state: "success", commit: "git-repo" }
|
||||
- name: build-pull-requests
|
||||
serial: true
|
||||
@@ -453,7 +458,7 @@ jobs:
|
||||
|
||||
groups:
|
||||
- name: "builds"
|
||||
jobs: ["build", "jdk11-build", "jdk16-build"]
|
||||
jobs: ["build", "jdk11-build", "jdk17-build"]
|
||||
- name: "releases"
|
||||
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
|
||||
- name: "ci-images"
|
||||
|
||||
@@ -4,7 +4,7 @@ image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: springio/github-changelog-generator
|
||||
tag: '0.0.6'
|
||||
tag: '0.0.7'
|
||||
inputs:
|
||||
- name: git-repo
|
||||
- name: artifactory-repo
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version=5.3.10-SNAPSHOT
|
||||
version=5.3.17
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
tasks.findByName("dokkaHtmlPartial")?.configure {
|
||||
outputDirectory.set(new File(buildDir, "docs/kdoc"))
|
||||
dokkaSourceSets {
|
||||
configureEach {
|
||||
outputDirectory.set(new File(buildDir, "docs/kdoc"))
|
||||
dokkaSourceSets {
|
||||
configureEach {
|
||||
sourceRoots.setFrom(file("src/main/kotlin"))
|
||||
classpath.from(sourceSets["main"].runtimeClasspath)
|
||||
externalDocumentationLink {
|
||||
@@ -17,7 +17,7 @@ tasks.findByName("dokkaHtmlPartial")?.configure {
|
||||
url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/"))
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://hamcrest.org/JavaHamcrest/javadoc/2.1/"))
|
||||
url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/"))
|
||||
}
|
||||
externalDocumentationLink {
|
||||
url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/"))
|
||||
@@ -26,5 +26,5 @@ tasks.findByName("dokkaHtmlPartial")?.configure {
|
||||
url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -46,8 +46,9 @@ task api(type: Javadoc) {
|
||||
stylesheetFile = file("src/docs/api/stylesheet.css")
|
||||
splitIndex = true
|
||||
links(project.ext.javadocLinks)
|
||||
addStringOption('Xdoclint:none', '-quiet')
|
||||
if(JavaVersion.current().isJava9Compatible()) {
|
||||
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
|
||||
addBooleanOption('Xwerror', true) // fail build on Javadoc warnings
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
addBooleanOption('html5', true)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-26
@@ -69,42 +69,20 @@ eclipse.classpath.file.whenMerged {
|
||||
}
|
||||
}
|
||||
|
||||
// Allow projects to be used as WTP modules
|
||||
eclipse.project.natures 'org.eclipse.wst.common.project.facet.core.nature'
|
||||
|
||||
// Include project specific settings
|
||||
task eclipseSettings(type: Copy) {
|
||||
from rootProject.files(
|
||||
'src/eclipse/org.eclipse.jdt.ui.prefs',
|
||||
'src/eclipse/org.eclipse.wst.common.project.facet.core.xml')
|
||||
'src/eclipse/org.eclipse.jdt.core.prefs',
|
||||
'src/eclipse/org.eclipse.jdt.ui.prefs')
|
||||
into project.file('.settings/')
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
task eclipseJdtSettings(type: Copy) {
|
||||
from rootProject.file('src/eclipse/org.eclipse.jdt.core.prefs')
|
||||
into project.file('.settings/')
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
task eclipseBuildship {
|
||||
dependsOn eclipseSettings, eclipseJdtSettings
|
||||
}
|
||||
|
||||
task eclipseWstComponentSettings(type: Copy) {
|
||||
from rootProject.files('src/eclipse/org.eclipse.wst.common.component')
|
||||
into project.file('.settings/')
|
||||
expand(deployname: project.name)
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
task cleanEclipseSettings(type: Delete) {
|
||||
delete project.file('.settings/org.eclipse.jdt.core.prefs')
|
||||
delete project.file('.settings/org.eclipse.jdt.ui.prefs')
|
||||
delete project.file('.settings/org.eclipse.wst.common.component')
|
||||
delete project.file('.settings/org.eclipse.wst.common.project.facet.core.xml')
|
||||
}
|
||||
|
||||
tasks['eclipse'].dependsOn(eclipseSettings, eclipseJdtSettings, eclipseWstComponentSettings)
|
||||
tasks['eclipseJdt'].dependsOn(eclipseJdtSettings)
|
||||
tasks['eclipse'].dependsOn(eclipseSettings)
|
||||
tasks['eclipseJdt'].dependsOn(eclipseSettings)
|
||||
tasks['cleanEclipse'].dependsOn(cleanEclipseSettings)
|
||||
|
||||
+24
-20
@@ -3,11 +3,11 @@
|
||||
This document will guide you through the process of importing the Spring Framework
|
||||
projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you
|
||||
have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java
|
||||
8 support, Eclipse Buildship, the Kotlin plugin, and the Groovy plugin.
|
||||
8 support, Eclipse Buildship, and the Groovy plugin.
|
||||
|
||||
The following instructions have been tested against [STS](https://spring.io/tools) 4.3.2
|
||||
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-432-changelog))
|
||||
(based on Eclipse 4.12) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
|
||||
The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0
|
||||
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog))
|
||||
(based on Eclipse 4.21) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
|
||||
The instructions should work with the latest Eclipse distribution as long as you install
|
||||
[Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note
|
||||
that STS 4 comes with Buildship preinstalled.
|
||||
@@ -16,28 +16,32 @@ that STS 4 comes with Buildship preinstalled.
|
||||
|
||||
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
|
||||
|
||||
1. Ensure that Eclipse launches with JDK 8.
|
||||
- For example, on Mac OS this can be configured in the `Info.plist` file located in the `Contents` folder of the installed Eclipse or STS application (e.g., the `Eclipse.app` file).
|
||||
1. Install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) in Eclipse.
|
||||
1. Install the [Eclipse Groovy Development Tools](https://github.com/groovy/groovy-eclipse/wiki) in Eclipse.
|
||||
1. Switch to Groovy 2.5 (Preferences -> Groovy -> Compiler -> Switch to 2.5...) in Eclipse.
|
||||
1. Change the _Forbidden reference (access rule)_ in Eclipse from Error to Warning
|
||||
(Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule)).
|
||||
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14).
|
||||
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute TestNG tests in the `spring-test` module.
|
||||
1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools).
|
||||
1. Switch to Groovy 3.0 in Eclipse (Preferences → Groovy → Compiler → Switch to 3.0...).
|
||||
- If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project.
|
||||
1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info`
|
||||
(Preferences → Java → Compiler → Errors/Warnings → Deprecated and restricted API → Forbidden reference (access rule)).
|
||||
1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions.
|
||||
- **NOTE**: As of September 21, 2021, it appears that the Kotlin Plugin for Eclipse does not yet work with Eclipse 4.21.
|
||||
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project.
|
||||
- **NOTE**: As of September 21, 2021, it appears that the AspectJ Development Tools do not yet work with Eclipse 4.21.
|
||||
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module.
|
||||
- As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse.
|
||||
1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`.
|
||||
1. To apply project specific settings, run `./gradlew eclipseBuildship` from the command line.
|
||||
1. Import into Eclipse (File -> Import -> Gradle -> Existing Gradle Project -> Navigate to the locally cloned `spring-framework` directory -> Select Finish).
|
||||
1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line.
|
||||
1. Import all projects into Eclipse (File → Import → Gradle → Existing Gradle Project → Navigate to the locally cloned `spring-framework` directory → Select Finish).
|
||||
- If you have not installed AJDT, exclude the `spring-aspects` project from the import, if prompted, or close it after the import.
|
||||
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences -> Gradle -> Java home).
|
||||
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select `Build Path -> Use as Source Folder`).
|
||||
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the small downward facing arrow in the upper right corner of the Package Explorer).
|
||||
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences → Gradle → Java home).
|
||||
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select "Build Path → Use as Source Folder").
|
||||
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the _three vertical dots_ in the upper right corner of the Package Explorer).
|
||||
1. Code away!
|
||||
|
||||
## Known Issues
|
||||
|
||||
1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
|
||||
- See `*RepackJar` tasks in the build.
|
||||
1. `spring-core` should be pre-compiled due to repackaged dependencies.
|
||||
- See `*RepackJar` tasks in the `spring-core.gradle` build file.
|
||||
1. `spring-oxm` should be pre-compiled due to JAXB types generated for tests.
|
||||
- Note that executing `./gradlew :spring-oxm:check` as explained in the _Steps_ above will compile `spring-core` and generate JAXB types for `spring-oxm`.
|
||||
1. `spring-aspects` does not compile due to references to aspect types unknown to Eclipse.
|
||||
- If you installed _AJDT_ into Eclipse it should work.
|
||||
1. While JUnit tests pass from the command line with Gradle, some may fail when run from
|
||||
|
||||
+18
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||
import org.springframework.context.annotation.ScopeMetadata;
|
||||
import org.springframework.context.annotation.ScopeMetadataResolver;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
@@ -307,29 +306,26 @@ class ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests {
|
||||
GenericWebApplicationContext context = new GenericWebApplicationContext();
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
scanner.setIncludeAnnotationConfig(false);
|
||||
scanner.setScopeMetadataResolver(new ScopeMetadataResolver() {
|
||||
@Override
|
||||
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
|
||||
ScopeMetadata metadata = new ScopeMetadata();
|
||||
if (definition instanceof AnnotatedBeanDefinition) {
|
||||
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
|
||||
for (String type : annDef.getMetadata().getAnnotationTypes()) {
|
||||
if (type.equals(javax.inject.Singleton.class.getName())) {
|
||||
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
|
||||
break;
|
||||
}
|
||||
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
|
||||
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
|
||||
metadata.setScopedProxyMode(scopedProxyMode);
|
||||
break;
|
||||
}
|
||||
else if (type.startsWith("javax.inject")) {
|
||||
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
}
|
||||
scanner.setScopeMetadataResolver(definition -> {
|
||||
ScopeMetadata metadata = new ScopeMetadata();
|
||||
if (definition instanceof AnnotatedBeanDefinition) {
|
||||
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
|
||||
for (String type : annDef.getMetadata().getAnnotationTypes()) {
|
||||
if (type.equals(javax.inject.Singleton.class.getName())) {
|
||||
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
|
||||
break;
|
||||
}
|
||||
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
|
||||
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
|
||||
metadata.setScopedProxyMode(scopedProxyMode);
|
||||
break;
|
||||
}
|
||||
else if (type.startsWith("javax.inject")) {
|
||||
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
}
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
return metadata;
|
||||
});
|
||||
|
||||
// Scan twice in order to find errors in the bean definition compatibility check.
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -74,7 +74,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
||||
|
||||
MyRepository repository = ctx.getBean(MyRepository.class);
|
||||
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
|
||||
assertThat(AopUtils.isCglibProxy(repository)).isEqualTo(true);
|
||||
assertThat(AopUtils.isCglibProxy(repository)).isTrue();
|
||||
assertThat(repository.getInvocationCount()).isGreaterThan(0);
|
||||
assertThat(txManager.commits).isGreaterThan(0);
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,13 +1,14 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven { url "https://repo.spring.io/plugins-release" }
|
||||
maven { url "https://repo.spring.io/release" }
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.6.1"
|
||||
id "io.spring.ge.conventions" version "0.0.7"
|
||||
id "com.gradle.enterprise" version "3.8.1"
|
||||
id "io.spring.ge.conventions" version "0.0.9"
|
||||
}
|
||||
|
||||
include "spring-aop"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,6 +44,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @see org.springframework.aop.support.AopUtils
|
||||
*/
|
||||
public abstract class AopProxyUtils {
|
||||
@@ -133,7 +134,7 @@ public abstract class AopProxyUtils {
|
||||
if (targetClass.isInterface()) {
|
||||
advised.setInterfaces(targetClass);
|
||||
}
|
||||
else if (Proxy.isProxyClass(targetClass)) {
|
||||
else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
|
||||
advised.setInterfaces(targetClass.getInterfaces());
|
||||
}
|
||||
specifiedInterfaces = advised.getProxiedInterfaces();
|
||||
@@ -244,4 +245,18 @@ public abstract class AopProxyUtils {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied {@link Class} is a JVM-generated implementation
|
||||
* class for a lambda expression or method reference.
|
||||
* <p>This method makes a best-effort attempt at determining this, based on
|
||||
* checks that work on modern, main stream JVMs.
|
||||
* @param clazz the class to check
|
||||
* @return {@code true} if the class is a lambda implementation class
|
||||
* @since 5.3.16
|
||||
*/
|
||||
static boolean isLambda(Class<?> clazz) {
|
||||
return (clazz.isSynthetic() && (clazz.getSuperclass() == Object.class) &&
|
||||
(clazz.getInterfaces().length > 0) && clazz.getName().contains("$$Lambda"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -237,7 +237,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
* validates it if not.
|
||||
*/
|
||||
private void validateClassIfNecessary(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
if (!this.advised.isOptimize() && logger.isInfoEnabled()) {
|
||||
synchronized (validatedClasses) {
|
||||
if (!validatedClasses.containsKey(proxySuperClass)) {
|
||||
doValidateClass(proxySuperClass, proxyClassLoader,
|
||||
@@ -679,13 +679,19 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Object retVal;
|
||||
// Check whether we only have one InvokerInterceptor: that is,
|
||||
// no real advice, but just reflective invocation of the target.
|
||||
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
|
||||
if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
|
||||
// We can skip creating a MethodInvocation: just invoke the target directly.
|
||||
// Note that the final invoker must be an InvokerInterceptor, so we know
|
||||
// it does nothing but a reflective operation on the target, and no hot
|
||||
// swapping or fancy proxying.
|
||||
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
|
||||
retVal = methodProxy.invoke(target, argsToUse);
|
||||
try {
|
||||
retVal = methodProxy.invoke(target, argsToUse);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
CglibMethodInvocation.logFastClassGenerationFailure(method);
|
||||
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We need to create a method invocation...
|
||||
@@ -737,10 +743,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
||||
|
||||
// Only use method proxy for public methods not derived from java.lang.Object
|
||||
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
|
||||
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
|
||||
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
|
||||
methodProxy : null);
|
||||
this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -776,10 +779,25 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
@Override
|
||||
protected Object invokeJoinpoint() throws Throwable {
|
||||
if (this.methodProxy != null) {
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
try {
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
logFastClassGenerationFailure(this.method);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return super.invokeJoinpoint();
|
||||
return super.invokeJoinpoint();
|
||||
}
|
||||
|
||||
static boolean isMethodProxyCompatible(Method method) {
|
||||
return (Modifier.isPublic(method.getModifiers()) &&
|
||||
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
|
||||
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method));
|
||||
}
|
||||
|
||||
static void logFastClassGenerationFailure(Method method) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to generate CGLIB fast class for method: " + method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,14 +40,16 @@ import org.springframework.core.NativeDetector;
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sebastien Deleuze
|
||||
* @author Sam Brannen
|
||||
* @since 12.03.2004
|
||||
* @see AdvisedSupport#setOptimize
|
||||
* @see AdvisedSupport#setProxyTargetClass
|
||||
* @see AdvisedSupport#setInterfaces
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7930414337282325166L;
|
||||
|
||||
|
||||
@Override
|
||||
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
|
||||
@@ -58,7 +60,7 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
|
||||
throw new AopConfigException("TargetSource cannot determine target class: " +
|
||||
"Either an interface or a target is required for proxy creation.");
|
||||
}
|
||||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
|
||||
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
|
||||
return new JdkDynamicAopProxy(config);
|
||||
}
|
||||
return new ObjenesisCglibAopProxy(config);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -73,11 +73,9 @@ public class ProxyConfig implements Serializable {
|
||||
* The exact meaning of "aggressive optimizations" will differ
|
||||
* between proxies, but there is usually some tradeoff.
|
||||
* Default is "false".
|
||||
* <p>For example, optimization will usually mean that advice changes won't
|
||||
* take effect after a proxy has been created. For this reason, optimization
|
||||
* is disabled by default. An optimize value of "true" may be ignored
|
||||
* if other settings preclude optimization: for example, if "exposeProxy"
|
||||
* is set to "true" and that's not compatible with the optimization.
|
||||
* <p>With Spring's current proxy options, this flag effectively
|
||||
* enforces CGLIB proxies (similar to {@link #setProxyTargetClass})
|
||||
* but without any class validation checks (for final methods etc).
|
||||
*/
|
||||
public void setOptimize(boolean optimize) {
|
||||
this.optimize = optimize;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -421,11 +421,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* are unaffected by such changes.
|
||||
*/
|
||||
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
|
||||
if (this.advisorChainInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
|
||||
if (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {
|
||||
if (this.beanFactory == null) {
|
||||
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
|
||||
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
|
||||
@@ -464,9 +460,9 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
addAdvisorOnChainCreation(advice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.advisorChainInitialized = true;
|
||||
this.advisorChainInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2021 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,8 +25,8 @@ import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.ThrowsAdvice;
|
||||
|
||||
/**
|
||||
* Adapter to enable {@link org.springframework.aop.MethodBeforeAdvice}
|
||||
* to be used in the Spring AOP framework.
|
||||
* Adapter to enable {@link org.springframework.aop.ThrowsAdvice} to be used
|
||||
* in the Spring AOP framework.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
* FactoryBean will get proxied. This default behavior applies as of Spring 2.0.
|
||||
* If you intend to proxy a FactoryBean instance itself (a rare use case, but
|
||||
* Spring 1.2's default behavior), specify the bean name of the FactoryBean
|
||||
* including the factory-bean prefix "&": e.g. "&myFactoryBean".
|
||||
* including the factory-bean prefix "&": e.g. "&myFactoryBean".
|
||||
* @see org.springframework.beans.factory.FactoryBean
|
||||
* @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
|
||||
*/
|
||||
|
||||
+5
-3
@@ -25,9 +25,11 @@ import org.springframework.lang.Nullable;
|
||||
/**
|
||||
* Convenient TargetSourceCreator using bean name prefixes to create one of three
|
||||
* well-known TargetSource types:
|
||||
* <li>: CommonsPool2TargetSource
|
||||
* <li>% ThreadLocalTargetSource
|
||||
* <li>! PrototypeTargetSource
|
||||
* <ul>
|
||||
* <li>: CommonsPool2TargetSource</li>
|
||||
* <li>% ThreadLocalTargetSource</li>
|
||||
* <li>! PrototypeTargetSource</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Stephane Nicoll
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -233,7 +233,8 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
return beanFactory.getBean(TaskExecutor.class);
|
||||
}
|
||||
catch (NoUniqueBeanDefinitionException ex) {
|
||||
logger.debug("Could not find unique TaskExecutor bean", ex);
|
||||
logger.debug("Could not find unique TaskExecutor bean. " +
|
||||
"Continuing search for an Executor bean named 'taskExecutor'", ex);
|
||||
try {
|
||||
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
|
||||
}
|
||||
@@ -246,7 +247,8 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
logger.debug("Could not find default TaskExecutor bean", ex);
|
||||
logger.debug("Could not find default TaskExecutor bean. " +
|
||||
"Continuing search for an Executor bean named 'taskExecutor'", ex);
|
||||
try {
|
||||
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -146,7 +146,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + methodName;
|
||||
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + this.methodName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -98,7 +98,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void perTargetAspect() throws SecurityException, NoSuchMethodException {
|
||||
void perTargetAspect() throws Exception {
|
||||
TestBean target = new TestBean();
|
||||
int realAge = 65;
|
||||
target.setAge(realAge);
|
||||
@@ -130,7 +130,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void multiplePerTargetAspects() throws SecurityException, NoSuchMethodException {
|
||||
void multiplePerTargetAspects() throws Exception {
|
||||
TestBean target = new TestBean();
|
||||
int realAge = 65;
|
||||
target.setAge(realAge);
|
||||
@@ -158,7 +158,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void multiplePerTargetAspectsWithOrderAnnotation() throws SecurityException, NoSuchMethodException {
|
||||
void multiplePerTargetAspectsWithOrderAnnotation() throws Exception {
|
||||
TestBean target = new TestBean();
|
||||
int realAge = 65;
|
||||
target.setAge(realAge);
|
||||
@@ -184,7 +184,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void perThisAspect() throws SecurityException, NoSuchMethodException {
|
||||
void perThisAspect() throws Exception {
|
||||
TestBean target = new TestBean();
|
||||
int realAge = 65;
|
||||
target.setAge(realAge);
|
||||
@@ -220,7 +220,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void perTypeWithinAspect() throws SecurityException, NoSuchMethodException {
|
||||
void perTypeWithinAspect() throws Exception {
|
||||
TestBean target = new TestBean();
|
||||
int realAge = 65;
|
||||
target.setAge(realAge);
|
||||
@@ -322,7 +322,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
int b = 12;
|
||||
int c = 25;
|
||||
String d = "d";
|
||||
StringBuffer e = new StringBuffer("stringbuf");
|
||||
StringBuilder e = new StringBuilder("stringbuf");
|
||||
String expectedResult = a + b+ c + d + e;
|
||||
assertThat(mva.mungeArgs(a, b, c, d, e)).isEqualTo(expectedResult);
|
||||
}
|
||||
@@ -728,12 +728,12 @@ abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
@Aspect
|
||||
static class ManyValuedArgs {
|
||||
|
||||
String mungeArgs(String a, int b, int c, String d, StringBuffer e) {
|
||||
String mungeArgs(String a, int b, int c, String d, StringBuilder e) {
|
||||
return a + b + c + d + e;
|
||||
}
|
||||
|
||||
@Around(value="execution(String mungeArgs(..)) && args(a, b, c, d, e)", argNames="b,c,d,e,a")
|
||||
String reverseAdvice(ProceedingJoinPoint pjp, int b, int c, String d, StringBuffer e, String a) throws Throwable {
|
||||
String reverseAdvice(ProceedingJoinPoint pjp, int b, int c, String d, StringBuilder e, String a) throws Throwable {
|
||||
assertThat(pjp.proceed()).isEqualTo(a + b+ c+ d+ e);
|
||||
return a + b + c + d + e;
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* @since 2.0
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
@@ -56,7 +55,7 @@ class AspectMetadataTests {
|
||||
assertThat(am.getAjType().getPerClause().getKind()).isEqualTo(PerClauseKind.PERTARGET);
|
||||
assertThat(am.getPerClausePointcut()).isInstanceOf(AspectJExpressionPointcut.class);
|
||||
assertThat(((AspectJExpressionPointcut) am.getPerClausePointcut()).getExpression())
|
||||
.isEqualTo("execution(* *.getSpouse())");
|
||||
.isEqualTo("execution(* *.getSpouse())");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -67,7 +66,7 @@ class AspectMetadataTests {
|
||||
assertThat(am.getAjType().getPerClause().getKind()).isEqualTo(PerClauseKind.PERTHIS);
|
||||
assertThat(am.getPerClausePointcut()).isInstanceOf(AspectJExpressionPointcut.class);
|
||||
assertThat(((AspectJExpressionPointcut) am.getPerClausePointcut()).getExpression())
|
||||
.isEqualTo("execution(* *.getSpouse())");
|
||||
.isEqualTo("execution(* *.getSpouse())");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+37
-47
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.aop.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -40,7 +41,7 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AopNamespaceHandlerEventTests {
|
||||
class AopNamespaceHandlerEventTests {
|
||||
|
||||
private static final Class<?> CLASS = AopNamespaceHandlerEventTests.class;
|
||||
|
||||
@@ -57,25 +58,24 @@ public class AopNamespaceHandlerEventTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.reader = new XmlBeanDefinitionReader(this.beanFactory);
|
||||
this.reader.setEventListener(this.eventListener);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPointcutEvents() {
|
||||
void pointcutEvents() {
|
||||
this.reader.loadBeanDefinitions(POINTCUT_EVENTS_CONTEXT);
|
||||
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
|
||||
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(1);
|
||||
boolean condition = componentDefinitions[0] instanceof CompositeComponentDefinition;
|
||||
assertThat(condition).as("No holder with nested components").isTrue();
|
||||
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(1);
|
||||
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
|
||||
|
||||
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
|
||||
assertThat(compositeDef.getName()).isEqualTo("aop:config");
|
||||
|
||||
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
|
||||
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
|
||||
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
|
||||
PointcutComponentDefinition pcd = null;
|
||||
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
|
||||
if (componentDefinition instanceof PointcutComponentDefinition) {
|
||||
@@ -84,84 +84,77 @@ public class AopNamespaceHandlerEventTests {
|
||||
}
|
||||
}
|
||||
assertThat(pcd).as("PointcutComponentDefinition not found").isNotNull();
|
||||
assertThat(pcd.getBeanDefinitions().length).as("Incorrect number of BeanDefinitions").isEqualTo(1);
|
||||
assertThat(pcd.getBeanDefinitions()).as("Incorrect number of BeanDefinitions").hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdvisorEventsWithPointcutRef() {
|
||||
void advisorEventsWithPointcutRef() {
|
||||
this.reader.loadBeanDefinitions(POINTCUT_REF_CONTEXT);
|
||||
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
|
||||
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(2);
|
||||
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
|
||||
|
||||
boolean condition1 = componentDefinitions[0] instanceof CompositeComponentDefinition;
|
||||
assertThat(condition1).as("No holder with nested components").isTrue();
|
||||
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
|
||||
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
|
||||
assertThat(compositeDef.getName()).isEqualTo("aop:config");
|
||||
|
||||
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
|
||||
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(3);
|
||||
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(3);
|
||||
AdvisorComponentDefinition acd = null;
|
||||
for (int i = 0; i < nestedComponentDefs.length; i++) {
|
||||
ComponentDefinition componentDefinition = nestedComponentDefs[i];
|
||||
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
|
||||
if (componentDefinition instanceof AdvisorComponentDefinition) {
|
||||
acd = (AdvisorComponentDefinition) componentDefinition;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertThat(acd).as("AdvisorComponentDefinition not found").isNotNull();
|
||||
assertThat(acd.getBeanDefinitions().length).isEqualTo(1);
|
||||
assertThat(acd.getBeanReferences().length).isEqualTo(2);
|
||||
assertThat(acd.getBeanDefinitions()).hasSize(1);
|
||||
assertThat(acd.getBeanReferences()).hasSize(2);
|
||||
|
||||
boolean condition = componentDefinitions[1] instanceof BeanComponentDefinition;
|
||||
assertThat(condition).as("No advice bean found").isTrue();
|
||||
assertThat(componentDefinitions[1]).as("No advice bean found").isInstanceOf(BeanComponentDefinition.class);
|
||||
BeanComponentDefinition adviceDef = (BeanComponentDefinition) componentDefinitions[1];
|
||||
assertThat(adviceDef.getBeanName()).isEqualTo("countingAdvice");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdvisorEventsWithDirectPointcut() {
|
||||
void advisorEventsWithDirectPointcut() {
|
||||
this.reader.loadBeanDefinitions(DIRECT_POINTCUT_EVENTS_CONTEXT);
|
||||
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
|
||||
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(2);
|
||||
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
|
||||
|
||||
boolean condition1 = componentDefinitions[0] instanceof CompositeComponentDefinition;
|
||||
assertThat(condition1).as("No holder with nested components").isTrue();
|
||||
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
|
||||
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
|
||||
assertThat(compositeDef.getName()).isEqualTo("aop:config");
|
||||
|
||||
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
|
||||
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
|
||||
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
|
||||
AdvisorComponentDefinition acd = null;
|
||||
for (int i = 0; i < nestedComponentDefs.length; i++) {
|
||||
ComponentDefinition componentDefinition = nestedComponentDefs[i];
|
||||
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
|
||||
if (componentDefinition instanceof AdvisorComponentDefinition) {
|
||||
acd = (AdvisorComponentDefinition) componentDefinition;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertThat(acd).as("AdvisorComponentDefinition not found").isNotNull();
|
||||
assertThat(acd.getBeanDefinitions().length).isEqualTo(2);
|
||||
assertThat(acd.getBeanReferences().length).isEqualTo(1);
|
||||
assertThat(acd.getBeanDefinitions()).hasSize(2);
|
||||
assertThat(acd.getBeanReferences()).hasSize(1);
|
||||
|
||||
boolean condition = componentDefinitions[1] instanceof BeanComponentDefinition;
|
||||
assertThat(condition).as("No advice bean found").isTrue();
|
||||
assertThat(componentDefinitions[1]).as("No advice bean found").isInstanceOf(BeanComponentDefinition.class);
|
||||
BeanComponentDefinition adviceDef = (BeanComponentDefinition) componentDefinitions[1];
|
||||
assertThat(adviceDef.getBeanName()).isEqualTo("countingAdvice");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAspectEvent() {
|
||||
void aspectEvent() {
|
||||
this.reader.loadBeanDefinitions(CONTEXT);
|
||||
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
|
||||
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(5);
|
||||
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
|
||||
|
||||
boolean condition = componentDefinitions[0] instanceof CompositeComponentDefinition;
|
||||
assertThat(condition).as("No holder with nested components").isTrue();
|
||||
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
|
||||
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
|
||||
assertThat(compositeDef.getName()).isEqualTo("aop:config");
|
||||
|
||||
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
|
||||
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
|
||||
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
|
||||
AspectComponentDefinition acd = null;
|
||||
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
|
||||
if (componentDefinition instanceof AspectComponentDefinition) {
|
||||
@@ -172,9 +165,9 @@ public class AopNamespaceHandlerEventTests {
|
||||
|
||||
assertThat(acd).as("AspectComponentDefinition not found").isNotNull();
|
||||
BeanDefinition[] beanDefinitions = acd.getBeanDefinitions();
|
||||
assertThat(beanDefinitions.length).isEqualTo(5);
|
||||
assertThat(beanDefinitions).hasSize(5);
|
||||
BeanReference[] beanReferences = acd.getBeanReferences();
|
||||
assertThat(beanReferences.length).isEqualTo(6);
|
||||
assertThat(beanReferences).hasSize(6);
|
||||
|
||||
Set<String> expectedReferences = new HashSet<>();
|
||||
expectedReferences.add("pc");
|
||||
@@ -182,19 +175,16 @@ public class AopNamespaceHandlerEventTests {
|
||||
for (BeanReference beanReference : beanReferences) {
|
||||
expectedReferences.remove(beanReference.getBeanName());
|
||||
}
|
||||
assertThat(expectedReferences.size()).as("Incorrect references found").isEqualTo(0);
|
||||
assertThat(expectedReferences).as("Incorrect references found").isEmpty();
|
||||
|
||||
for (int i = 1; i < componentDefinitions.length; i++) {
|
||||
boolean condition1 = componentDefinitions[i] instanceof BeanComponentDefinition;
|
||||
assertThat(condition1).isTrue();
|
||||
}
|
||||
Arrays.stream(componentDefinitions).skip(1).forEach(definition ->
|
||||
assertThat(definition).isInstanceOf(BeanComponentDefinition.class));
|
||||
|
||||
ComponentDefinition[] nestedComponentDefs2 = acd.getNestedComponents();
|
||||
assertThat(nestedComponentDefs2.length).as("Inner PointcutComponentDefinition not found").isEqualTo(1);
|
||||
boolean condition1 = nestedComponentDefs2[0] instanceof PointcutComponentDefinition;
|
||||
assertThat(condition1).isTrue();
|
||||
assertThat(nestedComponentDefs2).as("Inner PointcutComponentDefinition not found").hasSize(1);
|
||||
assertThat(nestedComponentDefs2[0]).isInstanceOf(PointcutComponentDefinition.class);
|
||||
PointcutComponentDefinition pcd = (PointcutComponentDefinition) nestedComponentDefs2[0];
|
||||
assertThat(pcd.getBeanDefinitions().length).as("Incorrect number of BeanDefinitions").isEqualTo(1);
|
||||
assertThat(pcd.getBeanDefinitions()).as("Incorrect number of BeanDefinitions").hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,10 +30,10 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
|
||||
* @author Mark Fisher
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AopNamespaceHandlerPointcutErrorTests {
|
||||
class AopNamespaceHandlerPointcutErrorTests {
|
||||
|
||||
@Test
|
||||
public void testDuplicatePointcutConfig() {
|
||||
void duplicatePointcutConfig() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() ->
|
||||
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
|
||||
@@ -42,7 +42,7 @@ public class AopNamespaceHandlerPointcutErrorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingPointcutConfig() {
|
||||
void missingPointcutConfig() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() ->
|
||||
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,10 +30,10 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class TopLevelAopTagTests {
|
||||
class TopLevelAopTagTests {
|
||||
|
||||
@Test
|
||||
public void testParse() {
|
||||
void parse() {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(
|
||||
qualifiedResource(TopLevelAopTagTests.class, "context.xml"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.framework;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -32,6 +33,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class AopProxyUtilsTests {
|
||||
|
||||
@@ -132,4 +134,61 @@ public class AopProxyUtilsTests {
|
||||
AopProxyUtils.proxiedUserInterfaces(proxy));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLambda() {
|
||||
assertIsLambda(AopProxyUtilsTests.staticLambdaExpression);
|
||||
assertIsLambda(AopProxyUtilsTests::staticStringFactory);
|
||||
|
||||
assertIsLambda(this.instanceLambdaExpression);
|
||||
assertIsLambda(this::instanceStringFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLambda() {
|
||||
assertIsNotLambda(new EnigmaSupplier());
|
||||
|
||||
assertIsNotLambda(new Supplier<String>() {
|
||||
@Override
|
||||
public String get() {
|
||||
return "anonymous inner class";
|
||||
}
|
||||
});
|
||||
|
||||
assertIsNotLambda(new Fake$$LambdaSupplier());
|
||||
}
|
||||
|
||||
private static void assertIsLambda(Supplier<String> supplier) {
|
||||
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isTrue();
|
||||
}
|
||||
|
||||
private static void assertIsNotLambda(Supplier<String> supplier) {
|
||||
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isFalse();
|
||||
}
|
||||
|
||||
private static final Supplier<String> staticLambdaExpression = () -> "static lambda expression";
|
||||
|
||||
private final Supplier<String> instanceLambdaExpression = () -> "instance lambda expressions";
|
||||
|
||||
private static String staticStringFactory() {
|
||||
return "static string factory";
|
||||
}
|
||||
|
||||
private String instanceStringFactory() {
|
||||
return "instance string factory";
|
||||
}
|
||||
|
||||
private static class EnigmaSupplier implements Supplier<String> {
|
||||
@Override
|
||||
public String get() {
|
||||
return "enigma";
|
||||
}
|
||||
}
|
||||
|
||||
private static class Fake$$LambdaSupplier implements Supplier<String> {
|
||||
@Override
|
||||
public String get() {
|
||||
return "fake lambda";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-10
@@ -125,16 +125,7 @@ public class ConcurrencyThrottleInterceptorTests {
|
||||
try {
|
||||
this.proxy.exceptional(this.ex);
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
if (ex == this.ex) {
|
||||
logger.debug("Expected exception thrown", ex);
|
||||
}
|
||||
else {
|
||||
// should never happen
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
catch (Error err) {
|
||||
catch (RuntimeException | Error err) {
|
||||
if (err == this.ex) {
|
||||
logger.debug("Expected exception thrown", err);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.support;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -29,10 +30,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Rob Harrop
|
||||
* @author Rick Evans
|
||||
*/
|
||||
public class ClassUtilsTests {
|
||||
class ClassUtilsTests {
|
||||
|
||||
@Test
|
||||
public void getShortNameForCglibClass() {
|
||||
void getShortNameForCglibClass() {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pf = new ProxyFactory();
|
||||
pf.setTarget(tb);
|
||||
@@ -41,4 +42,5 @@ public class ClassUtilsTests {
|
||||
String className = ClassUtils.getShortName(proxy.getClass());
|
||||
assertThat(className).as("Class name did not match").isEqualTo("TestBean");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-6
@@ -16,12 +16,6 @@
|
||||
</aop:aspect>
|
||||
</aop:config>
|
||||
|
||||
<bean id="getNameCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
|
||||
|
||||
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
|
||||
|
||||
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
|
||||
|
||||
</beans>
|
||||
|
||||
+1
-1
@@ -9,6 +9,6 @@
|
||||
<aop:advisor advice-ref="countingAdvice" pointcut="within(org.springframework..*)"/>
|
||||
</aop:config>
|
||||
|
||||
<bean id="countingAdvice" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
|
||||
<bean id="countingAdvice" class="org.springframework.aop.testfixture.advice.CountingBeforeAdvice"/>
|
||||
|
||||
</beans>
|
||||
|
||||
+1
-1
@@ -10,6 +10,6 @@
|
||||
<aop:advisor advice-ref="countingAdvice" pointcut-ref="pc"/>
|
||||
</aop:config>
|
||||
|
||||
<bean id="countingAdvice" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
|
||||
<bean id="countingAdvice" class="org.springframework.aop.testfixture.advice.CountingBeforeAdvice"/>
|
||||
|
||||
</beans>
|
||||
|
||||
-4
@@ -12,10 +12,6 @@
|
||||
</aop:aspect>
|
||||
</aop:config>
|
||||
|
||||
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
|
||||
|
||||
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
|
||||
|
||||
</beans>
|
||||
|
||||
-4
@@ -12,10 +12,6 @@
|
||||
</aop:aspect>
|
||||
</aop:config>
|
||||
|
||||
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
|
||||
|
||||
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
|
||||
|
||||
</beans>
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.aop.testfixture.advice;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Abstract superclass for counting advices etc.
|
||||
@@ -31,7 +32,7 @@ import java.util.HashMap;
|
||||
public class MethodCounter implements Serializable {
|
||||
|
||||
/** Method name --> count, does not understand overloading */
|
||||
private HashMap<String, Integer> map = new HashMap<>();
|
||||
private Map<String, Integer> map = new HashMap<>();
|
||||
|
||||
private int allCount;
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -13,14 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.aspectj;
|
||||
|
||||
/**
|
||||
* Marker interface for domain object that need DI through aspects.
|
||||
* Marker interface for domain objects that need DI through aspects.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.5
|
||||
*/
|
||||
public interface ConfigurableObject {
|
||||
|
||||
}
|
||||
|
||||
+2
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,6 @@ import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
@@ -107,10 +106,7 @@ public class AspectJEnableCachingIsolatedTests {
|
||||
try {
|
||||
load(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
Throwable root = ex.getRootCause();
|
||||
boolean condition = root instanceof IllegalStateException;
|
||||
assertThat(condition).isTrue();
|
||||
catch (IllegalStateException ex) {
|
||||
assertThat(ex.getMessage().contains("implementations of CachingConfigurer")).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
+8
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,13 +22,18 @@ import org.springframework.contextsupport.testfixture.jcache.AbstractJCacheAnnot
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class JCacheAspectJNamespaceConfigTests extends AbstractJCacheAnnotationTests {
|
||||
|
||||
@Override
|
||||
protected ApplicationContext getApplicationContext() {
|
||||
return new GenericXmlApplicationContext(
|
||||
"/org/springframework/cache/config/annotation-jcache-aspectj.xml");
|
||||
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
|
||||
// Disallow bean definition overriding to test https://github.com/spring-projects/spring-framework/pull/27499
|
||||
context.setAllowBeanDefinitionOverriding(false);
|
||||
context.load("/org/springframework/cache/config/annotation-jcache-aspectj.xml");
|
||||
context.refresh();
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -29,4 +30,5 @@ public class ClassWithPrivateAnnotatedMember {
|
||||
|
||||
@Transactional
|
||||
private void doInTransaction() {}
|
||||
|
||||
}
|
||||
|
||||
+2
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -29,4 +30,5 @@ public class ClassWithProtectedAnnotatedMember {
|
||||
|
||||
@Transactional
|
||||
protected void doInTransaction() {}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -100,9 +100,9 @@ public abstract class BeanUtils {
|
||||
* @param clazz class to instantiate
|
||||
* @return the new instance
|
||||
* @throws BeanInstantiationException if the bean cannot be instantiated
|
||||
* @see Class#newInstance()
|
||||
* @deprecated as of Spring 5.0, following the deprecation of
|
||||
* {@link Class#newInstance()} in JDK 9
|
||||
* @see Class#newInstance()
|
||||
*/
|
||||
@Deprecated
|
||||
public static <T> T instantiate(Class<T> clazz) throws BeanInstantiationException {
|
||||
@@ -226,32 +226,45 @@ public abstract class BeanUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resolvable constructor for the provided class, either a primary constructor
|
||||
* or single public constructor or simply a default constructor. Callers have to be
|
||||
* prepared to resolve arguments for the returned constructor's parameters, if any.
|
||||
* Return a resolvable constructor for the provided class, either a primary or single
|
||||
* public constructor with arguments, or a single non-public constructor with arguments,
|
||||
* or simply a default constructor. Callers have to be prepared to resolve arguments
|
||||
* for the returned constructor's parameters, if any.
|
||||
* @param clazz the class to check
|
||||
* @throws IllegalStateException in case of no unique constructor found at all
|
||||
* @since 5.3
|
||||
* @see #findPrimaryConstructor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Constructor<T> getResolvableConstructor(Class<T> clazz) {
|
||||
Constructor<T> ctor = findPrimaryConstructor(clazz);
|
||||
if (ctor == null) {
|
||||
Constructor<?>[] ctors = clazz.getConstructors();
|
||||
if (ctor != null) {
|
||||
return ctor;
|
||||
}
|
||||
|
||||
Constructor<?>[] ctors = clazz.getConstructors();
|
||||
if (ctors.length == 1) {
|
||||
// A single public constructor
|
||||
return (Constructor<T>) ctors[0];
|
||||
}
|
||||
else if (ctors.length == 0){
|
||||
ctors = clazz.getDeclaredConstructors();
|
||||
if (ctors.length == 1) {
|
||||
ctor = (Constructor<T>) ctors[0];
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ctor = clazz.getDeclaredConstructor();
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException("No primary or single public constructor found for " +
|
||||
clazz + " - and no default constructor found either");
|
||||
}
|
||||
// A single non-public constructor, e.g. from a non-public record type
|
||||
return (Constructor<T>) ctors[0];
|
||||
}
|
||||
}
|
||||
return ctor;
|
||||
|
||||
// Several constructors -> let's try to take the default constructor
|
||||
try {
|
||||
return clazz.getDeclaredConstructor();
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
// Giving up...
|
||||
}
|
||||
|
||||
// No unique constructor at all
|
||||
throw new IllegalStateException("No primary or single unique constructor found for " + clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -527,7 +540,7 @@ public abstract class BeanUtils {
|
||||
|
||||
/**
|
||||
* Find a JavaBeans PropertyEditor following the 'Editor' suffix convention
|
||||
* (e.g. "mypackage.MyDomainClass" -> "mypackage.MyDomainClassEditor").
|
||||
* (e.g. "mypackage.MyDomainClass" → "mypackage.MyDomainClassEditor").
|
||||
* <p>Compatible to the standard JavaBeans convention as implemented by
|
||||
* {@link java.beans.PropertyEditorManager} but isolated from the latter's
|
||||
* registered default editors for primitive types.
|
||||
@@ -678,7 +691,25 @@ public abstract class BeanUtils {
|
||||
* 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>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full BeanWrapper.
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects.
|
||||
* <p>The following table provides a non-exhaustive set of examples of source
|
||||
* and target property types that can be copied as well as source and target
|
||||
* property types that cannot be copied.
|
||||
* <table border="1">
|
||||
* <tr><th>source property type</th><th>target property type</th><th>copy supported</th></tr>
|
||||
* <tr><td>{@code Integer}</td><td>{@code Integer}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code Integer}</td><td>{@code Number}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Integer>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<?>}</td><td>{@code List<?>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<?>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<? extends Number>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code String}</td><td>{@code Integer}</td><td>no</td></tr>
|
||||
* <tr><td>{@code Number}</td><td>{@code Integer}</td><td>no</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Long>}</td><td>no</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Number>}</td><td>no</td></tr>
|
||||
* </table>
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @throws BeansException if the copying failed
|
||||
@@ -695,7 +726,10 @@ public abstract class BeanUtils {
|
||||
* 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>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full BeanWrapper.
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param editable the class (or interface) to restrict property setting to
|
||||
@@ -713,7 +747,10 @@ public abstract class BeanUtils {
|
||||
* 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>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full BeanWrapper.
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param ignoreProperties array of property names to ignore
|
||||
@@ -730,7 +767,8 @@ public abstract class BeanUtils {
|
||||
* 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.
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param editable the class (or interface) to restrict property setting to
|
||||
|
||||
@@ -134,8 +134,8 @@ public abstract class PropertyAccessorUtils {
|
||||
/**
|
||||
* Determine the canonical name for the given property path.
|
||||
* Removes surrounding quotes from map keys:<br>
|
||||
* {@code map['key']} -> {@code map[key]}<br>
|
||||
* {@code map["key"]} -> {@code map[key]}
|
||||
* {@code map['key']} → {@code map[key]}<br>
|
||||
* {@code map["key"]} → {@code map[key]}
|
||||
* @param propertyName the bean property path
|
||||
* @return the canonical representation of the property path
|
||||
*/
|
||||
|
||||
+7
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -422,10 +422,13 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
|
||||
}
|
||||
if (editor == null) {
|
||||
// Find editor for superclass or interface.
|
||||
for (Iterator<Class<?>> it = this.customEditors.keySet().iterator(); it.hasNext() && editor == null;) {
|
||||
Class<?> key = it.next();
|
||||
for (Map.Entry<Class<?>, PropertyEditor> entry : this.customEditors.entrySet()) {
|
||||
if (editor != null) {
|
||||
break;
|
||||
}
|
||||
Class<?> key = entry.getKey();
|
||||
if (key.isAssignableFrom(requiredType)) {
|
||||
editor = this.customEditors.get(key);
|
||||
editor = entry.getValue();
|
||||
// Cache editor for search type, to avoid the overhead
|
||||
// of repeated assignable-from checks.
|
||||
if (this.customEditorCache == null) {
|
||||
|
||||
@@ -214,6 +214,7 @@ public interface BeanFactory {
|
||||
/**
|
||||
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
|
||||
* of instances, including availability and uniqueness options.
|
||||
* <p>For matching a generic type, consider {@link #getBeanProvider(ResolvableType)}.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass
|
||||
* @return a corresponding provider handle
|
||||
* @since 5.1
|
||||
@@ -223,13 +224,20 @@ public interface BeanFactory {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* of instances, including availability and uniqueness options. This variant allows
|
||||
* for specifying a generic type to match, similar to reflective injection points
|
||||
* with generic type declarations in method/constructor parameters.
|
||||
* <p>Note that collections of beans 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.
|
||||
* <p>Also, generics matching is strict here, as per the Java assignment rules.
|
||||
* For lenient fallback matching with unchecked semantics (similar to the ´unchecked´
|
||||
* Java compiler warning), consider calling {@link #getBeanProvider(Class)} with the
|
||||
* raw type as a second step if no full generic match is
|
||||
* {@link ObjectProvider#getIfAvailable() available} with this variant.
|
||||
* @return a corresponding provider handle
|
||||
* @param requiredType type the bean must match; can be a generic type declaration
|
||||
* @since 5.1
|
||||
* @see ObjectProvider#iterator()
|
||||
* @see ObjectProvider#stream()
|
||||
|
||||
+23
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -353,9 +353,31 @@ public interface ListableBeanFactory extends BeanFactory {
|
||||
* @since 3.0
|
||||
* @see #getBeanNamesForAnnotation
|
||||
* @see #getBeansWithAnnotation
|
||||
* @see #getType(String)
|
||||
*/
|
||||
@Nullable
|
||||
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
|
||||
throws NoSuchBeanDefinitionException;
|
||||
|
||||
/**
|
||||
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
|
||||
* traversing its interfaces and super classes if no annotation can be found on
|
||||
* the given class itself, as well as checking the bean's factory method (if any).
|
||||
* @param beanName the name of the bean to look for annotations on
|
||||
* @param annotationType the type of annotation to look for
|
||||
* (at class, interface or factory method level of the specified bean)
|
||||
* @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized
|
||||
* just for the purpose of determining its object type
|
||||
* @return the annotation of the given type if found, or {@code null} otherwise
|
||||
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
|
||||
* @since 5.3.14
|
||||
* @see #getBeanNamesForAnnotation
|
||||
* @see #getBeansWithAnnotation
|
||||
* @see #getType(String, boolean)
|
||||
*/
|
||||
@Nullable
|
||||
<A extends Annotation> A findAnnotationOnBean(
|
||||
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
|
||||
throws NoSuchBeanDefinitionException;
|
||||
|
||||
}
|
||||
|
||||
+4
-5
@@ -459,7 +459,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
|
||||
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
|
||||
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
|
||||
return InjectionMetadata.EMPTY;
|
||||
}
|
||||
@@ -537,11 +537,10 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||
* @param ann the Autowired annotation
|
||||
* @return whether the annotation indicates that a dependency is required
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "cast"})
|
||||
@SuppressWarnings("deprecation")
|
||||
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
|
||||
// The following (AnnotationAttributes) cast is required on JDK 9+.
|
||||
return determineRequiredStatus((AnnotationAttributes)
|
||||
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
|
||||
return determineRequiredStatus(ann.<AnnotationAttributes> asMap(
|
||||
mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -302,7 +302,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
||||
checkedInitMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
||||
checkedDestroyMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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,9 +34,7 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* <p><b>NOTE:</b> This interface is a special purpose interface, mainly for
|
||||
* internal use within the framework. It is recommended to implement the plain
|
||||
* {@link BeanPostProcessor} interface as far as possible, or to derive from
|
||||
* {@link InstantiationAwareBeanPostProcessorAdapter} in order to be shielded
|
||||
* from extensions to this interface.
|
||||
* {@link BeanPostProcessor} interface as far as possible.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
|
||||
+7
-7
@@ -47,17 +47,17 @@ import org.springframework.util.ClassUtils;
|
||||
* which uses this class to call a static initialization method:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
* <property name="staticMethod" value="com.whatever.MyClass.init"/>
|
||||
* </bean></pre>
|
||||
* <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
* <property name="staticMethod" value="com.whatever.MyClass.init"/>
|
||||
* </bean></pre>
|
||||
*
|
||||
* <p>An example of calling an instance method to start some server bean:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
* <property name="targetObject" ref="myServer"/>
|
||||
* <property name="targetMethod" value="start"/>
|
||||
* </bean></pre>
|
||||
* <bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
* <property name="targetObject" ref="myServer"/>
|
||||
* <property name="targetMethod" value="start"/>
|
||||
* </bean></pre>
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0.3
|
||||
|
||||
+12
-12
@@ -56,24 +56,24 @@ import org.springframework.lang.Nullable;
|
||||
* which uses this class to call a static factory method:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/>
|
||||
* </bean></pre>
|
||||
* <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/>
|
||||
* </bean></pre>
|
||||
*
|
||||
* <p>An example of calling a static method then an instance method to get at a
|
||||
* Java system property. Somewhat verbose, but it works.
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="targetClass" value="java.lang.System"/>
|
||||
* <property name="targetMethod" value="getProperties"/>
|
||||
* </bean>
|
||||
* <bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="targetClass" value="java.lang.System"/>
|
||||
* <property name="targetMethod" value="getProperties"/>
|
||||
* </bean>
|
||||
*
|
||||
* <bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="targetObject" ref="sysProps"/>
|
||||
* <property name="targetMethod" value="getProperty"/>
|
||||
* <property name="arguments" value="java.version"/>
|
||||
* </bean></pre>
|
||||
* <bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
* <property name="targetObject" ref="sysProps"/>
|
||||
* <property name="targetMethod" value="getProperty"/>
|
||||
* <property name="arguments" value="java.version"/>
|
||||
* </bean></pre>
|
||||
*
|
||||
* @author Colin Sampaleanu
|
||||
* @author Juergen Hoeller
|
||||
|
||||
+22
-22
@@ -83,22 +83,22 @@ import org.springframework.util.StringUtils;
|
||||
* <p>A sample config in an XML-based
|
||||
* {@link org.springframework.beans.factory.BeanFactory} might look as follows:
|
||||
*
|
||||
* <pre class="code"><beans>
|
||||
* <pre class="code"><beans>
|
||||
*
|
||||
* <!-- Prototype bean since we have state -->
|
||||
* <bean id="myService" class="a.b.c.MyService" singleton="false"/>
|
||||
* <!-- Prototype bean since we have state -->
|
||||
* <bean id="myService" class="a.b.c.MyService" singleton="false"/>
|
||||
*
|
||||
* <!-- will lookup the above 'myService' bean by *TYPE* -->
|
||||
* <!-- will lookup the above 'myService' bean by *TYPE* -->
|
||||
* <bean id="myServiceFactory"
|
||||
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
|
||||
* <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
|
||||
* </bean>
|
||||
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
|
||||
* <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
|
||||
* </bean>
|
||||
*
|
||||
* <bean id="clientBean" class="a.b.c.MyClientBean">
|
||||
* <property name="myServiceFactory" ref="myServiceFactory"/>
|
||||
* </bean>
|
||||
* <bean id="clientBean" class="a.b.c.MyClientBean">
|
||||
* <property name="myServiceFactory" ref="myServiceFactory"/>
|
||||
* </bean>
|
||||
*
|
||||
*</beans></pre>
|
||||
*</beans></pre>
|
||||
*
|
||||
* <p>The attendant {@code MyClientBean} class implementation might then
|
||||
* look something like this:
|
||||
@@ -135,22 +135,22 @@ import org.springframework.util.StringUtils;
|
||||
* <p>A sample config in an XML-based
|
||||
* {@link org.springframework.beans.factory.BeanFactory} might look as follows:
|
||||
*
|
||||
* <pre class="code"><beans>
|
||||
* <pre class="code"><beans>
|
||||
*
|
||||
* <!-- Prototype beans since we have state (both extend MyService) -->
|
||||
* <bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
|
||||
* <bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>
|
||||
* <!-- Prototype beans since we have state (both extend MyService) -->
|
||||
* <bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
|
||||
* <bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>
|
||||
*
|
||||
* <bean id="myServiceFactory"
|
||||
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
|
||||
* <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
|
||||
* </bean>
|
||||
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
|
||||
* <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
|
||||
* </bean>
|
||||
*
|
||||
* <bean id="clientBean" class="a.b.c.MyClientBean">
|
||||
* <property name="myServiceFactory" ref="myServiceFactory"/>
|
||||
* </bean>
|
||||
* <bean id="clientBean" class="a.b.c.MyClientBean">
|
||||
* <property name="myServiceFactory" ref="myServiceFactory"/>
|
||||
* </bean>
|
||||
*
|
||||
*</beans></pre>
|
||||
*</beans></pre>
|
||||
*
|
||||
* <p>The attendant {@code MyClientBean} class implementation might then
|
||||
* look something like this:
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public abstract class YamlProcessor {
|
||||
* </pre>
|
||||
* when mapped with
|
||||
* <pre class="code">
|
||||
* setDocumentMatchers(properties ->
|
||||
* setDocumentMatchers(properties ->
|
||||
* ("prod".equals(properties.getProperty("environment")) ? MatchStatus.FOUND : MatchStatus.NOT_FOUND));
|
||||
* </pre>
|
||||
* would end up as
|
||||
|
||||
+5
-5
@@ -75,18 +75,18 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* def reader = new GroovyBeanDefinitionReader(myApplicationContext)
|
||||
* reader.beans {
|
||||
* dataSource(BasicDataSource) { // <--- invokeMethod
|
||||
* dataSource(BasicDataSource) { // <--- invokeMethod
|
||||
* driverClassName = "org.hsqldb.jdbcDriver"
|
||||
* url = "jdbc:hsqldb:mem:grailsDB"
|
||||
* username = "sa" // <-- setProperty
|
||||
* username = "sa" // <-- setProperty
|
||||
* password = ""
|
||||
* settings = [mynew:"setting"]
|
||||
* }
|
||||
* sessionFactory(SessionFactory) {
|
||||
* dataSource = dataSource // <-- getProperty for retrieving references
|
||||
* dataSource = dataSource // <-- getProperty for retrieving references
|
||||
* }
|
||||
* myService(MyService) {
|
||||
* nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean
|
||||
* nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean
|
||||
* dataSource = dataSource
|
||||
* }
|
||||
* }
|
||||
@@ -113,7 +113,7 @@ import org.springframework.util.StringUtils;
|
||||
* dataSource = dataSource
|
||||
* }
|
||||
* myService(MyService) {
|
||||
* nestedBean = { AnotherBean bean ->
|
||||
* nestedBean = { AnotherBean bean ->
|
||||
* dataSource = dataSource
|
||||
* }
|
||||
* }
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -1342,7 +1342,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @param explicitArgs argument values passed in programmatically via the getBean method,
|
||||
* or {@code null} if none (-> use constructor argument values from bean definition)
|
||||
* or {@code null} if none (implying the use of constructor argument values from bean definition)
|
||||
* @return a BeanWrapper for the new instance
|
||||
* @see #getBean(String, Object[])
|
||||
*/
|
||||
@@ -1363,7 +1363,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param mbd the bean definition for the bean
|
||||
* @param ctors the chosen candidate constructors
|
||||
* @param explicitArgs argument values passed in programmatically via the getBean method,
|
||||
* or {@code null} if none (-> use constructor argument values from bean definition)
|
||||
* or {@code null} if none (implying the use of constructor argument values from bean definition)
|
||||
* @return a BeanWrapper for the new instance
|
||||
*/
|
||||
protected BeanWrapper autowireConstructor(
|
||||
@@ -1844,7 +1844,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
throws Throwable {
|
||||
|
||||
boolean isInitializingBean = (bean instanceof InitializingBean);
|
||||
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
|
||||
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
|
||||
}
|
||||
@@ -1868,7 +1868,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
String initMethodName = mbd.getInitMethodName();
|
||||
if (StringUtils.hasLength(initMethodName) &&
|
||||
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
|
||||
!mbd.isExternallyManagedInitMethod(initMethodName)) {
|
||||
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
|
||||
invokeCustomInitMethod(beanName, bean, mbd);
|
||||
}
|
||||
}
|
||||
@@ -1908,7 +1908,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
|
||||
}
|
||||
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
|
||||
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod, bean.getClass());
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
|
||||
+9
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -103,6 +103,14 @@ public abstract class AbstractBeanDefinitionReader implements BeanDefinitionRead
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the bean factory to register the bean definitions with.
|
||||
* <p>The factory is exposed through the BeanDefinitionRegistry interface,
|
||||
* encapsulating the methods that are relevant for bean definition handling.
|
||||
* @deprecated as of Spring Framework 5.3.15 in favor of {@link #getRegistry()},
|
||||
* to be removed in Spring Framework 6.0
|
||||
*/
|
||||
@Deprecated
|
||||
public final BeanDefinitionRegistry getBeanFactory() {
|
||||
return this.registry;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -361,7 +361,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
else {
|
||||
String scopeName = mbd.getScope();
|
||||
if (!StringUtils.hasLength(scopeName)) {
|
||||
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
|
||||
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
|
||||
}
|
||||
Scope scope = this.scopes.get(scopeName);
|
||||
if (scope == null) {
|
||||
|
||||
+17
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,15 +22,15 @@ import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Simple interface for bean definition readers.
|
||||
* Specifies load methods with Resource and String location parameters.
|
||||
* Simple interface for bean definition readers that specifies load methods with
|
||||
* {@link Resource} and {@link String} location parameters.
|
||||
*
|
||||
* <p>Concrete bean definition readers can of course add additional
|
||||
* load and register methods for bean definitions, specific to
|
||||
* their bean definition format.
|
||||
*
|
||||
* <p>Note that a bean definition reader does not have to implement
|
||||
* this interface. It only serves as suggestion for bean definition
|
||||
* this interface. It only serves as a suggestion for bean definition
|
||||
* readers that want to follow standard naming conventions.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
@@ -41,14 +41,14 @@ public interface BeanDefinitionReader {
|
||||
|
||||
/**
|
||||
* Return the bean factory to register the bean definitions with.
|
||||
* <p>The factory is exposed through the BeanDefinitionRegistry interface,
|
||||
* <p>The factory is exposed through the {@link BeanDefinitionRegistry} interface,
|
||||
* encapsulating the methods that are relevant for bean definition handling.
|
||||
*/
|
||||
BeanDefinitionRegistry getRegistry();
|
||||
|
||||
/**
|
||||
* Return the resource loader to use for resource locations.
|
||||
* Can be checked for the <b>ResourcePatternResolver</b> interface and cast
|
||||
* Return the {@link ResourceLoader} to use for resource locations.
|
||||
* <p>Can be checked for the {@code ResourcePatternResolver} interface and cast
|
||||
* accordingly, for loading multiple resources for a given resource pattern.
|
||||
* <p>A {@code null} return value suggests that absolute resource loading
|
||||
* is not available for this bean definition reader.
|
||||
@@ -56,10 +56,10 @@ public interface BeanDefinitionReader {
|
||||
* from within a bean definition resource, for example via the "import"
|
||||
* tag in XML bean definitions. It is recommended, however, to apply
|
||||
* such imports relative to the defining resource; only explicit full
|
||||
* resource locations will trigger absolute resource loading.
|
||||
* resource locations will trigger absolute path based resource loading.
|
||||
* <p>There is also a {@code loadBeanDefinitions(String)} method available,
|
||||
* for loading bean definitions from a resource location (or location pattern).
|
||||
* This is a convenience to avoid explicit ResourceLoader handling.
|
||||
* This is a convenience to avoid explicit {@code ResourceLoader} handling.
|
||||
* @see #loadBeanDefinitions(String)
|
||||
* @see org.springframework.core.io.support.ResourcePatternResolver
|
||||
*/
|
||||
@@ -70,13 +70,13 @@ public interface BeanDefinitionReader {
|
||||
* Return the class loader to use for bean classes.
|
||||
* <p>{@code null} suggests to not load bean classes eagerly
|
||||
* but rather to just register bean definitions with class names,
|
||||
* with the corresponding Classes to be resolved later (or never).
|
||||
* with the corresponding classes to be resolved later (or never).
|
||||
*/
|
||||
@Nullable
|
||||
ClassLoader getBeanClassLoader();
|
||||
|
||||
/**
|
||||
* Return the BeanNameGenerator to use for anonymous beans
|
||||
* Return the {@link BeanNameGenerator} to use for anonymous beans
|
||||
* (without explicit bean name specified).
|
||||
*/
|
||||
BeanNameGenerator getBeanNameGenerator();
|
||||
@@ -101,9 +101,10 @@ public interface BeanDefinitionReader {
|
||||
/**
|
||||
* Load bean definitions from the specified resource location.
|
||||
* <p>The location can also be a location pattern, provided that the
|
||||
* ResourceLoader of this bean definition reader is a ResourcePatternResolver.
|
||||
* @param location the resource location, to be loaded with the ResourceLoader
|
||||
* (or ResourcePatternResolver) of this bean definition reader
|
||||
* {@link ResourceLoader} of this bean definition reader is a
|
||||
* {@code ResourcePatternResolver}.
|
||||
* @param location the resource location, to be loaded with the {@code ResourceLoader}
|
||||
* (or {@code ResourcePatternResolver}) of this bean definition reader
|
||||
* @return the number of bean definitions found
|
||||
* @throws BeanDefinitionStoreException in case of loading or parsing errors
|
||||
* @see #getResourceLoader()
|
||||
@@ -114,8 +115,8 @@ public interface BeanDefinitionReader {
|
||||
|
||||
/**
|
||||
* Load bean definitions from the specified resource locations.
|
||||
* @param locations the resource locations, to be loaded with the ResourceLoader
|
||||
* (or ResourcePatternResolver) of this bean definition reader
|
||||
* @param locations the resource locations, to be loaded with the {@code ResourceLoader}
|
||||
* (or {@code ResourcePatternResolver}) of this bean definition reader
|
||||
* @return the number of bean definitions found
|
||||
* @throws BeanDefinitionStoreException in case of loading or parsing errors
|
||||
*/
|
||||
|
||||
+13
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -730,14 +730,23 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
return findMergedAnnotationOnBean(beanName, annotationType)
|
||||
return findAnnotationOnBean(beanName, annotationType, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <A extends Annotation> A findAnnotationOnBean(
|
||||
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
return findMergedAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit)
|
||||
.synthesize(MergedAnnotation::isPresent).orElse(null);
|
||||
}
|
||||
|
||||
private <A extends Annotation> MergedAnnotation<A> findMergedAnnotationOnBean(
|
||||
String beanName, Class<A> annotationType) {
|
||||
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit) {
|
||||
|
||||
Class<?> beanType = getType(beanName);
|
||||
Class<?> beanType = getType(beanName, allowFactoryBeanInit);
|
||||
if (beanType != null) {
|
||||
MergedAnnotation<A> annotation =
|
||||
MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY).get(annotationType);
|
||||
|
||||
+100
-58
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,6 +52,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see AbstractBeanFactory
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
@@ -61,6 +62,8 @@ import org.springframework.util.StringUtils;
|
||||
@SuppressWarnings("serial")
|
||||
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
|
||||
private static final String DESTROY_METHOD_NAME = "destroy";
|
||||
|
||||
private static final String CLOSE_METHOD_NAME = "close";
|
||||
|
||||
private static final String SHUTDOWN_METHOD_NAME = "shutdown";
|
||||
@@ -72,12 +75,11 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
|
||||
private final String beanName;
|
||||
|
||||
private final boolean invokeDisposableBean;
|
||||
|
||||
private final boolean nonPublicAccessAllowed;
|
||||
|
||||
@Nullable
|
||||
private final AccessControlContext acc;
|
||||
private final boolean invokeDisposableBean;
|
||||
|
||||
private boolean invokeAutoCloseable;
|
||||
|
||||
@Nullable
|
||||
private String destroyMethodName;
|
||||
@@ -88,6 +90,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
@Nullable
|
||||
private final List<DestructionAwareBeanPostProcessor> beanPostProcessors;
|
||||
|
||||
@Nullable
|
||||
private final AccessControlContext acc;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new DisposableBeanAdapter for the given bean.
|
||||
@@ -103,38 +108,45 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
Assert.notNull(bean, "Disposable bean must not be null");
|
||||
this.bean = bean;
|
||||
this.beanName = beanName;
|
||||
this.invokeDisposableBean =
|
||||
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
|
||||
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
|
||||
this.acc = acc;
|
||||
this.invokeDisposableBean = (bean instanceof DisposableBean &&
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
|
||||
|
||||
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
|
||||
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
Method destroyMethod = determineDestroyMethod(destroyMethodName);
|
||||
if (destroyMethod == null) {
|
||||
if (beanDefinition.isEnforceDestroyMethod()) {
|
||||
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
|
||||
destroyMethodName + "' on bean with name '" + beanName + "'");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (destroyMethod.getParameterCount() > 0) {
|
||||
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
|
||||
if (paramTypes.length > 1) {
|
||||
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
|
||||
beanName + "' has more than one parameter - not supported as destroy method");
|
||||
}
|
||||
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
|
||||
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
|
||||
beanName + "' has a non-boolean parameter - not supported as destroy method");
|
||||
if (destroyMethodName != null &&
|
||||
!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
|
||||
this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));
|
||||
if (!this.invokeAutoCloseable) {
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
Method destroyMethod = determineDestroyMethod(destroyMethodName);
|
||||
if (destroyMethod == null) {
|
||||
if (beanDefinition.isEnforceDestroyMethod()) {
|
||||
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
|
||||
destroyMethodName + "' on bean with name '" + beanName + "'");
|
||||
}
|
||||
}
|
||||
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
|
||||
else {
|
||||
if (destroyMethod.getParameterCount() > 0) {
|
||||
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
|
||||
if (paramTypes.length > 1) {
|
||||
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
|
||||
beanName + "' has more than one parameter - not supported as destroy method");
|
||||
}
|
||||
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
|
||||
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
|
||||
beanName + "' has a non-boolean parameter - not supported as destroy method");
|
||||
}
|
||||
}
|
||||
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod, bean.getClass());
|
||||
}
|
||||
this.destroyMethod = destroyMethod;
|
||||
}
|
||||
this.destroyMethod = destroyMethod;
|
||||
}
|
||||
|
||||
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,26 +161,27 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
Assert.notNull(bean, "Disposable bean must not be null");
|
||||
this.bean = bean;
|
||||
this.beanName = bean.getClass().getName();
|
||||
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
|
||||
this.nonPublicAccessAllowed = true;
|
||||
this.acc = acc;
|
||||
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
|
||||
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DisposableBeanAdapter for the given bean.
|
||||
*/
|
||||
private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDisposableBean,
|
||||
boolean nonPublicAccessAllowed, @Nullable String destroyMethodName,
|
||||
private DisposableBeanAdapter(Object bean, String beanName, boolean nonPublicAccessAllowed,
|
||||
boolean invokeDisposableBean, boolean invokeAutoCloseable, @Nullable String destroyMethodName,
|
||||
@Nullable List<DestructionAwareBeanPostProcessor> postProcessors) {
|
||||
|
||||
this.bean = bean;
|
||||
this.beanName = beanName;
|
||||
this.invokeDisposableBean = invokeDisposableBean;
|
||||
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
|
||||
this.acc = null;
|
||||
this.invokeDisposableBean = invokeDisposableBean;
|
||||
this.invokeAutoCloseable = invokeAutoCloseable;
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
this.beanPostProcessors = postProcessors;
|
||||
this.acc = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -211,13 +224,38 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.destroyMethod != null) {
|
||||
if (this.invokeAutoCloseable) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking close() on bean with name '" + this.beanName + "'");
|
||||
}
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||
((AutoCloseable) this.bean).close();
|
||||
return null;
|
||||
}, this.acc);
|
||||
}
|
||||
else {
|
||||
((AutoCloseable) this.bean).close();
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
String msg = "Invocation of close method failed on bean with name '" + this.beanName + "'";
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn(msg, ex);
|
||||
}
|
||||
else {
|
||||
logger.warn(msg + ": " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.destroyMethod != null) {
|
||||
invokeCustomDestroyMethod(this.destroyMethod);
|
||||
}
|
||||
else if (this.destroyMethodName != null) {
|
||||
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
|
||||
if (methodToInvoke != null) {
|
||||
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
|
||||
Method destroyMethod = determineDestroyMethod(this.destroyMethodName);
|
||||
if (destroyMethod != null) {
|
||||
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(destroyMethod, this.bean.getClass()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,7 +297,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
args[0] = Boolean.TRUE;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking destroy method '" + this.destroyMethodName +
|
||||
logger.trace("Invoking custom destroy method '" + this.destroyMethodName +
|
||||
"' on bean with name '" + this.beanName + "'");
|
||||
}
|
||||
try {
|
||||
@@ -282,7 +320,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
String msg = "Destroy method '" + this.destroyMethodName + "' on bean with name '" +
|
||||
String msg = "Custom destroy method '" + this.destroyMethodName + "' on bean with name '" +
|
||||
this.beanName + "' threw an exception";
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn(msg, ex.getTargetException());
|
||||
@@ -292,7 +330,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.warn("Failed to invoke destroy method '" + this.destroyMethodName +
|
||||
logger.warn("Failed to invoke custom destroy method '" + this.destroyMethodName +
|
||||
"' on bean with name '" + this.beanName + "'", ex);
|
||||
}
|
||||
}
|
||||
@@ -312,8 +350,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
return new DisposableBeanAdapter(this.bean, this.beanName, this.invokeDisposableBean,
|
||||
this.nonPublicAccessAllowed, this.destroyMethodName, serializablePostProcessors);
|
||||
return new DisposableBeanAdapter(
|
||||
this.bean, this.beanName, this.nonPublicAccessAllowed, this.invokeDisposableBean,
|
||||
this.invokeAutoCloseable, this.destroyMethodName, serializablePostProcessors);
|
||||
}
|
||||
|
||||
|
||||
@@ -323,10 +362,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
* @param beanDefinition the corresponding bean definition
|
||||
*/
|
||||
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
|
||||
if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
|
||||
return true;
|
||||
}
|
||||
return inferDestroyMethodIfNecessary(bean, beanDefinition) != null;
|
||||
return (bean instanceof DisposableBean || inferDestroyMethodIfNecessary(bean, beanDefinition) != null);
|
||||
}
|
||||
|
||||
|
||||
@@ -348,21 +384,27 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
|
||||
if (destroyMethodName == null) {
|
||||
destroyMethodName = beanDefinition.getDestroyMethodName();
|
||||
boolean autoCloseable = (bean instanceof AutoCloseable);
|
||||
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
|
||||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
|
||||
// Only perform destroy method inference or Closeable detection
|
||||
// in case of the bean not explicitly implementing DisposableBean
|
||||
(destroyMethodName == null && autoCloseable)) {
|
||||
// Only perform destroy method inference in case of the bean
|
||||
// not explicitly implementing the DisposableBean interface
|
||||
destroyMethodName = null;
|
||||
if (!(bean instanceof DisposableBean)) {
|
||||
try {
|
||||
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
|
||||
if (autoCloseable) {
|
||||
destroyMethodName = CLOSE_METHOD_NAME;
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
else {
|
||||
try {
|
||||
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
|
||||
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
|
||||
}
|
||||
catch (NoSuchMethodException ex2) {
|
||||
// no candidate destroy method found
|
||||
catch (NoSuchMethodException ex) {
|
||||
try {
|
||||
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
|
||||
}
|
||||
catch (NoSuchMethodException ex2) {
|
||||
// no candidate destroy method found
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
@@ -53,6 +54,20 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new instance containing an arbitrary number of elements.
|
||||
* @param elements the elements to be contained in the list
|
||||
* @param <E> the {@code List}'s element type
|
||||
* @return a {@code List} containing the specified elements
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <E> ManagedList<E> of(E... elements) {
|
||||
ManagedList<E> list = new ManagedList<>();
|
||||
list.addAll(Arrays.asList(elements));
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configuration source {@code Object} for this metadata element.
|
||||
* <p>The exact type of the object will depend on the configuration mechanism used.
|
||||
|
||||
+22
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.beans.factory.support;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.Mergeable;
|
||||
@@ -56,6 +57,26 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new instance containing keys and values extracted from the
|
||||
* given entries. The entries themselves are not stored in the map.
|
||||
* @param entries {@code Map.Entry}s containing the keys and values
|
||||
* from which the map is populated
|
||||
* @param <K> the {@code Map}'s key type
|
||||
* @param <V> the {@code Map}'s value type
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K,V> ManagedMap<K,V> ofEntries(Entry<? extends K, ? extends V>... entries) {
|
||||
ManagedMap<K,V > map = new ManagedMap<>();
|
||||
for (Entry<? extends K, ? extends V> entry : entries) {
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configuration source {@code Object} for this metadata element.
|
||||
* <p>The exact type of the object will depend on the configuration mechanism used.
|
||||
|
||||
+16
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -52,6 +53,20 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new instance containing an arbitrary number of elements.
|
||||
* @param elements the elements to be contained in the set
|
||||
* @param <E> the {@code Set}'s element type
|
||||
* @return a {@code Set} containing the specified elements
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <E> ManagedSet<E> of(E... elements) {
|
||||
ManagedSet<E> set = new ManagedSet<>();
|
||||
set.addAll(Arrays.asList(elements));
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configuration source {@code Object} for this metadata element.
|
||||
* <p>The exact type of the object will depend on the configuration mechanism used.
|
||||
|
||||
+147
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,8 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -48,6 +49,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @see GenericBeanDefinition
|
||||
* @see ChildBeanDefinition
|
||||
*/
|
||||
@@ -422,15 +424,21 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
return this.factoryMethodToIntrospect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration method or field.
|
||||
*/
|
||||
public void registerExternallyManagedConfigMember(Member configMember) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (this.externallyManagedConfigMembers == null) {
|
||||
this.externallyManagedConfigMembers = new HashSet<>(1);
|
||||
this.externallyManagedConfigMembers = new LinkedHashSet<>(1);
|
||||
}
|
||||
this.externallyManagedConfigMembers.add(configMember);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method or field is an externally managed configuration member.
|
||||
*/
|
||||
public boolean isExternallyManagedConfigMember(Member configMember) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedConfigMembers != null &&
|
||||
@@ -438,15 +446,44 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all externally managed configuration methods and fields (as an immutable Set).
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<Member> getExternallyManagedConfigMembers() {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedConfigMembers != null ?
|
||||
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedConfigMembers)) :
|
||||
Collections.emptySet());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration initialization method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PostConstruct} annotation.
|
||||
* <p>The supplied {@code initMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
*/
|
||||
public void registerExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (this.externallyManagedInitMethods == null) {
|
||||
this.externallyManagedInitMethods = new HashSet<>(1);
|
||||
this.externallyManagedInitMethods = new LinkedHashSet<>(1);
|
||||
}
|
||||
this.externallyManagedInitMethods.add(initMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* initialization method.
|
||||
* <p>See {@link #registerExternallyManagedInitMethod} for details
|
||||
* regarding the format for the supplied {@code initMethod}.
|
||||
*/
|
||||
public boolean isExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedInitMethods != null &&
|
||||
@@ -454,15 +491,76 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* initialization method, regardless of method visibility.
|
||||
* <p>In contrast to {@link #isExternallyManagedInitMethod(String)}, this
|
||||
* method also returns {@code true} if there is a {@code private} externally
|
||||
* managed initialization method that has been
|
||||
* {@linkplain #registerExternallyManagedInitMethod(String) registered}
|
||||
* using a qualified method name instead of a simple method name.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
boolean hasAnyExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (isExternallyManagedInitMethod(initMethod)) {
|
||||
return true;
|
||||
}
|
||||
if (this.externallyManagedInitMethods != null) {
|
||||
for (String candidate : this.externallyManagedInitMethods) {
|
||||
int indexOfDot = candidate.lastIndexOf('.');
|
||||
if (indexOfDot >= 0) {
|
||||
String methodName = candidate.substring(indexOfDot + 1);
|
||||
if (methodName.equals(initMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all externally managed initialization methods (as an immutable Set).
|
||||
* <p>See {@link #registerExternallyManagedInitMethod} for details
|
||||
* regarding the format for the initialization methods in the returned set.
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedInitMethods() {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedInitMethods != null ?
|
||||
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedInitMethods)) :
|
||||
Collections.emptySet());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration destruction method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PreDestroy} annotation.
|
||||
* <p>The supplied {@code destroyMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
*/
|
||||
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (this.externallyManagedDestroyMethods == null) {
|
||||
this.externallyManagedDestroyMethods = new HashSet<>(1);
|
||||
this.externallyManagedDestroyMethods = new LinkedHashSet<>(1);
|
||||
}
|
||||
this.externallyManagedDestroyMethods.add(destroyMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* destruction method.
|
||||
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
|
||||
* regarding the format for the supplied {@code destroyMethod}.
|
||||
*/
|
||||
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedDestroyMethods != null &&
|
||||
@@ -470,6 +568,50 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* destruction method, regardless of method visibility.
|
||||
* <p>In contrast to {@link #isExternallyManagedDestroyMethod(String)}, this
|
||||
* method also returns {@code true} if there is a {@code private} externally
|
||||
* managed destruction method that has been
|
||||
* {@linkplain #registerExternallyManagedDestroyMethod(String) registered}
|
||||
* using a qualified method name instead of a simple method name.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
boolean hasAnyExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (isExternallyManagedDestroyMethod(destroyMethod)) {
|
||||
return true;
|
||||
}
|
||||
if (this.externallyManagedDestroyMethods != null) {
|
||||
for (String candidate : this.externallyManagedDestroyMethods) {
|
||||
int indexOfDot = candidate.lastIndexOf('.');
|
||||
if (indexOfDot >= 0) {
|
||||
String methodName = candidate.substring(indexOfDot + 1);
|
||||
if (methodName.equals(destroyMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all externally managed destruction methods (as an immutable Set).
|
||||
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
|
||||
* regarding the format for the destruction methods in the returned set.
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedDestroyMethods() {
|
||||
synchronized (this.postProcessingLock) {
|
||||
return (this.externallyManagedDestroyMethods != null ?
|
||||
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedDestroyMethods)) :
|
||||
Collections.emptySet());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RootBeanDefinition cloneBeanDefinition() {
|
||||
|
||||
+11
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -459,7 +459,16 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
Class<?> beanType = getType(beanName);
|
||||
return findAnnotationOnBean(beanName, annotationType, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <A extends Annotation> A findAnnotationOnBean(
|
||||
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
Class<?> beanType = getType(beanName, allowFactoryBeanInit);
|
||||
return (beanType != null ? AnnotatedElementUtils.findMergedAnnotation(beanType, annotationType) : null);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ import org.springframework.util.xml.XmlValidationModeDetector;
|
||||
* when starting your JVM. For example, to use the Oracle {@link DocumentBuilder},
|
||||
* you might start your application like as follows:
|
||||
*
|
||||
* <pre code="class">java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass</pre>
|
||||
* <pre class="code">java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass</pre>
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -64,24 +64,24 @@ public final class ParserContext {
|
||||
}
|
||||
|
||||
|
||||
public final XmlReaderContext getReaderContext() {
|
||||
public XmlReaderContext getReaderContext() {
|
||||
return this.readerContext;
|
||||
}
|
||||
|
||||
public final BeanDefinitionRegistry getRegistry() {
|
||||
public BeanDefinitionRegistry getRegistry() {
|
||||
return this.readerContext.getRegistry();
|
||||
}
|
||||
|
||||
public final BeanDefinitionParserDelegate getDelegate() {
|
||||
public BeanDefinitionParserDelegate getDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final BeanDefinition getContainingBeanDefinition() {
|
||||
public BeanDefinition getContainingBeanDefinition() {
|
||||
return this.containingBeanDefinition;
|
||||
}
|
||||
|
||||
public final boolean isNested() {
|
||||
public boolean isNested() {
|
||||
return (this.containingBeanDefinition != null);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -71,13 +71,13 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
|
||||
private final String schemaMappingsLocation;
|
||||
|
||||
/** Stores the mapping of schema URL -> local schema path. */
|
||||
/** Stores the mapping of schema URL → local schema path. */
|
||||
@Nullable
|
||||
private volatile Map<String, String> schemaMappings;
|
||||
|
||||
|
||||
/**
|
||||
* Loads the schema URL -> schema file location mappings using the default
|
||||
* Loads the schema URL → schema file location mappings using the default
|
||||
* mapping file pattern "META-INF/spring.schemas".
|
||||
* @param classLoader the ClassLoader to use for loading
|
||||
* (can be {@code null}) to use the default ClassLoader)
|
||||
@@ -89,7 +89,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the schema URL -> schema file location mappings using the given
|
||||
* Loads the schema URL → schema file location mappings using the given
|
||||
* mapping file pattern.
|
||||
* @param classLoader the ClassLoader to use for loading
|
||||
* (can be {@code null}) to use the default ClassLoader)
|
||||
|
||||
+1
-1
@@ -64,6 +64,6 @@ inline fun <reified T : Annotation> ListableBeanFactory.getBeansWithAnnotation()
|
||||
* @author Sebastien Deleuze
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String): Annotation? =
|
||||
inline fun <reified T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String): T? =
|
||||
findAnnotationOnBean(beanName, T::class.java)
|
||||
|
||||
|
||||
+4
-4
@@ -43,13 +43,13 @@ public abstract class AbstractPropertyValuesTests {
|
||||
m.put("forname", "Tony");
|
||||
m.put("surname", "Blair");
|
||||
m.put("age", "50");
|
||||
for (int i = 0; i < ps.length; i++) {
|
||||
Object val = m.get(ps[i].getName());
|
||||
for (PropertyValue element : ps) {
|
||||
Object val = m.get(element.getName());
|
||||
assertThat(val != null).as("Can't have unexpected value").isTrue();
|
||||
boolean condition = val instanceof String;
|
||||
assertThat(condition).as("Val i string").isTrue();
|
||||
assertThat(val.equals(ps[i].getValue())).as("val matches expected").isTrue();
|
||||
m.remove(ps[i].getName());
|
||||
assertThat(val.equals(element.getValue())).as("val matches expected").isTrue();
|
||||
m.remove(element.getName());
|
||||
}
|
||||
assertThat(m.size() == 0).as("Map size is 0").isTrue();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -203,8 +203,25 @@ class BeanUtilsTests {
|
||||
assertThat(tb2.getTouchy().equals(tb.getTouchy())).as("Touchy copied").isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Integer} can be copied to {@code Number}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatches() {
|
||||
void copyPropertiesFromSubTypeToSuperType() {
|
||||
IntegerHolder integerHolder = new IntegerHolder();
|
||||
integerHolder.setNumber(42);
|
||||
NumberHolder numberHolder = new NumberHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerHolder, numberHolder);
|
||||
assertThat(integerHolder.getNumber()).isEqualTo(42);
|
||||
assertThat(numberHolder.getNumber()).isEqualTo(42);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<Integer>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromIntegerToInteger() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
IntegerListHolder2 integerListHolder2 = new IntegerListHolder2();
|
||||
@@ -214,6 +231,68 @@ class BeanUtilsTests {
|
||||
assertThat(integerListHolder2.getList()).containsOnly(42);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<?>} can be copied to {@code List<?>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromWildcardToWildcard() {
|
||||
List<?> list = Arrays.asList("foo", 42);
|
||||
WildcardListHolder1 wildcardListHolder1 = new WildcardListHolder1();
|
||||
wildcardListHolder1.setList(list);
|
||||
WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2();
|
||||
assertThat(wildcardListHolder2.getList()).isEmpty();
|
||||
|
||||
BeanUtils.copyProperties(wildcardListHolder1, wildcardListHolder2);
|
||||
assertThat(wildcardListHolder1.getList()).isEqualTo(list);
|
||||
assertThat(wildcardListHolder2.getList()).isEqualTo(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<?>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromIntegerToWildcard() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder1, wildcardListHolder2);
|
||||
assertThat(integerListHolder1.getList()).containsOnly(42);
|
||||
assertThat(wildcardListHolder2.getList()).isEqualTo(Arrays.asList(42));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<? extends Number>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesForUpperBoundedWildcard() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
NumberUpperBoundedWildcardListHolder numberListHolder = new NumberUpperBoundedWildcardListHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder1, numberListHolder);
|
||||
assertThat(integerListHolder1.getList()).containsOnly(42);
|
||||
assertThat(numberListHolder.getList()).hasSize(1);
|
||||
assertThat(numberListHolder.getList().contains(Integer.valueOf(42))).isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Number} can NOT be copied to {@code Integer}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotCopyeFromSuperTypeToSubType() {
|
||||
NumberHolder numberHolder = new NumberHolder();
|
||||
numberHolder.setNumber(Integer.valueOf(42));
|
||||
IntegerHolder integerHolder = new IntegerHolder();
|
||||
|
||||
BeanUtils.copyProperties(numberHolder, integerHolder);
|
||||
assertThat(numberHolder.getNumber()).isEqualTo(42);
|
||||
assertThat(integerHolder.getNumber()).isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can NOT be copied to {@code List<Long>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotHonorGenericTypeMismatches() {
|
||||
IntegerListHolder1 integerListHolder = new IntegerListHolder1();
|
||||
@@ -225,6 +304,20 @@ class BeanUtilsTests {
|
||||
assertThat(longListHolder.getList()).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can NOT be copied to {@code List<Number>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotHonorGenericTypeMismatchesFromSubTypeToSuperType() {
|
||||
IntegerListHolder1 integerListHolder = new IntegerListHolder1();
|
||||
integerListHolder.getList().add(42);
|
||||
NumberListHolder numberListHolder = new NumberListHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder, numberListHolder);
|
||||
assertThat(integerListHolder.getList()).containsOnly(42);
|
||||
assertThat(numberListHolder.getList()).isEmpty();
|
||||
}
|
||||
|
||||
@Test // gh-26531
|
||||
void copyPropertiesIgnoresGenericsIfSourceOrTargetHasUnresolvableGenerics() throws Exception {
|
||||
Order original = new Order("test", Arrays.asList("foo", "bar"));
|
||||
@@ -413,6 +506,90 @@ class BeanUtilsTests {
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberHolder {
|
||||
|
||||
private Number number;
|
||||
|
||||
public Number getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Number number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class IntegerHolder {
|
||||
|
||||
private Integer number;
|
||||
|
||||
public Integer getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Integer number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class WildcardListHolder1 {
|
||||
|
||||
private List<?> list = new ArrayList<>();
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class WildcardListHolder2 {
|
||||
|
||||
private List<?> list = new ArrayList<>();
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberUpperBoundedWildcardListHolder {
|
||||
|
||||
private List<? extends Number> list = new ArrayList<>();
|
||||
|
||||
public List<? extends Number> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<? extends Number> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberListHolder {
|
||||
|
||||
private List<Number> list = new ArrayList<>();
|
||||
|
||||
public List<Number> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<Number> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class IntegerListHolder1 {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnum", null);
|
||||
assertThat(gb.getCustomEnum()).isEqualTo(null);
|
||||
assertThat(gb.getCustomEnum()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,7 +54,7 @@ public class BeanWrapperEnumTests {
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnum", "");
|
||||
assertThat(gb.getCustomEnum()).isEqualTo(null);
|
||||
assertThat(gb.getCustomEnum()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
@@ -483,6 +483,7 @@ public class BeanFactoryUtilsTests {
|
||||
return TestBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestBean getObject() {
|
||||
// We don't really care if the actual instance is a singleton or prototype
|
||||
// for the tests that use this factory.
|
||||
|
||||
+22
-31
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,8 +48,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.NotWritablePropertyException;
|
||||
import org.springframework.beans.PropertyEditorRegistrar;
|
||||
import org.springframework.beans.PropertyEditorRegistry;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
@@ -84,7 +82,6 @@ import org.springframework.beans.testfixture.beans.factory.DummyFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -433,7 +430,7 @@ class DefaultListableBeanFactoryTests {
|
||||
assertThat(lbf.isTypeMatch("x1", Object.class)).isTrue();
|
||||
assertThat(lbf.isTypeMatch("&x1", Object.class)).isFalse();
|
||||
assertThat(lbf.getType("x1")).isEqualTo(TestBean.class);
|
||||
assertThat(lbf.getType("&x1")).isEqualTo(null);
|
||||
assertThat(lbf.getType("&x1")).isNull();
|
||||
assertThat(TestBeanFactory.initialized).isFalse();
|
||||
|
||||
lbf.registerAlias("x1", "x2");
|
||||
@@ -990,16 +987,13 @@ class DefaultListableBeanFactoryTests {
|
||||
@Test
|
||||
void customConverter() {
|
||||
GenericConversionService conversionService = new DefaultConversionService();
|
||||
conversionService.addConverter(new Converter<String, Float>() {
|
||||
@Override
|
||||
public Float convert(String source) {
|
||||
try {
|
||||
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
|
||||
return nf.parse(source).floatValue();
|
||||
}
|
||||
catch (ParseException ex) {
|
||||
throw new IllegalArgumentException(ex);
|
||||
}
|
||||
conversionService.addConverter(String.class, Float.class, source -> {
|
||||
try {
|
||||
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
|
||||
return nf.parse(source).floatValue();
|
||||
}
|
||||
catch (ParseException ex) {
|
||||
throw new IllegalArgumentException(ex);
|
||||
}
|
||||
});
|
||||
lbf.setConversionService(conversionService);
|
||||
@@ -1014,12 +1008,9 @@ class DefaultListableBeanFactoryTests {
|
||||
|
||||
@Test
|
||||
void customEditorWithBeanReference() {
|
||||
lbf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
|
||||
@Override
|
||||
public void registerCustomEditors(PropertyEditorRegistry registry) {
|
||||
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
|
||||
registry.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, nf, true));
|
||||
}
|
||||
lbf.addPropertyEditorRegistrar(registry -> {
|
||||
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
|
||||
registry.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, nf, true));
|
||||
});
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.add("myFloat", new RuntimeBeanReference("myFloat"));
|
||||
@@ -2307,9 +2298,7 @@ class DefaultListableBeanFactoryTests {
|
||||
|
||||
@Test
|
||||
void prototypeWithArrayConversionForConstructor() {
|
||||
List<String> list = new ManagedList<>();
|
||||
list.add("myName");
|
||||
list.add("myBeanName");
|
||||
List<String> list = ManagedList.of("myName", "myBeanName");
|
||||
RootBeanDefinition bd = new RootBeanDefinition(DerivedTestBean.class);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue(list);
|
||||
@@ -2325,9 +2314,7 @@ class DefaultListableBeanFactoryTests {
|
||||
|
||||
@Test
|
||||
void prototypeWithArrayConversionForFactoryMethod() {
|
||||
List<String> list = new ManagedList<>();
|
||||
list.add("myName");
|
||||
list.add("myBeanName");
|
||||
List<String> list = ManagedList.of("myName", "myBeanName");
|
||||
RootBeanDefinition bd = new RootBeanDefinition(DerivedTestBean.class);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.setFactoryMethodName("create");
|
||||
@@ -2622,8 +2609,8 @@ class DefaultListableBeanFactoryTests {
|
||||
void containsBeanReturnsTrueEvenForAbstractBeanDefinition() {
|
||||
lbf.registerBeanDefinition("abs", BeanDefinitionBuilder
|
||||
.rootBeanDefinition(TestBean.class).setAbstract(true).getBeanDefinition());
|
||||
assertThat(lbf.containsBean("abs")).isEqualTo(true);
|
||||
assertThat(lbf.containsBean("bogus")).isEqualTo(false);
|
||||
assertThat(lbf.containsBean("abs")).isTrue();
|
||||
assertThat(lbf.containsBean("bogus")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2718,8 +2705,12 @@ class DefaultListableBeanFactoryTests {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ConstructorDependency that = (ConstructorDependency) o;
|
||||
return spouseAge == that.spouseAge &&
|
||||
Objects.equals(spouse, that.spouse) &&
|
||||
|
||||
+2
-6
@@ -22,7 +22,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -3660,11 +3659,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T createMock(Class<T> toMock) {
|
||||
return (T) Proxy.newProxyInstance(AutowiredAnnotationBeanPostProcessorTests.class.getClassLoader(), new Class<?>[] {toMock},
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
throw new UnsupportedOperationException("mocked!");
|
||||
}
|
||||
(InvocationHandler) (proxy, method, args) -> {
|
||||
throw new UnsupportedOperationException("mocked!");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+1
-7
@@ -29,7 +29,6 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyEditorRegistrar;
|
||||
import org.springframework.beans.PropertyEditorRegistry;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||
@@ -50,12 +49,7 @@ public class CustomEditorConfigurerTests {
|
||||
CustomEditorConfigurer cec = new CustomEditorConfigurer();
|
||||
final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN);
|
||||
cec.setPropertyEditorRegistrars(new PropertyEditorRegistrar[] {
|
||||
new PropertyEditorRegistrar() {
|
||||
@Override
|
||||
public void registerCustomEditors(PropertyEditorRegistry registry) {
|
||||
registry.registerCustomEditor(Date.class, new CustomDateEditor(df, true));
|
||||
}
|
||||
}});
|
||||
registry -> registry.registerCustomEditor(Date.class, new CustomDateEditor(df, true))});
|
||||
cec.postProcessBeanFactory(bf);
|
||||
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
|
||||
+5
-5
@@ -113,7 +113,7 @@ public class MethodInvokingFactoryBeanTests {
|
||||
mcfb = new MethodInvokingFactoryBean();
|
||||
mcfb.setTargetClass(TestClass1.class);
|
||||
mcfb.setTargetMethod("supertypes");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), "hello");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), "hello");
|
||||
mcfb.afterPropertiesSet();
|
||||
mcfb.getObjectType();
|
||||
|
||||
@@ -184,7 +184,7 @@ public class MethodInvokingFactoryBeanTests {
|
||||
mcfb = new MethodInvokingFactoryBean();
|
||||
mcfb.setTargetClass(TestClass1.class);
|
||||
mcfb.setTargetMethod("supertypes");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), "hello");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), "hello");
|
||||
// should pass
|
||||
mcfb.afterPropertiesSet();
|
||||
}
|
||||
@@ -194,7 +194,7 @@ public class MethodInvokingFactoryBeanTests {
|
||||
MethodInvokingFactoryBean mcfb = new MethodInvokingFactoryBean();
|
||||
mcfb.setTargetClass(TestClass1.class);
|
||||
mcfb.setTargetMethod("supertypes");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), "hello", "bogus");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), "hello", "bogus");
|
||||
assertThatExceptionOfType(NoSuchMethodException.class).as(
|
||||
"Matched method with wrong number of args").isThrownBy(
|
||||
mcfb::afterPropertiesSet);
|
||||
@@ -210,14 +210,14 @@ public class MethodInvokingFactoryBeanTests {
|
||||
mcfb = new MethodInvokingFactoryBean();
|
||||
mcfb.setTargetClass(TestClass1.class);
|
||||
mcfb.setTargetMethod("supertypes2");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), "hello", "bogus");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), "hello", "bogus");
|
||||
mcfb.afterPropertiesSet();
|
||||
assertThat(mcfb.getObject()).isEqualTo("hello");
|
||||
|
||||
mcfb = new MethodInvokingFactoryBean();
|
||||
mcfb.setTargetClass(TestClass1.class);
|
||||
mcfb.setTargetMethod("supertypes2");
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<Object>(), new Object());
|
||||
mcfb.setArguments(new ArrayList<>(), new ArrayList<>(), new Object());
|
||||
assertThatExceptionOfType(NoSuchMethodException.class).as(
|
||||
"Matched method when shouldn't have matched").isThrownBy(
|
||||
mcfb::afterPropertiesSet);
|
||||
|
||||
+13
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -111,7 +112,7 @@ public class PropertyResourceConfigurerTests {
|
||||
|
||||
assertThat(tb1.getAge()).isEqualTo(99);
|
||||
assertThat(tb2.getAge()).isEqualTo(99);
|
||||
assertThat(tb1.getName()).isEqualTo(null);
|
||||
assertThat(tb1.getName()).isNull();
|
||||
assertThat(tb2.getName()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@@ -310,7 +311,7 @@ public class PropertyResourceConfigurerTests {
|
||||
TestBean tb2 = (TestBean) factory.getBean("tb2");
|
||||
assertThat(tb1.getAge()).isEqualTo(99);
|
||||
assertThat(tb2.getAge()).isEqualTo(99);
|
||||
assertThat(tb1.getName()).isEqualTo(null);
|
||||
assertThat(tb1.getName()).isNull();
|
||||
assertThat(tb2.getName()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@@ -357,22 +358,18 @@ public class PropertyResourceConfigurerTests {
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.add("stringArray", new String[] {"${os.name}", "${age}"});
|
||||
|
||||
List<Object> friends = new ManagedList<>();
|
||||
friends.add("na${age}me");
|
||||
friends.add(new RuntimeBeanReference("${ref}"));
|
||||
List<Object> friends = ManagedList.of("na${age}me", new RuntimeBeanReference("${ref}"));
|
||||
pvs.add("friends", friends);
|
||||
|
||||
Set<Object> someSet = new ManagedSet<>();
|
||||
someSet.add("na${age}me");
|
||||
someSet.add(new RuntimeBeanReference("${ref}"));
|
||||
someSet.add(new TypedStringValue("${age}", Integer.class));
|
||||
Set<Object> someSet = ManagedSet.of("na${age}me",
|
||||
new RuntimeBeanReference("${ref}"), new TypedStringValue("${age}", Integer.class));
|
||||
pvs.add("someSet", someSet);
|
||||
|
||||
Map<Object, Object> someMap = new ManagedMap<>();
|
||||
someMap.put(new TypedStringValue("key${age}"), new TypedStringValue("${age}"));
|
||||
someMap.put(new TypedStringValue("key${age}ref"), new RuntimeBeanReference("${ref}"));
|
||||
someMap.put("key1", new RuntimeBeanReference("${ref}"));
|
||||
someMap.put("key2", "${age}name");
|
||||
Map<Object, Object> someMap = ManagedMap.ofEntries(
|
||||
new SimpleEntry<>(new TypedStringValue("key${age}"), new TypedStringValue("${age}")),
|
||||
new SimpleEntry<>(new TypedStringValue("key${age}ref"), new RuntimeBeanReference("${ref}")),
|
||||
new SimpleEntry<>("key1", new RuntimeBeanReference("${ref}")),
|
||||
new SimpleEntry<>("key2", "${age}name"));
|
||||
MutablePropertyValues innerPvs = new MutablePropertyValues();
|
||||
innerPvs.add("country", "${os.name}");
|
||||
RootBeanDefinition innerBd = new RootBeanDefinition(TestBean.class);
|
||||
@@ -423,7 +420,7 @@ public class PropertyResourceConfigurerTests {
|
||||
TestBean inner1 = (TestBean) tb2.getSomeMap().get("key3");
|
||||
TestBean inner2 = (TestBean) tb2.getSomeMap().get("mykey4");
|
||||
assertThat(inner1.getAge()).isEqualTo(0);
|
||||
assertThat(inner1.getName()).isEqualTo(null);
|
||||
assertThat(inner1.getName()).isNull();
|
||||
assertThat(inner1.getCountry()).isEqualTo(System.getProperty("os.name"));
|
||||
assertThat(inner2.getAge()).isEqualTo(98);
|
||||
assertThat(inner2.getName()).isEqualTo("namemyvarmyvar${");
|
||||
|
||||
+4
-20
@@ -17,7 +17,6 @@
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
@@ -34,8 +33,6 @@ import java.util.stream.Collectors;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.PropertyEditorRegistrar;
|
||||
import org.springframework.beans.PropertyEditorRegistry;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
@@ -409,12 +406,7 @@ class BeanFactoryGenericsTests {
|
||||
@Test
|
||||
void testGenericMapWithCollectionValueConstructor() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
|
||||
@Override
|
||||
public void registerCustomEditors(PropertyEditorRegistry registry) {
|
||||
registry.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false));
|
||||
}
|
||||
});
|
||||
bf.addPropertyEditorRegistrar(registry -> registry.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false)));
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
|
||||
|
||||
Map<String, AbstractCollection<?>> input = new HashMap<>();
|
||||
@@ -568,12 +560,7 @@ class BeanFactoryGenericsTests {
|
||||
@Test
|
||||
void testGenericMapWithCollectionValueFactoryMethod() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
|
||||
@Override
|
||||
public void registerCustomEditors(PropertyEditorRegistry registry) {
|
||||
registry.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false));
|
||||
}
|
||||
});
|
||||
bf.addPropertyEditorRegistrar(registry -> registry.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false)));
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
|
||||
rbd.setFactoryMethodName("createInstance");
|
||||
|
||||
@@ -1010,11 +997,8 @@ class BeanFactoryGenericsTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T createMock(Class<T> toMock) {
|
||||
return (T) Proxy.newProxyInstance(BeanFactoryGenericsTests.class.getClassLoader(), new Class<?>[] {toMock},
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
throw new UnsupportedOperationException("mocked!");
|
||||
}
|
||||
(InvocationHandler) (proxy, method, args) -> {
|
||||
throw new UnsupportedOperationException("mocked!");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+1
-8
@@ -18,8 +18,6 @@ package org.springframework.beans.factory.support;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.testfixture.beans.DerivedTestBean;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
@@ -40,12 +38,7 @@ public class DefaultSingletonBeanRegistryTests {
|
||||
beanRegistry.registerSingleton("tb", tb);
|
||||
assertThat(beanRegistry.getSingleton("tb")).isSameAs(tb);
|
||||
|
||||
TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", new ObjectFactory<Object>() {
|
||||
@Override
|
||||
public Object getObject() throws BeansException {
|
||||
return new TestBean();
|
||||
}
|
||||
});
|
||||
TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", () -> new TestBean());
|
||||
assertThat(beanRegistry.getSingleton("tb2")).isSameAs(tb2);
|
||||
|
||||
assertThat(beanRegistry.getSingleton("tb")).isSameAs(tb);
|
||||
|
||||
+8
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,11 +34,8 @@ public class ManagedListTests {
|
||||
|
||||
@Test
|
||||
public void mergeSunnyDay() {
|
||||
ManagedList parent = new ManagedList();
|
||||
parent.add("one");
|
||||
parent.add("two");
|
||||
ManagedList child = new ManagedList();
|
||||
child.add("three");
|
||||
ManagedList parent = ManagedList.of("one", "two");
|
||||
ManagedList child = ManagedList.of("three");
|
||||
child.setMergeEnabled(true);
|
||||
List mergedList = child.merge(parent);
|
||||
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(3);
|
||||
@@ -46,8 +43,7 @@ public class ManagedListTests {
|
||||
|
||||
@Test
|
||||
public void mergeWithNullParent() {
|
||||
ManagedList child = new ManagedList();
|
||||
child.add("one");
|
||||
ManagedList child = ManagedList.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
assertThat(child.merge(null)).isSameAs(child);
|
||||
}
|
||||
@@ -61,8 +57,7 @@ public class ManagedListTests {
|
||||
|
||||
@Test
|
||||
public void mergeWithNonCompatibleParentType() {
|
||||
ManagedList child = new ManagedList();
|
||||
child.add("one");
|
||||
ManagedList child = ManagedList.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
child.merge("hello"));
|
||||
@@ -70,9 +65,7 @@ public class ManagedListTests {
|
||||
|
||||
@Test
|
||||
public void mergeEmptyChild() {
|
||||
ManagedList parent = new ManagedList();
|
||||
parent.add("one");
|
||||
parent.add("two");
|
||||
ManagedList parent = ManagedList.of("one", "two");
|
||||
ManagedList child = new ManagedList();
|
||||
child.setMergeEnabled(true);
|
||||
List mergedList = child.merge(parent);
|
||||
@@ -82,11 +75,8 @@ public class ManagedListTests {
|
||||
@Test
|
||||
public void mergeChildValuesOverrideTheParents() {
|
||||
// doesn't make much sense in the context of a list...
|
||||
ManagedList parent = new ManagedList();
|
||||
parent.add("one");
|
||||
parent.add("two");
|
||||
ManagedList child = new ManagedList();
|
||||
child.add("one");
|
||||
ManagedList parent = ManagedList.of("one", "two");
|
||||
ManagedList child = ManagedList.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
List mergedList = child.merge(parent);
|
||||
assertThat(mergedList.size()).as("merge() obviously did not work.").isEqualTo(3);
|
||||
|
||||
+10
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -34,11 +35,9 @@ public class ManagedMapTests {
|
||||
|
||||
@Test
|
||||
public void mergeSunnyDay() {
|
||||
ManagedMap parent = new ManagedMap();
|
||||
parent.put("one", "one");
|
||||
parent.put("two", "two");
|
||||
ManagedMap child = new ManagedMap();
|
||||
child.put("three", "three");
|
||||
ManagedMap parent = ManagedMap.ofEntries(new SimpleEntry<>("one", "one"),
|
||||
new SimpleEntry<>("two", "two"));
|
||||
ManagedMap child = ManagedMap.ofEntries(new SimpleEntry<>("tree", "three"));
|
||||
child.setMergeEnabled(true);
|
||||
Map mergedMap = (Map) child.merge(parent);
|
||||
assertThat(mergedMap.size()).as("merge() obviously did not work.").isEqualTo(3);
|
||||
@@ -67,9 +66,8 @@ public class ManagedMapTests {
|
||||
|
||||
@Test
|
||||
public void mergeEmptyChild() {
|
||||
ManagedMap parent = new ManagedMap();
|
||||
parent.put("one", "one");
|
||||
parent.put("two", "two");
|
||||
ManagedMap parent = ManagedMap.ofEntries(new SimpleEntry<>("one", "one"),
|
||||
new SimpleEntry<>("two", "two"));
|
||||
ManagedMap child = new ManagedMap();
|
||||
child.setMergeEnabled(true);
|
||||
Map mergedMap = (Map) child.merge(parent);
|
||||
@@ -78,11 +76,9 @@ public class ManagedMapTests {
|
||||
|
||||
@Test
|
||||
public void mergeChildValuesOverrideTheParents() {
|
||||
ManagedMap parent = new ManagedMap();
|
||||
parent.put("one", "one");
|
||||
parent.put("two", "two");
|
||||
ManagedMap child = new ManagedMap();
|
||||
child.put("one", "fork");
|
||||
ManagedMap parent = ManagedMap.ofEntries(new SimpleEntry<>("one", "one"),
|
||||
new SimpleEntry<>("two", "two"));
|
||||
ManagedMap child = ManagedMap.ofEntries(new SimpleEntry<>("one", "fork"));
|
||||
child.setMergeEnabled(true);
|
||||
Map mergedMap = (Map) child.merge(parent);
|
||||
// child value for 'one' must override parent value...
|
||||
|
||||
+8
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,10 +34,8 @@ public class ManagedSetTests {
|
||||
|
||||
@Test
|
||||
public void mergeSunnyDay() {
|
||||
ManagedSet parent = new ManagedSet();
|
||||
parent.add("one");
|
||||
parent.add("two");
|
||||
ManagedSet child = new ManagedSet();
|
||||
ManagedSet parent = ManagedSet.of("one", "two");
|
||||
ManagedSet child = ManagedSet.of("three");
|
||||
child.add("three");
|
||||
child.setMergeEnabled(true);
|
||||
Set mergedSet = child.merge(parent);
|
||||
@@ -46,8 +44,7 @@ public class ManagedSetTests {
|
||||
|
||||
@Test
|
||||
public void mergeWithNullParent() {
|
||||
ManagedSet child = new ManagedSet();
|
||||
child.add("one");
|
||||
ManagedSet child = ManagedSet.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
assertThat(child.merge(null)).isSameAs(child);
|
||||
}
|
||||
@@ -60,8 +57,7 @@ public class ManagedSetTests {
|
||||
|
||||
@Test
|
||||
public void mergeWithNonCompatibleParentType() {
|
||||
ManagedSet child = new ManagedSet();
|
||||
child.add("one");
|
||||
ManagedSet child = ManagedSet.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
child.merge("hello"));
|
||||
@@ -69,9 +65,7 @@ public class ManagedSetTests {
|
||||
|
||||
@Test
|
||||
public void mergeEmptyChild() {
|
||||
ManagedSet parent = new ManagedSet();
|
||||
parent.add("one");
|
||||
parent.add("two");
|
||||
ManagedSet parent = ManagedSet.of("one", "two");
|
||||
ManagedSet child = new ManagedSet();
|
||||
child.setMergeEnabled(true);
|
||||
Set mergedSet = child.merge(parent);
|
||||
@@ -81,11 +75,8 @@ public class ManagedSetTests {
|
||||
@Test
|
||||
public void mergeChildValuesOverrideTheParents() {
|
||||
// asserts that the set contract is not violated during a merge() operation...
|
||||
ManagedSet parent = new ManagedSet();
|
||||
parent.add("one");
|
||||
parent.add("two");
|
||||
ManagedSet child = new ManagedSet();
|
||||
child.add("one");
|
||||
ManagedSet parent = ManagedSet.of("one", "two");
|
||||
ManagedSet child = ManagedSet.of("one");
|
||||
child.setMergeEnabled(true);
|
||||
Set mergedSet = child.merge(parent);
|
||||
assertThat(mergedSet.size()).as("merge() obviously did not work.").isEqualTo(2);
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -449,7 +449,7 @@ public class CallbacksSecurityTests {
|
||||
public Object run() {
|
||||
// sanity check
|
||||
assertThat(getCurrentSubjectName()).isEqualTo("user1");
|
||||
assertThat(NonPrivilegedBean.destroyed).isEqualTo(false);
|
||||
assertThat(NonPrivilegedBean.destroyed).isFalse();
|
||||
|
||||
beanFactory.getBean("trusted-spring-callbacks");
|
||||
beanFactory.getBean("trusted-custom-init-destroy");
|
||||
@@ -465,7 +465,7 @@ public class CallbacksSecurityTests {
|
||||
beanFactory.getBean("trusted-working-property-injection");
|
||||
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(NonPrivilegedBean.destroyed).isEqualTo(true);
|
||||
assertThat(NonPrivilegedBean.destroyed).isTrue();
|
||||
return null;
|
||||
}
|
||||
}, provider.getAccessControlContext());
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
@@ -27,4 +28,5 @@ public class CustomCallbackBean {
|
||||
public void destroy() {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
@@ -26,4 +27,5 @@ public class DestroyBean implements DisposableBean {
|
||||
public void destroy() throws Exception {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
@@ -33,4 +34,5 @@ public class FactoryBean {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
@@ -26,4 +27,5 @@ public class InitBean implements InitializingBean {
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
@@ -27,4 +28,5 @@ public class PropertyBean {
|
||||
public void setProperty(Object property) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -100,17 +100,17 @@ public class FactoryMethodTests {
|
||||
|
||||
FactoryMethods fm = (FactoryMethods) xbf.getBean("fullWithNull");
|
||||
assertThat(fm.getNum()).isEqualTo(27);
|
||||
assertThat(fm.getName()).isEqualTo(null);
|
||||
assertThat(fm.getName()).isNull();
|
||||
assertThat(fm.getTestBean().getName()).isEqualTo("Juergen");
|
||||
|
||||
fm = (FactoryMethods) xbf.getBean("fullWithGenericNull");
|
||||
assertThat(fm.getNum()).isEqualTo(27);
|
||||
assertThat(fm.getName()).isEqualTo(null);
|
||||
assertThat(fm.getName()).isNull();
|
||||
assertThat(fm.getTestBean().getName()).isEqualTo("Juergen");
|
||||
|
||||
fm = (FactoryMethods) xbf.getBean("fullWithNamedNull");
|
||||
assertThat(fm.getNum()).isEqualTo(27);
|
||||
assertThat(fm.getName()).isEqualTo(null);
|
||||
assertThat(fm.getName()).isNull();
|
||||
assertThat(fm.getTestBean().getName()).isEqualTo("Juergen");
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -342,7 +342,7 @@ public class UtilNamespaceHandlerTests {
|
||||
public void testLoadProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo(null);
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isNull();
|
||||
Properties props2 = (Properties) this.beanFactory.getBean("myProperties");
|
||||
assertThat(props == props2).isTrue();
|
||||
}
|
||||
@@ -351,17 +351,17 @@ public class UtilNamespaceHandlerTests {
|
||||
public void testScopedProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myScopedProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo(null);
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isNull();
|
||||
Properties props2 = (Properties) this.beanFactory.getBean("myScopedProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo("bar");
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo(null);
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isNull();
|
||||
assertThat(props != props2).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myLocalProperties");
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isEqualTo(null);
|
||||
assertThat(props.get("foo")).as("Incorrect property value").isNull();
|
||||
assertThat(props.get("foo2")).as("Incorrect property value").isEqualTo("bar2");
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -283,7 +283,7 @@ public class XmlBeanCollectionTests {
|
||||
Iterator it = hasMap.getSet().iterator();
|
||||
assertThat(it.next()).isEqualTo("bar");
|
||||
assertThat(it.next()).isEqualTo(jenny);
|
||||
assertThat(it.next()).isEqualTo(null);
|
||||
assertThat(it.next()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -181,7 +181,7 @@ public class XmlListableBeanFactoryTests extends AbstractListableBeanFactoryTest
|
||||
assertThat(beanNames.contains("aliasWithoutId3")).isFalse();
|
||||
|
||||
TestBean tb4 = (TestBean) getBeanFactory().getBean(TestBean.class.getName() + "#0");
|
||||
assertThat(tb4.getName()).isEqualTo(null);
|
||||
assertThat(tb4.getName()).isNull();
|
||||
|
||||
Map drs = getListableBeanFactory().getBeansOfType(DummyReferencer.class, false, false);
|
||||
assertThat(drs.size()).isEqualTo(5);
|
||||
|
||||
+5
-1
@@ -16,9 +16,11 @@
|
||||
|
||||
package org.springframework.beans.factory
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.reflect.full.createInstance
|
||||
|
||||
/**
|
||||
* Mock object based tests for ListableBeanFactory Kotlin extensions
|
||||
@@ -77,10 +79,12 @@ class ListableBeanFactoryExtensionsTests {
|
||||
verify { lbf.getBeansWithAnnotation(Bar::class.java) }
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
@Test
|
||||
fun `findAnnotationOnBean with String and reified type parameters`() {
|
||||
val name = "bar"
|
||||
lbf.findAnnotationOnBean<Bar>(name)
|
||||
every { lbf.findAnnotationOnBean(name, Bar::class.java) } returns Bar::class.createInstance()
|
||||
val annotation: Bar? = lbf.findAnnotationOnBean(name)
|
||||
verify { lbf.findAnnotationOnBean(name, Bar::class.java) }
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user