mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
357 Commits
main
...
v4.0.9.RELEASE
| Author | SHA1 | Date | |
|---|---|---|---|
| d820f5e410 | |||
| 8575533081 | |||
| 5528c8a93b | |||
| c9912f0d2d | |||
| 8e14a5d640 | |||
| 230aa07fbb | |||
| b9aa471def | |||
| 39fbfbd343 | |||
| e9d24d5336 | |||
| 4a27a98702 | |||
| 929c596b55 | |||
| 9362d0d547 | |||
| 37713ae9dd | |||
| e118086bd1 | |||
| 0c7fa9e786 | |||
| dc15070877 | |||
| 61a6bc0139 | |||
| c087e51b80 | |||
| 9cb1569e67 | |||
| ac5c361688 | |||
| 328ba7b6d4 | |||
| d97add075a | |||
| c8ff562d1f | |||
| 1d6978afd5 | |||
| 4660e61cf9 | |||
| dfc79721cb | |||
| 90ae073854 | |||
| 50c578c5a0 | |||
| c89d8ec382 | |||
| 7e07f3d083 | |||
| e039185fec | |||
| b45f1aa26f | |||
| 054464709f | |||
| 5ac868036f | |||
| 58bea23f1d | |||
| 98569045cb | |||
| c2ffbf28c5 | |||
| a5e2afc980 | |||
| 5be50c8e5e | |||
| 1214624265 | |||
| 493e8463fa | |||
| 6d3a0d5735 | |||
| 5f58cd3b79 | |||
| 8854c33bf7 | |||
| f093a5f749 | |||
| 1f45dd297d | |||
| 21b8ce5284 | |||
| 2490d1b38d | |||
| ffa4736895 | |||
| 9beae9ae42 | |||
| e42e2330b3 | |||
| b331d65019 | |||
| 1823ce1fad | |||
| 2d0a677117 | |||
| a09bc9b1c1 | |||
| 260b451d5f | |||
| acefd8381d | |||
| 7fa3e65d04 | |||
| 329ba2a913 | |||
| f691618967 | |||
| fde0713a94 | |||
| 4729483804 | |||
| d3ec48f490 | |||
| 2d874d724b | |||
| 91940f212e | |||
| de8645b30c | |||
| c8b8dc5f97 | |||
| aa82da8507 | |||
| 16a4fe70f2 | |||
| 6117311906 | |||
| 6e5711a7fb | |||
| 15c8987cc4 | |||
| 0e907764a4 | |||
| a305bf7ad1 | |||
| e16f21c281 | |||
| 7507560e75 | |||
| a1c0905a7c | |||
| 6f9d7da59e | |||
| 47ed4d634b | |||
| da2c30cd0c | |||
| a7eeedaf6a | |||
| 578c3dd853 | |||
| 9758bc7833 | |||
| c672678423 | |||
| ac4103d1b9 | |||
| d23b033f61 | |||
| c74bad6e07 | |||
| f41e0bc796 | |||
| c7b6b72e73 | |||
| 1df8133237 | |||
| 43d40187d9 | |||
| b91cab1fde | |||
| d46c3fc7bf | |||
| 3267e5aa33 | |||
| 251970a2f9 | |||
| 901346eb7d | |||
| 1ffefcb548 | |||
| 0c680d6d03 | |||
| b87329cda7 | |||
| f21c8c37fb | |||
| 50e50d0c18 | |||
| 205e681295 | |||
| 29abca5399 | |||
| 60d5ff8dd5 | |||
| d2e8b7e6ee | |||
| 7d55715213 | |||
| d07230cf6a | |||
| bf881e4544 | |||
| 36a1d6242e | |||
| 10d4888408 | |||
| f8b729aa5f | |||
| b39e66b897 | |||
| 64849a46b4 | |||
| afb0342924 | |||
| bea9f3ff76 | |||
| 31094f3ef6 | |||
| d765698ac3 | |||
| d081a4530c | |||
| 97bd0ccfec | |||
| 8543a5548e | |||
| d2ef6dcb8d | |||
| bff2bf2cdb | |||
| 72d62a7113 | |||
| e1a01d4c3c | |||
| b7726ff48c | |||
| a52ff46fea | |||
| eb3509a37c | |||
| 93ad7f8def | |||
| 54ba5c5e7b | |||
| 249c688e9b | |||
| e324c2ab4a | |||
| 39a23660fa | |||
| 25971d9927 | |||
| 379e5abd83 | |||
| 8fb7b694dd | |||
| 21d0ce5af8 | |||
| fb452fad7c | |||
| 2dd2b7175f | |||
| f418e6e981 | |||
| 5e2b9b6f07 | |||
| a95a3ae4ec | |||
| 0c0d23d0f4 | |||
| a31ebb6c1e | |||
| 42c090efa4 | |||
| 035a9b91d2 | |||
| a7492fa55b | |||
| ecf23ff6cd | |||
| 4129f00a02 | |||
| e2d71a8ccd | |||
| 1034b0dae2 | |||
| c08ded769a | |||
| d61353db51 | |||
| 96efafef97 | |||
| fbf24a927d | |||
| f2eea9d911 | |||
| cac0683dab | |||
| 9ad6618207 | |||
| 84a4433898 | |||
| 44fac40a2f | |||
| 6e95b2613e | |||
| fca72f6b65 | |||
| 0dca31c39b | |||
| d45f743248 | |||
| acbd61b87a | |||
| dcb83c2daf | |||
| 5342d92db7 | |||
| 7af1e002bd | |||
| abd5f18e85 | |||
| 940ae0c528 | |||
| 5f77dce1ee | |||
| 0ef17a2f2c | |||
| 452260316e | |||
| c0815407bb | |||
| 845528a6cb | |||
| ed88155f55 | |||
| a3a76d8c15 | |||
| 10a039000b | |||
| 7de42efaf2 | |||
| 7dcc01e69b | |||
| adb73d5f35 | |||
| 7eee7d2e30 | |||
| d72ee809b7 | |||
| 31a251e44a | |||
| ce6adfbe35 | |||
| 60d3a7f300 | |||
| 6dbb465585 | |||
| 47de943926 | |||
| 0164f8691a | |||
| 077c624b73 | |||
| dae81fd5e6 | |||
| 837f27851f | |||
| c3b992c5c4 | |||
| f8ab4f6980 | |||
| 77406eded8 | |||
| 977c5ca439 | |||
| ede2150544 | |||
| 07edf11e21 | |||
| f27b9498be | |||
| e9ecaf6f4a | |||
| 5092414842 | |||
| 6438209557 | |||
| 7396210d40 | |||
| b9935e9fe3 | |||
| 86ea3059b6 | |||
| 4384c1ae50 | |||
| 347b7313b8 | |||
| 3fb05017a1 | |||
| 48f753f368 | |||
| c16032b98a | |||
| c32d5592c7 | |||
| 5f695a47db | |||
| 74c878ee0e | |||
| 178d58cc75 | |||
| 7b38b41bf5 | |||
| 6403479902 | |||
| 5af1a691bc | |||
| 9f967b1d81 | |||
| e50507206f | |||
| c73ac075c4 | |||
| 0bf0901b8f | |||
| 7d94b5e853 | |||
| 8ddbbc2e67 | |||
| 0a34f86333 | |||
| a0c86ae455 | |||
| 0761ee99ae | |||
| 9054f4fb58 | |||
| 41e78d0f50 | |||
| 526d5ba253 | |||
| 40c203ca71 | |||
| d18fc53148 | |||
| 618771d59d | |||
| 87077d3fad | |||
| c0c3618906 | |||
| 0405bb401a | |||
| e3e71ba92a | |||
| d4e1b9eb4c | |||
| 44ee51a6c9 | |||
| ba6d187b5c | |||
| 54636b3f7c | |||
| 545c28fd4e | |||
| 95a7bfd327 | |||
| ccebbf74ec | |||
| c350080f99 | |||
| 6b9738fd68 | |||
| 1120680c65 | |||
| a2ef2c9d3e | |||
| 1bbc032071 | |||
| c70a81a805 | |||
| 3c709a763d | |||
| 7d78c65187 | |||
| 748167bfa3 | |||
| 3e70013b55 | |||
| ea9ad4ee9b | |||
| 482eff81e1 | |||
| c706cbbed4 | |||
| 7bc38acbf6 | |||
| 297e4eec36 | |||
| 235b65d103 | |||
| 8a28645dd6 | |||
| f94ded830d | |||
| ad8f17b6af | |||
| 261520cea0 | |||
| 00aa40b8da | |||
| ac9b64e528 | |||
| 1e7fade89e | |||
| 3c58be05a5 | |||
| ef290ff95c | |||
| ae45794451 | |||
| fccec210b4 | |||
| 96da77ef75 | |||
| c9417d0610 | |||
| 085e52fc31 | |||
| 8f175046c8 | |||
| c1dbd9f150 | |||
| 42a35ef3be | |||
| 21fd68150a | |||
| d20259be1d | |||
| 6ca921021c | |||
| eab9d24c31 | |||
| 15749c2a9d | |||
| 93b0f0b126 | |||
| 27b2ed1614 | |||
| 790d62bcb1 | |||
| 563476f57c | |||
| 79de45b805 | |||
| 63a868dafb | |||
| 1afdd9bd75 | |||
| d0c839f0eb | |||
| 744727b8aa | |||
| 9fbb7394e2 | |||
| 80cb0c4e5b | |||
| 5c4804f4a4 | |||
| a679f3e7a3 | |||
| bd5b3749c5 | |||
| 89398b0811 | |||
| a87c9b8c5c | |||
| d0f9853769 | |||
| bed739ce92 | |||
| cb712afa97 | |||
| c97c246940 | |||
| 4196e6c96f | |||
| 59cef3ce81 | |||
| c8ea80d7ed | |||
| 656fc52ff9 | |||
| a4d6f8473e | |||
| 443fb8e4ee | |||
| 95b1cb7173 | |||
| 51fb485181 | |||
| f16e6c4105 | |||
| 4dbc0c296c | |||
| d71d38bfaf | |||
| eb28259371 | |||
| 7ae6a60f43 | |||
| d3c9a31e9a | |||
| 5aa126600f | |||
| 2f15f72fcc | |||
| d5aacdefd9 | |||
| e379e77b96 | |||
| 9c45755890 | |||
| 5962fc2590 | |||
| 1b59b4eb26 | |||
| f6b89c2ca9 | |||
| 82c32db5a1 | |||
| 52f580149f | |||
| 271fe4f554 | |||
| 02e8198283 | |||
| 090ab4bb6d | |||
| 18ef1d4f76 | |||
| d9cb44527c | |||
| 8e44521ec4 | |||
| d28c6d8bdb | |||
| c9432ce499 | |||
| 2d8e0c8f87 | |||
| 03ae8eeb95 | |||
| 9230b38aea | |||
| d5ce30f360 | |||
| 428aee5b72 | |||
| f7a17added | |||
| 196f629a20 | |||
| 7135e729e2 | |||
| 21874627d2 | |||
| 3ab88b857b | |||
| 294545d07a | |||
| 38cd79047a | |||
| 8a779c32d5 | |||
| 7ba31dee45 | |||
| 1c45d7573c | |||
| f014bbb5cf | |||
| d1030b798d | |||
| d628025f13 | |||
| 30ea1a3475 | |||
| 7b014eaa55 | |||
| e21c47d4ce | |||
| 632ae6a4df | |||
| 989f6194b6 | |||
| 17bf5b991f | |||
| cd9d7cfe4f |
+120
-98
@@ -1,36 +1,45 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url "http://repo.springsource.org/plugins-release" }
|
||||
maven { url "https://repo.spring.io/plugins-release" }
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.5")
|
||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
|
||||
classpath("org.asciidoctor:asciidoctor-gradle-plugin:0.7.0")
|
||||
classpath("org.springframework.build.gradle:docbook-reference-plugin:0.2.8")
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
moduleProjects = subprojects.findAll {
|
||||
!it.name.equals('spring-build-src') && !it.name.equals('spring-framework-bom')
|
||||
}
|
||||
}
|
||||
|
||||
configure(allprojects) { project ->
|
||||
group = "org.springframework"
|
||||
version = qualifyVersionIfNecessary(version)
|
||||
|
||||
ext.aspectjVersion = "1.7.4"
|
||||
ext.aspectjVersion = "1.8.4"
|
||||
ext.eclipseLinkVersion = "2.4.2"
|
||||
ext.groovyVersion = "1.8.9"
|
||||
ext.hibernate3Version = "3.6.10.Final"
|
||||
ext.hibernate4Version = "4.2.11.Final"
|
||||
ext.hibValVersion = "4.3.1.Final"
|
||||
ext.hibernate4Version = "4.2.16.Final"
|
||||
ext.hibVal4Version = "4.3.2.Final"
|
||||
ext.hsqldbVersion = "2.3.2"
|
||||
ext.jackson1Version = "1.9.13"
|
||||
ext.jackson2Version = "2.3.1"
|
||||
ext.jackson2Version = "2.3.4"
|
||||
ext.jasperReportsVersion = "5.5.1"
|
||||
ext.jettyVersion = "9.1.3.v20140225"
|
||||
ext.jettyVersion = "9.1.5.v20140505"
|
||||
ext.jodaVersion = "2.3"
|
||||
ext.junitVersion = "4.11"
|
||||
ext.slf4jVersion = "1.7.6"
|
||||
ext.openJpaVersion = "2.2.2"
|
||||
ext.slf4jVersion = "1.7.9"
|
||||
ext.tiles2Version = "2.2.2"
|
||||
ext.tiles3Version = "3.0.3"
|
||||
ext.tiles3Version = "3.0.5"
|
||||
ext.tomcatVersion = "8.0.15"
|
||||
ext.xstreamVersion = "1.4.7"
|
||||
|
||||
ext.gradleScriptDir = "${rootProject.projectDir}/gradle"
|
||||
ext.gradleScriptDir = "${rootProject.projectDir}/gradle"
|
||||
|
||||
apply plugin: "propdeps"
|
||||
apply plugin: "java"
|
||||
@@ -71,14 +80,12 @@ configure(allprojects) { project ->
|
||||
include(["**/*Tests.class", "**/*Test.class"])
|
||||
// Since we set scanForTestClasses to false, we need to filter out inner
|
||||
// classes with the "$" pattern; otherwise, using -Dtest.single=MyTests to
|
||||
// run MyTests by itself will fail if MyTests contains any inner classes.
|
||||
// run MyTests by itself will fail if MyTests contains any inner classes.
|
||||
exclude(["**/Abstract*.class", '**/*$*'])
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url "http://repo.spring.io/libs-release" }
|
||||
maven { url "http://repo.spring.io/milestone" } // for AspectJ 1.8.0.M1
|
||||
maven { url "https://oss.sonatype.org/content/repositories/releases" } // javax.cache
|
||||
maven { url "https://repo.spring.io/libs-release" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -93,7 +100,7 @@ configure(allprojects) { project ->
|
||||
|
||||
ext.javadocLinks = [
|
||||
"http://docs.oracle.com/javase/7/docs/api/",
|
||||
"http://docs.oracle.com/javaee/6/api/",
|
||||
"http://docs.oracle.com/javaee/7/api/",
|
||||
"http://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
|
||||
"http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/",
|
||||
"http://glassfish.java.net/nonav/docs/v3/api/",
|
||||
@@ -108,7 +115,7 @@ configure(allprojects) { project ->
|
||||
"http://aopalliance.sourceforge.net/doc/",
|
||||
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
|
||||
"http://ehcache.org/apidocs/",
|
||||
"http://quartz-scheduler.org/api/2.1.7/",
|
||||
"http://quartz-scheduler.org/api/2.2.0/",
|
||||
"http://jackson.codehaus.org/1.9.4/javadoc/",
|
||||
"http://fasterxml.github.com/jackson-core/javadoc/2.3.0/",
|
||||
"http://fasterxml.github.com/jackson-databind/javadoc/2.3.0/",
|
||||
@@ -149,10 +156,10 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
|
||||
logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn:classes) {
|
||||
classifier = "sources"
|
||||
from sourceSets.main.allJava.srcDirs
|
||||
include "**/*.java", "**/*.aj"
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
// don't include or exclude anything explicitly by default. See SPR-12085.
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
@@ -279,7 +286,7 @@ project("spring-beans") {
|
||||
compile(project(":spring-core"))
|
||||
compile(files(project(":spring-core").cglibRepackJar))
|
||||
optional("javax.inject:javax.inject:1")
|
||||
optional("javax.el:javax.el-api:2.2.4")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
}
|
||||
}
|
||||
@@ -371,12 +378,12 @@ project("spring-context") {
|
||||
optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0")
|
||||
optional("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
optional("javax.validation:validation-api:1.0.0.GA")
|
||||
optional("org.hibernate:hibernate-validator:${hibValVersion}")
|
||||
optional("org.hibernate:hibernate-validator:${hibVal4Version}")
|
||||
optional("joda-time:joda-time:${jodaVersion}")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
optional("org.beanshell:bsh:2.0b4")
|
||||
optional("org.jruby:jruby:1.7.10")
|
||||
optional("org.jruby:jruby:1.7.17")
|
||||
testCompile("javax.inject:javax.inject-tck:1")
|
||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
|
||||
@@ -397,7 +404,8 @@ project("spring-messaging") {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
compile(project(":spring-context"))
|
||||
optional("org.projectreactor:reactor-core:1.0.1.RELEASE")
|
||||
optional("org.projectreactor:reactor-core:1.1.5.RELEASE")
|
||||
optional("org.projectreactor:reactor-net:1.1.5.RELEASE")
|
||||
optional("org.projectreactor:reactor-tcp:1.0.1.RELEASE")
|
||||
optional("org.eclipse.jetty.websocket:websocket-server:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet-api"
|
||||
@@ -417,9 +425,9 @@ project("spring-messaging") {
|
||||
testCompile("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet-api"
|
||||
}
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:8.0.3")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:8.0.3")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:8.0.3")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}")
|
||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
@@ -433,7 +441,7 @@ project("spring-tx") {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
optional(project(":spring-aop"))
|
||||
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
|
||||
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
optional("javax.transaction:javax.transaction-api:1.2")
|
||||
optional("javax.resource:connector-api:1.5")
|
||||
@@ -458,8 +466,9 @@ project("spring-oxm") {
|
||||
dependencies {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
optional("org.codehaus.castor:castor-xml:1.3.2") {
|
||||
optional("org.codehaus.castor:castor-xml:1.3.3") {
|
||||
exclude group: 'stax', module: 'stax-api'
|
||||
exclude group: "org.springframework", module: "spring-context"
|
||||
}
|
||||
optional("org.apache.xmlbeans:xmlbeans:2.6.0") {
|
||||
exclude group: 'stax', module: 'stax-api'
|
||||
@@ -507,13 +516,13 @@ project("spring-jdbc") {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
compile(project(":spring-tx"))
|
||||
optional(project(":spring-context")) // for JndiDataSourceLookup
|
||||
optional(project(":spring-context")) // for JndiDataSourceLookup
|
||||
optional("javax.transaction:javax.transaction-api:1.2")
|
||||
optional("c3p0:c3p0:0.9.1.2")
|
||||
optional("com.mchange:c3p0:0.9.2.1")
|
||||
optional("org.hsqldb:hsqldb:${hsqldbVersion}")
|
||||
optional("com.h2database:h2:1.0.71")
|
||||
optional("org.apache.derby:derby:10.10.1.1")
|
||||
optional("org.apache.derby:derbyclient:10.10.1.1")
|
||||
optional("com.h2database:h2:1.3.176")
|
||||
optional("org.apache.derby:derby:10.10.2.0")
|
||||
optional("org.apache.derby:derbyclient:10.10.2.0")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,12 +533,12 @@ project("spring-context-support") {
|
||||
compile(project(":spring-core"))
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-context"))
|
||||
optional(project(":spring-jdbc")) // for Quartz support
|
||||
optional(project(":spring-tx")) // for Quartz support
|
||||
optional("javax.mail:mail:1.4.7")
|
||||
optional("javax.cache:cache-api:1.0.0-RC1")
|
||||
optional("com.google.guava:guava:16.0.1")
|
||||
optional("net.sf.ehcache:ehcache-core:2.6.5")
|
||||
optional(project(":spring-jdbc")) // for Quartz support
|
||||
optional(project(":spring-tx")) // for Quartz support
|
||||
optional("javax.mail:javax.mail-api:1.4.7")
|
||||
optional("javax.cache:cache-api:1.0.0")
|
||||
optional("com.google.guava:guava:17.0")
|
||||
optional("net.sf.ehcache:ehcache-core:2.6.7")
|
||||
optional("org.quartz-scheduler:quartz:1.8.6") {
|
||||
exclude group: "org.slf4j", module: "slf4j-log4j12"
|
||||
}
|
||||
@@ -537,12 +546,15 @@ project("spring-context-support") {
|
||||
optional("org.apache.velocity:velocity:1.7")
|
||||
optional("org.freemarker:freemarker:2.3.20")
|
||||
optional("com.lowagie:itext:2.1.7")
|
||||
optional("net.sf.jasperreports:jasperreports:$jasperReportsVersion")
|
||||
testCompile("org.apache.poi:poi:3.9")
|
||||
testCompile("commons-beanutils:commons-beanutils:1.8.0") // for Velocity/JasperReports
|
||||
testCompile("commons-digester:commons-digester:1.8.1") // for Velocity/JasperReports
|
||||
optional("net.sf.jasperreports:jasperreports:$jasperReportsVersion") {
|
||||
exclude group: "xml-apis", module: "xml-apis"
|
||||
}
|
||||
testCompile("org.apache.poi:poi:3.10.1")
|
||||
testCompile("commons-beanutils:commons-beanutils:1.8.0") // for Velocity/JasperReports
|
||||
testCompile("commons-digester:commons-digester:1.8.1") // for Velocity/JasperReports
|
||||
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
|
||||
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
|
||||
testRuntime("com.sun.mail:javax.mail:1.4.7")
|
||||
}
|
||||
|
||||
// pick up **/*.types files in src/main
|
||||
@@ -553,25 +565,24 @@ project("spring-web") {
|
||||
description = "Spring Web"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
|
||||
compile(project(":spring-beans")) // for MultiPartFilter
|
||||
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
|
||||
compile(project(":spring-beans")) // for MultipartFilter
|
||||
compile(project(":spring-context"))
|
||||
compile(project(":spring-core"))
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional(project(":spring-oxm")) // for MarshallingHttpMessageConverter
|
||||
optional("javax.servlet.jsp:jsp-api:2.2")
|
||||
optional(project(":spring-oxm")) // for MarshallingHttpMessageConverter
|
||||
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
|
||||
optional("javax.portlet:portlet-api:2.0")
|
||||
optional("javax.el:javax.el-api:2.2.4")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("javax.faces:javax.faces-api:2.2")
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
optional("com.caucho:hessian:4.0.7")
|
||||
optional("commons-fileupload:commons-fileupload:1.3.1")
|
||||
optional("org.apache.httpcomponents:httpclient:4.3.3")
|
||||
optional("org.apache.httpcomponents:httpasyncclient:4.0.1")
|
||||
optional("org.apache.httpcomponents:httpclient:4.3.6")
|
||||
optional("org.apache.httpcomponents:httpasyncclient:4.0.2")
|
||||
optional("org.codehaus.jackson:jackson-mapper-asl:${jackson1Version}")
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
optional("rome:rome:1.0")
|
||||
optional("taglibs:standard:1.1.2")
|
||||
optional("org.eclipse.jetty:jetty-servlet:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet-api"
|
||||
}
|
||||
@@ -582,6 +593,9 @@ project("spring-web") {
|
||||
testCompile(project(":spring-context-support")) // for JafMediaTypeFactory
|
||||
testCompile("xmlunit:xmlunit:1.5")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
testCompile("org.apache.taglibs:taglibs-standard-jstlel:1.2.1") {
|
||||
exclude group: "org.apache.taglibs", module: "taglibs-standard-spec"
|
||||
}
|
||||
}
|
||||
|
||||
// pick up ContextLoader.properties in src/main
|
||||
@@ -599,7 +613,7 @@ project("spring-websocket") {
|
||||
optional(project(":spring-webmvc"))
|
||||
optional("javax.servlet:javax.servlet-api:3.1.0")
|
||||
optional("javax.websocket:javax.websocket-api:1.0")
|
||||
optional("org.apache.tomcat:tomcat-websocket:8.0.3") {
|
||||
optional("org.apache.tomcat:tomcat-websocket:${tomcatVersion}") {
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-websocket-api"
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-servlet-api"
|
||||
}
|
||||
@@ -612,20 +626,20 @@ project("spring-websocket") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
|
||||
optional("io.undertow:undertow-core:1.0.0.Final")
|
||||
optional("io.undertow:undertow-servlet:1.0.0.Final") {
|
||||
optional("io.undertow:undertow-core:1.0.1.Final")
|
||||
optional("io.undertow:undertow-servlet:1.0.1.Final") {
|
||||
exclude group: "org.jboss.spec.javax.servlet", module: "jboss-servlet-api_3.1_spec"
|
||||
exclude group: "org.jboss.spec.javax.annotation", module: "jboss-annotations-api_1.2_spec"
|
||||
}
|
||||
optional("io.undertow:undertow-websockets-jsr:1.0.0.Final") {
|
||||
optional("io.undertow:undertow-websockets-jsr:1.0.1.Final") {
|
||||
exclude group: "org.jboss.spec.javax.websocket", module: "jboss-websocket-api_1.0_spec"
|
||||
}
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:8.0.3")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:8.0.3")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:8.0.3")
|
||||
testCompile("org.projectreactor:reactor-core:1.0.1.RELEASE")
|
||||
testCompile("org.projectreactor:reactor-tcp:1.0.1.RELEASE")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}")
|
||||
testCompile("org.projectreactor:reactor-core:1.1.4.RELEASE")
|
||||
testCompile("org.projectreactor:reactor-net:1.1.4.RELEASE")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
}
|
||||
@@ -643,9 +657,9 @@ project("spring-orm") {
|
||||
optional(project(":spring-context"))
|
||||
optional(project(":spring-web"))
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
optional("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
optional("org.eclipse.persistence:org.eclipse.persistence.core:2.4.0")
|
||||
optional("org.eclipse.persistence:org.eclipse.persistence.jpa:2.4.0") {
|
||||
optional("org.eclipse.persistence:javax.persistence:2.0.5")
|
||||
optional("org.eclipse.persistence:org.eclipse.persistence.core:${eclipseLinkVersion}")
|
||||
optional("org.eclipse.persistence:org.eclipse.persistence.jpa:${eclipseLinkVersion}") {
|
||||
exclude group: 'org.eclipse.persistence', module: 'javax.persistence'
|
||||
}
|
||||
optional("org.hibernate:hibernate-core:${hibernate3Version}") {
|
||||
@@ -655,13 +669,13 @@ project("spring-orm") {
|
||||
optional("org.hibernate:hibernate-entitymanager:${hibernate3Version}") {
|
||||
exclude group: 'org.hibernate.javax.persistence', module: 'hibernate-jpa-2.0-api'
|
||||
}
|
||||
optional("org.apache.openjpa:openjpa:2.2.1") {
|
||||
optional("org.apache.openjpa:openjpa:${openJpaVersion}") {
|
||||
exclude group: 'junit', module: 'junit'
|
||||
exclude group: 'org.apache.geronimo.specs', module: 'geronimo-jpa_2.0_spec'
|
||||
exclude group: 'org.apache.geronimo.specs', module: 'geronimo-jta_1.1_spec'
|
||||
exclude group: 'org.apache.geronimo.specs', module: 'geronimo-jms_1.1_spec'
|
||||
}
|
||||
optional("javax.jdo:jdo-api:3.0") {
|
||||
optional("javax.jdo:jdo-api:3.0.1") {
|
||||
exclude group: 'javax.transaction', module: 'transaction-api'
|
||||
}
|
||||
optional("javax.servlet:javax.servlet-api:3.0.1")
|
||||
@@ -682,6 +696,7 @@ project("spring-orm-hibernate4") {
|
||||
optional("org.hibernate:hibernate-core:${hibernate4Version}")
|
||||
optional("org.hibernate:hibernate-entitymanager:${hibernate4Version}")
|
||||
optional("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,12 +711,12 @@ project("spring-webmvc") {
|
||||
compile(project(":spring-expression"))
|
||||
compile(project(":spring-web"))
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional(project(":spring-context-support")) // for Velocity support
|
||||
optional(project(":spring-oxm")) // for MarshallingView
|
||||
optional("javax.servlet.jsp:jsp-api:2.2")
|
||||
optional("javax.servlet:jstl:1.2")
|
||||
optional(project(":spring-context-support")) // for Velocity support
|
||||
optional(project(":spring-oxm")) // for MarshallingView
|
||||
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
|
||||
optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1")
|
||||
optional("net.sourceforge.jexcelapi:jxl:2.6.12")
|
||||
optional("org.apache.poi:poi:3.9")
|
||||
optional("org.apache.poi:poi:3.10.1")
|
||||
optional("org.apache.velocity:velocity:1.7")
|
||||
optional("velocity-tools:velocity-tools-view:1.4")
|
||||
optional("org.freemarker:freemarker:2.3.20")
|
||||
@@ -748,8 +763,8 @@ project("spring-webmvc") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
testCompile("javax.validation:validation-api:1.0.0.GA")
|
||||
testCompile("org.hibernate:hibernate-validator:${hibValVersion}")
|
||||
testCompile("org.apache.httpcomponents:httpclient:4.3.3")
|
||||
testCompile("org.hibernate:hibernate-validator:${hibVal4Version}")
|
||||
testCompile("org.apache.httpcomponents:httpclient:4.3.6")
|
||||
testCompile("commons-fileupload:commons-fileupload:1.3.1")
|
||||
testCompile("commons-io:commons-io:1.3")
|
||||
testCompile("joda-time:joda-time:${jodaVersion}")
|
||||
@@ -768,9 +783,9 @@ project("spring-webmvc-tiles3") {
|
||||
provided(project(":spring-context"))
|
||||
provided(project(":spring-web"))
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional("javax.servlet.jsp:jsp-api:2.2")
|
||||
optional("javax.servlet:jstl:1.2")
|
||||
optional("javax.el:javax.el-api:2.2.4")
|
||||
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
|
||||
optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("org.apache.tiles:tiles-api:${tiles3Version}")
|
||||
optional("org.apache.tiles:tiles-core:${tiles3Version}") {
|
||||
exclude group: "org.slf4j", module: "jcl-over-slf4j"
|
||||
@@ -827,25 +842,28 @@ project("spring-test") {
|
||||
optional("org.testng:testng:6.8.8")
|
||||
optional("javax.inject:javax.inject:1")
|
||||
optional("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional("javax.servlet.jsp:jsp-api:2.2")
|
||||
optional("javax.servlet:jstl:1.2")
|
||||
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
|
||||
optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1")
|
||||
optional("org.apache.taglibs:taglibs-standard-jstlel:1.2.1") {
|
||||
exclude group: "org.apache.taglibs", module: "taglibs-standard-spec"
|
||||
}
|
||||
optional("javax.portlet:portlet-api:2.0")
|
||||
optional("javax.el:javax.el-api:2.2.4")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.hamcrest:hamcrest-core:1.3")
|
||||
optional("com.jayway.jsonpath:json-path:0.9.0")
|
||||
optional("com.jayway.jsonpath:json-path:0.9.1")
|
||||
optional("xmlunit:xmlunit:1.5")
|
||||
testCompile(project(":spring-context-support"))
|
||||
testCompile(project(":spring-oxm"))
|
||||
testCompile(project(":spring-webmvc-tiles3"))
|
||||
testCompile("javax.mail:mail:1.4.7")
|
||||
testCompile("javax.mail:javax.mail-api:1.4.7")
|
||||
testCompile("javax.ejb:ejb-api:3.0")
|
||||
testCompile("org.hibernate:hibernate-core:${hibernate3Version}") {
|
||||
exclude group: 'org.hibernate.javax.persistence', module: 'hibernate-jpa-2.0-api'
|
||||
}
|
||||
testCompile("org.hibernate:hibernate-entitymanager:${hibernate3Version}")
|
||||
testCompile("org.hibernate:hibernate-validator:${hibValVersion}")
|
||||
testCompile("org.hibernate:hibernate-validator:${hibVal4Version}")
|
||||
testCompile("com.thoughtworks.xstream:xstream:${xstreamVersion}")
|
||||
testCompile("org.codehaus.jackson:jackson-mapper-asl:${jackson1Version}")
|
||||
testCompile("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
@@ -862,7 +880,9 @@ project("spring-test") {
|
||||
}
|
||||
|
||||
task testNG(type: Test) {
|
||||
description = 'Runs TestNG tests.'
|
||||
useTestNG()
|
||||
scanForTestClasses = false
|
||||
include(["**/testng/**/*Tests.class", "**/testng/**/*Test.class"])
|
||||
// Show STD_OUT & STD_ERR of the test JVM(s) on the console:
|
||||
// testLogging.showStandardStreams = true
|
||||
@@ -870,12 +890,14 @@ project("spring-test") {
|
||||
}
|
||||
|
||||
test {
|
||||
description = 'Runs JUnit tests.'
|
||||
dependsOn testNG
|
||||
useJUnit()
|
||||
exclude "**/testng/**/*.*"
|
||||
}
|
||||
|
||||
task aggregateTestReports(type: TestReport) {
|
||||
description = 'Aggregates JUnit and TestNG test reports.'
|
||||
destinationDir = test.reports.html.destination
|
||||
reportOn test, testNG
|
||||
}
|
||||
@@ -889,19 +911,19 @@ project("spring-aspects") {
|
||||
|
||||
dependencies {
|
||||
aspects(project(":spring-orm"))
|
||||
ajc("org.aspectj:aspectjtools:1.8.0.RC2") // needed for ajc on JDK 8 only
|
||||
rt("org.aspectj:aspectjrt:1.8.0.RC2") // needed for ajc on JDK 8 only
|
||||
compile("org.aspectj:aspectjweaver:${aspectjVersion}") // exposing regular AspectJ version to users
|
||||
ajc("org.aspectj:aspectjtools:${aspectjVersion}")
|
||||
rt("org.aspectj:aspectjrt:${aspectjVersion}")
|
||||
compile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
provided("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
optional(project(":spring-aop")) // for @Async support
|
||||
optional(project(":spring-beans")) // for @Configurable support
|
||||
optional(project(":spring-context")) // for @Enable* support
|
||||
optional(project(":spring-context-support")) // for JavaMail support
|
||||
optional(project(":spring-orm")) // for JPA exception translation support
|
||||
optional(project(":spring-tx")) // for JPA, @Transactional support
|
||||
testCompile(project(":spring-core")) // for CodeStyleAspect
|
||||
optional(project(":spring-aop")) // for @Async support
|
||||
optional(project(":spring-beans")) // for @Configurable support
|
||||
optional(project(":spring-context")) // for @Enable* support
|
||||
optional(project(":spring-context-support")) // for JavaMail support
|
||||
optional(project(":spring-orm")) // for JPA exception translation support
|
||||
optional(project(":spring-tx")) // for JPA, @Transactional support
|
||||
testCompile(project(":spring-core")) // for CodeStyleAspect
|
||||
testCompile(project(":spring-test"))
|
||||
testCompile("javax.mail:mail:1.4.7")
|
||||
testCompile("javax.mail:javax.mail-api:1.4.7")
|
||||
}
|
||||
|
||||
eclipse.project {
|
||||
@@ -1075,8 +1097,8 @@ configure(rootProject) {
|
||||
classifier = "schema"
|
||||
description = "Builds -${classifier} archive containing all " +
|
||||
"XSDs for deployment at http://springframework.org/schema."
|
||||
|
||||
subprojects.each { subproject ->
|
||||
duplicatesStrategy 'exclude'
|
||||
moduleProjects.each { subproject ->
|
||||
def Properties schemas = new Properties();
|
||||
|
||||
subproject.sourceSets.main.resources.find {
|
||||
@@ -1122,7 +1144,7 @@ configure(rootProject) {
|
||||
into "${baseDir}/schema"
|
||||
}
|
||||
|
||||
subprojects.each { subproject ->
|
||||
moduleProjects.each { subproject ->
|
||||
into ("${baseDir}/libs") {
|
||||
from subproject.jar
|
||||
if (subproject.tasks.findByPath("sourcesJar")) {
|
||||
@@ -1135,7 +1157,7 @@ configure(rootProject) {
|
||||
}
|
||||
}
|
||||
|
||||
// Create an distribution that contains all dependencies (required and optional).
|
||||
// Create a distribution that contains all dependencies (required and optional).
|
||||
// Not published by default; only for use when building from source.
|
||||
task depsZip(type: Zip, dependsOn: distZip) { zipTask ->
|
||||
group = "Distribution"
|
||||
@@ -1175,7 +1197,7 @@ configure(rootProject) {
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
description = "Generates gradlew[.bat] scripts"
|
||||
gradleVersion = "1.11"
|
||||
gradleVersion = "1.12"
|
||||
|
||||
doLast() {
|
||||
def gradleOpts = "-XX:MaxMetaspaceSize=1024m -Xmx1024m"
|
||||
|
||||
@@ -21,13 +21,10 @@ import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ProjectDependency;
|
||||
import org.gradle.api.artifacts.maven.Conf2ScopeMapping
|
||||
import org.gradle.api.plugins.MavenPlugin
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.plugins.ide.eclipse.EclipsePlugin
|
||||
import org.gradle.plugins.ide.eclipse.model.EclipseClasspath;
|
||||
import org.gradle.plugins.ide.idea.IdeaPlugin
|
||||
import org.gradle.api.invocation.*
|
||||
|
||||
|
||||
/**
|
||||
* Gradle plugin that allows projects to merged together. Primarily developed to
|
||||
* allow Spring to support multiple incompatible versions of third-party
|
||||
@@ -76,13 +73,13 @@ class MergePlugin implements Plugin<Project> {
|
||||
|
||||
// Hook to perform the actual merge logic
|
||||
project.afterEvaluate{
|
||||
if(it.merge.into != null) {
|
||||
if (it.merge.into != null) {
|
||||
setup(it)
|
||||
}
|
||||
}
|
||||
|
||||
// Hook to build runtimeMerge dependencies
|
||||
if(!attachedProjectsEvaluated) {
|
||||
if (!attachedProjectsEvaluated) {
|
||||
project.gradle.projectsEvaluated{
|
||||
postProcessProjects(it)
|
||||
}
|
||||
@@ -102,7 +99,7 @@ class MergePlugin implements Plugin<Project> {
|
||||
// invoking a task will invoke the task with the same name on 'into' project
|
||||
["sourcesJar", "jar", "javadocJar", "javadoc", "install", "artifactoryPublish"].each {
|
||||
def task = project.tasks.findByPath(it)
|
||||
if(task) {
|
||||
if (task) {
|
||||
task.enabled = false
|
||||
task.dependsOn(project.merge.into.tasks.findByPath(it))
|
||||
}
|
||||
@@ -120,7 +117,7 @@ class MergePlugin implements Plugin<Project> {
|
||||
private void setupMaven(Project project) {
|
||||
project.configurations.each { configuration ->
|
||||
Conf2ScopeMapping mapping = project.conf2ScopeMappings.getMapping([configuration])
|
||||
if(mapping.scope) {
|
||||
if (mapping.scope) {
|
||||
Configuration intoConfiguration = project.merge.into.configurations.create(
|
||||
project.name + "-" + configuration.name)
|
||||
configuration.excludeRules.each {
|
||||
@@ -131,7 +128,7 @@ class MergePlugin implements Plugin<Project> {
|
||||
configuration.dependencies.each {
|
||||
def intoCompile = project.merge.into.configurations.getByName("compile")
|
||||
// Protect against changing a compile scope dependency (SPR-10218)
|
||||
if(!intoCompile.dependencies.contains(it)) {
|
||||
if (!intoCompile.dependencies.contains(it)) {
|
||||
intoConfiguration.dependencies.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,6 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.ProjectDependency;
|
||||
|
||||
|
||||
/**
|
||||
* Gradle plugin that automatically updates testCompile dependencies to include
|
||||
* the test source sets of project dependencies.
|
||||
@@ -41,11 +40,10 @@ class TestSourceSetDependenciesPlugin implements Plugin<Project> {
|
||||
}
|
||||
}
|
||||
|
||||
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies,
|
||||
Project project) {
|
||||
for(def configurationName in ["compile", "optional", "provided", "testCompile"]) {
|
||||
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies, Project project) {
|
||||
for (def configurationName in ["compile", "optional", "provided", "testCompile"]) {
|
||||
Configuration configuration = project.getConfigurations().findByName(configurationName)
|
||||
if(configuration) {
|
||||
if (configuration) {
|
||||
configuration.dependencies.findAll { it instanceof ProjectDependency }.each {
|
||||
projectDependencies.add(it)
|
||||
collectProjectDependencies(projectDependencies, it.dependencyProject)
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.0.4.BUILD-SNAPSHOT
|
||||
version=4.0.9.RELEASE
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Wed Feb 12 23:28:21 CET 2014
|
||||
#Wed Apr 30 13:06:57 CEST 2014
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-bin.zip
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -240,7 +240,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
setArgumentNamesFromStringArray(tokens);
|
||||
}
|
||||
|
||||
public void setArgumentNamesFromStringArray(String[] args) {
|
||||
public void setArgumentNamesFromStringArray(String... args) {
|
||||
this.argumentNames = new String[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
this.argumentNames[i] = StringUtils.trimWhitespace(args[i]);
|
||||
|
||||
+59
-54
@@ -29,7 +29,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.weaver.BCException;
|
||||
import org.aspectj.weaver.patterns.NamePattern;
|
||||
import org.aspectj.weaver.reflect.ReflectionWorld;
|
||||
import org.aspectj.weaver.reflect.ReflectionWorld.ReflectionWorldException;
|
||||
import org.aspectj.weaver.reflect.ShadowMatchImpl;
|
||||
import org.aspectj.weaver.tools.ContextBasedMatcher;
|
||||
@@ -108,6 +107,8 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private transient ClassLoader pointcutClassLoader;
|
||||
|
||||
private transient PointcutExpression pointcutExpression;
|
||||
|
||||
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
|
||||
@@ -185,20 +186,13 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
throw new IllegalStateException("Must set property 'expression' before attempting to match");
|
||||
}
|
||||
if (this.pointcutExpression == null) {
|
||||
this.pointcutExpression = buildPointcutExpression();
|
||||
this.pointcutClassLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
|
||||
ClassUtils.getDefaultClassLoader());
|
||||
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the underlying AspectJ pointcut expression.
|
||||
*/
|
||||
private PointcutExpression buildPointcutExpression() {
|
||||
ClassLoader cl = (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
|
||||
ClassUtils.getDefaultClassLoader());
|
||||
return buildPointcutExpression(cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the underlying AspectJ pointcut expression.
|
||||
*/
|
||||
@@ -252,23 +246,22 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
public boolean matches(Class<?> targetClass) {
|
||||
checkReadyToMatch();
|
||||
try {
|
||||
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
|
||||
}
|
||||
catch (ReflectionWorldException rwe) {
|
||||
logger.debug("PointcutExpression matching rejected target class", rwe);
|
||||
try {
|
||||
// Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
|
||||
return getFallbackPointcutExpression(targetClass).couldMatchJoinPointsInType(targetClass);
|
||||
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
|
||||
}
|
||||
catch (BCException bce) {
|
||||
logger.debug("Fallback PointcutExpression matching rejected target class", bce);
|
||||
return false;
|
||||
catch (ReflectionWorldException ex) {
|
||||
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
|
||||
// Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
|
||||
PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
|
||||
if (fallbackExpression != null) {
|
||||
return fallbackExpression.couldMatchJoinPointsInType(targetClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BCException ex) {
|
||||
logger.debug("PointcutExpression matching rejected target class", ex);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -365,12 +358,19 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
|
||||
/**
|
||||
* Get a new pointcut expression based on a target class's loader, rather
|
||||
* than the default.
|
||||
* Get a new pointcut expression based on a target class's loader rather than the default.
|
||||
*/
|
||||
private PointcutExpression getFallbackPointcutExpression(Class<?> targetClass) {
|
||||
ClassLoader classLoader = targetClass.getClassLoader();
|
||||
return (classLoader != null ? buildPointcutExpression(classLoader) : this.pointcutExpression);
|
||||
try {
|
||||
ClassLoader classLoader = targetClass.getClassLoader();
|
||||
if (classLoader != null && classLoader != this.pointcutClassLoader) {
|
||||
return buildPointcutExpression(classLoader);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.debug("Failed to create fallback PointcutExpression", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private RuntimeTestWalker getRuntimeTestWalker(ShadowMatch shadowMatch) {
|
||||
@@ -396,46 +396,51 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
if (shadowMatch == null) {
|
||||
synchronized (this.shadowMatchCache) {
|
||||
// Not found - now check again with full lock...
|
||||
PointcutExpression fallbackExpression = null;
|
||||
Method methodToMatch = targetMethod;
|
||||
PointcutExpression fallbackPointcutExpression = null;
|
||||
shadowMatch = this.shadowMatchCache.get(methodToMatch);
|
||||
shadowMatch = this.shadowMatchCache.get(targetMethod);
|
||||
if (shadowMatch == null) {
|
||||
try {
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod);
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
catch (ReflectionWorld.ReflectionWorldException ex) {
|
||||
catch (ReflectionWorldException ex) {
|
||||
// Failed to introspect target method, probably because it has been loaded
|
||||
// in a special ClassLoader. Let's try the original method instead...
|
||||
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
|
||||
try {
|
||||
fallbackPointcutExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
|
||||
shadowMatch = fallbackPointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
catch (ReflectionWorld.ReflectionWorldException ex2) {
|
||||
if (targetMethod == originalMethod) {
|
||||
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
|
||||
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
|
||||
if (fallbackExpression != null) {
|
||||
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(originalMethod);
|
||||
}
|
||||
catch (ReflectionWorld.ReflectionWorldException ex3) {
|
||||
// Could neither introspect the target class nor the proxy class ->
|
||||
// let's simply consider this method as non-matching.
|
||||
methodToMatch = originalMethod;
|
||||
fallbackPointcutExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
|
||||
try {
|
||||
shadowMatch = fallbackPointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
catch (ReflectionWorld.ReflectionWorldException ex4) {
|
||||
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
|
||||
}
|
||||
}
|
||||
catch (ReflectionWorldException ex2) {
|
||||
fallbackExpression = null;
|
||||
}
|
||||
}
|
||||
if (shadowMatch == null && targetMethod != originalMethod) {
|
||||
methodToMatch = originalMethod;
|
||||
try {
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
catch (ReflectionWorldException ex3) {
|
||||
// Could neither introspect the target class nor the proxy class ->
|
||||
// let's try the original method's declaring class before we give up...
|
||||
try {
|
||||
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
|
||||
if (fallbackExpression != null) {
|
||||
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
}
|
||||
catch (ReflectionWorldException ex4) {
|
||||
fallbackExpression = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shadowMatch.maybeMatches() && fallbackPointcutExpression != null) {
|
||||
if (shadowMatch == null) {
|
||||
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
|
||||
}
|
||||
else if (shadowMatch.maybeMatches() && fallbackExpression != null) {
|
||||
shadowMatch = new DefensiveShadowMatch(shadowMatch,
|
||||
fallbackPointcutExpression.matchesMethodExecution(methodToMatch));
|
||||
fallbackExpression.matchesMethodExecution(methodToMatch));
|
||||
}
|
||||
this.shadowMatchCache.put(targetMethod, shadowMatch);
|
||||
}
|
||||
|
||||
+11
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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,24 +40,24 @@ public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdv
|
||||
this.pointcut.setExpression(expression);
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return this.pointcut.getExpression();
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.pointcut.setLocation(location);
|
||||
}
|
||||
|
||||
public void setParameterTypes(Class<?>[] types) {
|
||||
this.pointcut.setParameterTypes(types);
|
||||
}
|
||||
|
||||
public void setParameterNames(String[] names) {
|
||||
this.pointcut.setParameterNames(names);
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return this.pointcut.getLocation();
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return this.pointcut.getExpression();
|
||||
public void setParameterTypes(Class<?>[] types) {
|
||||
this.pointcut.setParameterTypes(types);
|
||||
}
|
||||
|
||||
public void setParameterNames(String... names) {
|
||||
this.pointcut.setParameterNames(names);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+35
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -91,9 +91,11 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
|
||||
// Ignore AOP infrastructure such as scoped proxies.
|
||||
return bean;
|
||||
}
|
||||
if (isEligible(bean, beanName)) {
|
||||
if (bean instanceof Advised) {
|
||||
Advised advised = (Advised) bean;
|
||||
|
||||
if (bean instanceof Advised) {
|
||||
Advised advised = (Advised) bean;
|
||||
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
|
||||
// Add our local Advisor to the existing proxy's Advisor chain...
|
||||
if (this.beforeExistingAdvisors) {
|
||||
advised.addAdvisor(0, this.advisor);
|
||||
}
|
||||
@@ -102,32 +104,47 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
else {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(bean);
|
||||
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
|
||||
proxyFactory.copyFrom(this);
|
||||
proxyFactory.addAdvisor(this.advisor);
|
||||
return proxyFactory.getProxy(this.beanClassLoader);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No async proxy needed.
|
||||
return bean;
|
||||
|
||||
if (isEligible(bean, beanName)) {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(bean);
|
||||
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
|
||||
proxyFactory.copyFrom(this);
|
||||
proxyFactory.addAdvisor(this.advisor);
|
||||
return proxyFactory.getProxy(this.beanClassLoader);
|
||||
}
|
||||
|
||||
// No async proxy needed.
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given bean is eligible for advising with this
|
||||
* post-processor's {@link Advisor}.
|
||||
* <p>Implements caching of {@code canApply} results per bean target class.
|
||||
* <p>Delegates to {@link #isEligible(Class)} for target class checking.
|
||||
* Can be overridden e.g. to specifically exclude certain beans by name.
|
||||
* <p>Note: Only called for regular bean instances but not for existing
|
||||
* proxy instances which implement {@link Advised} and allow for adding
|
||||
* the local {@link Advisor} to the existing proxy's {@link Advisor} chain.
|
||||
* For the latter, {@link #isEligible(Class)} is being called directly,
|
||||
* with the actual target class behind the existing proxy (as determined
|
||||
* by {@link AopUtils#getTargetClass(Object)}).
|
||||
* @param bean the bean instance
|
||||
* @param beanName the name of the bean
|
||||
* @see AopUtils#getTargetClass(Object)
|
||||
* @see AopUtils#canApply(Advisor, Class)
|
||||
* @see #isEligible(Class)
|
||||
*/
|
||||
protected boolean isEligible(Object bean, String beanName) {
|
||||
Class<?> targetClass = AopUtils.getTargetClass(bean);
|
||||
return isEligible(bean.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given class is eligible for advising with this
|
||||
* post-processor's {@link Advisor}.
|
||||
* <p>Implements caching of {@code canApply} results per bean target class.
|
||||
* @param targetClass the class to check against
|
||||
* @see AopUtils#canApply(Advisor, Class)
|
||||
*/
|
||||
protected boolean isEligible(Class<?> targetClass) {
|
||||
Boolean eligible = this.eligibleBeans.get(targetClass);
|
||||
if (eligible != null) {
|
||||
return eligible;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,10 +32,10 @@ public interface AdvisorChainFactory {
|
||||
* for the given advisor chain configuration.
|
||||
* @param config the AOP configuration in the form of an Advised object
|
||||
* @param method the proxied method
|
||||
* @param targetClass the target class
|
||||
* @param targetClass the target class (may be {@code null} to indicate a proxy without
|
||||
* target object, in which case the method's declaring class is the next best option)
|
||||
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
|
||||
*/
|
||||
List<Object> getInterceptorsAndDynamicInterceptionAdvice(
|
||||
Advised config, Method method, Class<?> targetClass);
|
||||
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass);
|
||||
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
if (!Object.class.equals(method.getDeclaringClass()) && !Modifier.isStatic(method.getModifiers()) &&
|
||||
Modifier.isFinal(method.getModifiers())) {
|
||||
logger.warn("Unable to proxy method [" + method + "] because it is final: " +
|
||||
"All calls to this method via a proxy will be routed directly to the proxy.");
|
||||
"All calls to this method via a proxy will NOT be routed to the target instance.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -604,7 +604,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
|
||||
|
||||
private AdvisedSupport advised;
|
||||
private final AdvisedSupport advised;
|
||||
|
||||
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
|
||||
this.advised = advised;
|
||||
@@ -622,8 +622,8 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
setProxyContext = true;
|
||||
}
|
||||
// May be null Get as late as possible to minimize the time we
|
||||
// "own" the target, in case it comes from a pool.
|
||||
// May be null. Get as late as possible to minimize the time we
|
||||
// "own" the target, in case it comes from a pool...
|
||||
target = getTarget();
|
||||
if (target != null) {
|
||||
targetClass = target.getClass();
|
||||
@@ -689,13 +689,13 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
private final MethodProxy methodProxy;
|
||||
|
||||
private boolean protectedMethod;
|
||||
private final boolean publicMethod;
|
||||
|
||||
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
|
||||
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
|
||||
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
||||
this.methodProxy = methodProxy;
|
||||
this.protectedMethod = Modifier.isProtected(method.getModifiers());
|
||||
this.publicMethod = Modifier.isPublic(method.getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -704,11 +704,11 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
@Override
|
||||
protected Object invokeJoinpoint() throws Throwable {
|
||||
if (this.protectedMethod) {
|
||||
return super.invokeJoinpoint();
|
||||
if (this.publicMethod) {
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
}
|
||||
else {
|
||||
return this.methodProxy.invoke(this.target, this.arguments);
|
||||
return super.invokeJoinpoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -829,8 +829,8 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
// of the target type. If so we know it never needs to have return type
|
||||
// massage and can use a dispatcher.
|
||||
// If the proxy is being exposed, then must use the interceptor the
|
||||
// correct one is already configured. If the target is not static cannot
|
||||
// use a Dispatcher because the target can not then be released.
|
||||
// correct one is already configured. If the target is not static, then
|
||||
// cannot use a dispatcher because the target cannot be released.
|
||||
if (exposeProxy || !isStatic) {
|
||||
return INVOKE_TARGET;
|
||||
}
|
||||
|
||||
+11
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,19 +50,21 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
|
||||
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
|
||||
Advised config, Method method, Class<?> targetClass) {
|
||||
|
||||
// This is somewhat tricky... we have to process introductions first,
|
||||
// This is somewhat tricky... We have to process introductions first,
|
||||
// but we need to preserve order in the ultimate list.
|
||||
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
|
||||
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
|
||||
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
|
||||
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
|
||||
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
|
||||
|
||||
for (Advisor advisor : config.getAdvisors()) {
|
||||
if (advisor instanceof PointcutAdvisor) {
|
||||
// Add it conditionally.
|
||||
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
|
||||
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
|
||||
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
|
||||
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
|
||||
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
|
||||
if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {
|
||||
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
|
||||
if (mm.isRuntime()) {
|
||||
// Creating a new object instance in the getInterceptors() method
|
||||
// isn't a problem as we normally cache created chains.
|
||||
@@ -78,7 +80,7 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
|
||||
}
|
||||
else if (advisor instanceof IntroductionAdvisor) {
|
||||
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
|
||||
if (config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {
|
||||
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
|
||||
Interceptor[] interceptors = registry.getInterceptors(advisor);
|
||||
interceptorList.addAll(Arrays.asList(interceptors));
|
||||
}
|
||||
@@ -88,18 +90,19 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
|
||||
interceptorList.addAll(Arrays.asList(interceptors));
|
||||
}
|
||||
}
|
||||
|
||||
return interceptorList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the Advisors contain matching introductions.
|
||||
*/
|
||||
private static boolean hasMatchingIntroductions(Advised config, Class<?> targetClass) {
|
||||
private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
|
||||
for (int i = 0; i < config.getAdvisors().length; i++) {
|
||||
Advisor advisor = config.getAdvisors()[i];
|
||||
if (advisor instanceof IntroductionAdvisor) {
|
||||
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
|
||||
if (ia.getClassFilter().matches(targetClass)) {
|
||||
if (ia.getClassFilter().matches(actualClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -75,7 +75,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
*/
|
||||
|
||||
/** We use a static Log to avoid serialization issues */
|
||||
private static Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
|
||||
private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
|
||||
|
||||
/** Config used to configure this proxy */
|
||||
private final AdvisedSupport advised;
|
||||
@@ -215,8 +215,10 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
// is type-compatible. Note that we can't help if the target sets
|
||||
// a reference to itself in another returned object.
|
||||
retVal = proxy;
|
||||
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
|
||||
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
|
||||
}
|
||||
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
|
||||
throw new AopInvocationException(
|
||||
"Null return value from advice does not match primitive return type for: " + method);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,7 +19,6 @@ package org.springframework.aop.framework;
|
||||
import org.aopalliance.intercept.Interceptor;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -47,9 +46,8 @@ public class ProxyFactory extends ProxyCreatorSupport {
|
||||
* @param target the target object to be proxied
|
||||
*/
|
||||
public ProxyFactory(Object target) {
|
||||
Assert.notNull(target, "Target object must not be null");
|
||||
setInterfaces(ClassUtils.getAllInterfaces(target));
|
||||
setTarget(target);
|
||||
setInterfaces(ClassUtils.getAllInterfaces(target));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -154,7 +154,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* @see org.aopalliance.aop.Advice
|
||||
* @see org.springframework.aop.target.SingletonTargetSource
|
||||
*/
|
||||
public void setInterceptorNames(String[] interceptorNames) {
|
||||
public void setInterceptorNames(String... interceptorNames) {
|
||||
this.interceptorNames = interceptorNames;
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -205,7 +205,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
* Ordering is significant: The TargetSource returned from the first matching
|
||||
* TargetSourceCreator (that is, the first that returns non-null) will be used.
|
||||
*/
|
||||
public void setCustomTargetSourceCreators(TargetSourceCreator[] targetSourceCreators) {
|
||||
public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
|
||||
this.customTargetSourceCreators = targetSourceCreators;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
* This is perfectly valid, if "specific" interceptors such as matching
|
||||
* Advisors are all we want.
|
||||
*/
|
||||
public void setInterceptorNames(String[] interceptorNames) {
|
||||
public void setInterceptorNames(String... interceptorNames) {
|
||||
this.interceptorNames = interceptorNames;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,9 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||
@Override
|
||||
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
|
||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||
this.earlyProxyReferences.add(cacheKey);
|
||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
||||
this.earlyProxyReferences.add(cacheKey);
|
||||
}
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -60,7 +60,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
* @see org.springframework.beans.factory.FactoryBean
|
||||
* @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
|
||||
*/
|
||||
public void setBeanNames(String[] beanNames) {
|
||||
public void setBeanNames(String... beanNames) {
|
||||
Assert.notEmpty(beanNames, "'beanNames' must not be empty");
|
||||
this.beanNames = new ArrayList<String>(beanNames.length);
|
||||
for (String mappedName : beanNames) {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* Copyright 2002-2014 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,7 +25,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
* TargetSourceCreator that enforces a LazyInitTargetSource for each bean
|
||||
* that is defined as "lazy-init". This will lead to a proxy created for
|
||||
* each of those beans, allowing to fetch a reference to such a bean
|
||||
* without actually initialized the target bean instance.
|
||||
* without actually initializing the target bean instance.
|
||||
*
|
||||
* <p>To be registered as custom TargetSourceCreator for an auto-proxy creator,
|
||||
* in combination with custom interceptors for specific beans or for the
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,6 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
|
||||
@@ -81,7 +80,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
* Set the {@link BeanFactory} to be used when looking up executors by qualifier.
|
||||
*/
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -62,11 +62,11 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport
|
||||
|
||||
/**
|
||||
* Create a new {@code AsyncExecutionInterceptor}.
|
||||
* @param executor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to.
|
||||
* @param defaultExecutor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}
|
||||
* or {@link java.util.concurrent.ExecutorService}) to delegate to
|
||||
*/
|
||||
public AsyncExecutionInterceptor(Executor executor) {
|
||||
super(executor);
|
||||
public AsyncExecutionInterceptor(Executor defaultExecutor) {
|
||||
super(defaultExecutor);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,8 +119,8 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport
|
||||
* Subclasses may override to provide support for extracting qualifier information,
|
||||
* e.g. via an annotation on the given method.
|
||||
* @return always {@code null}
|
||||
* @see #determineAsyncExecutor(Method)
|
||||
* @since 3.1.2
|
||||
* @see #determineAsyncExecutor(Method)
|
||||
*/
|
||||
@Override
|
||||
protected String getExecutorQualifier(Method method) {
|
||||
|
||||
+2
-2
@@ -258,7 +258,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
return returnValue;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if(stopWatch.isRunning()) {
|
||||
if (stopWatch.isRunning()) {
|
||||
stopWatch.stop();
|
||||
}
|
||||
exitThroughException = true;
|
||||
@@ -268,7 +268,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
|
||||
}
|
||||
finally {
|
||||
if (!exitThroughException) {
|
||||
if(stopWatch.isRunning()) {
|
||||
if (stopWatch.isRunning()) {
|
||||
stopWatch.stop();
|
||||
}
|
||||
writeToLog(logger,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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,7 +19,7 @@ package org.springframework.aop.support;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -215,7 +215,7 @@ public abstract class AopUtils {
|
||||
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
|
||||
}
|
||||
|
||||
Set<Class<?>> classes = new HashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
|
||||
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
|
||||
classes.add(targetClass);
|
||||
for (Class<?> clazz : classes) {
|
||||
Method[] methods = clazz.getMethods();
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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,7 +17,7 @@
|
||||
package org.springframework.aop.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
@@ -43,7 +43,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
|
||||
|
||||
private final Advice advice;
|
||||
|
||||
private final Set<Class<?>> interfaces = new HashSet<Class<?>>();
|
||||
private final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
|
||||
|
||||
private int order = Integer.MAX_VALUE;
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -43,7 +43,7 @@ import org.springframework.util.ClassUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class IntroductionInfoSupport implements IntroductionInfo, Serializable {
|
||||
|
||||
protected final Set<Class<?>> publishedInterfaces = new HashSet<Class<?>>();
|
||||
protected final Set<Class<?>> publishedInterfaces = new LinkedHashSet<Class<?>>();
|
||||
|
||||
private transient Map<Method, Boolean> rememberedMethods = new ConcurrentHashMap<Method, Boolean>(32);
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -47,7 +47,7 @@ public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut impleme
|
||||
* @see #setMappedNames
|
||||
*/
|
||||
public void setMappedName(String mappedName) {
|
||||
setMappedNames(new String[] {mappedName});
|
||||
setMappedNames(mappedName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +55,7 @@ public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut impleme
|
||||
* Matching will be the union of all these; if any match,
|
||||
* the pointcut matches.
|
||||
*/
|
||||
public void setMappedNames(String[] mappedNames) {
|
||||
public void setMappedNames(String... mappedNames) {
|
||||
this.mappedNames = new LinkedList<String>();
|
||||
if (mappedNames != null) {
|
||||
this.mappedNames.addAll(Arrays.asList(mappedNames));
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -68,7 +68,7 @@ public class NameMatchMethodPointcutAdvisor extends AbstractGenericPointcutAdvis
|
||||
* the pointcut matches.
|
||||
* @see NameMatchMethodPointcut#setMappedNames
|
||||
*/
|
||||
public void setMappedNames(String[] mappedNames) {
|
||||
public void setMappedNames(String... mappedNames) {
|
||||
this.pointcut.setMappedNames(mappedNames);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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 @@ public class RegexpMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor
|
||||
* @see #setPatterns
|
||||
*/
|
||||
public void setPattern(String pattern) {
|
||||
setPatterns(new String[] {pattern});
|
||||
setPatterns(pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,7 +108,7 @@ public class RegexpMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor
|
||||
* patterns matches, the pointcut matches.
|
||||
* @see AbstractRegexpMethodPointcut#setPatterns
|
||||
*/
|
||||
public void setPatterns(String[] patterns) {
|
||||
public void setPatterns(String... patterns) {
|
||||
this.patterns = patterns;
|
||||
}
|
||||
|
||||
|
||||
+4
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -48,8 +47,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @see ThreadLocalTargetSource
|
||||
* @see CommonsPoolTargetSource
|
||||
*/
|
||||
public abstract class AbstractBeanFactoryBasedTargetSource
|
||||
implements TargetSource, BeanFactoryAware, Serializable {
|
||||
public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSource, BeanFactoryAware, Serializable {
|
||||
|
||||
/** use serialVersionUID from Spring 1.2.7 for interoperability */
|
||||
private static final long serialVersionUID = -4721607536018568393L;
|
||||
@@ -108,7 +106,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
if (this.targetBeanName == null) {
|
||||
throw new IllegalStateException("Property'targetBeanName' is required");
|
||||
throw new IllegalStateException("Property 'targetBeanName' is required");
|
||||
}
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
@@ -185,8 +183,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(ClassUtils.getShortName(getClass()));
|
||||
StringBuilder sb = new StringBuilder(getClass().getSimpleName());
|
||||
sb.append(" for target bean '").append(this.targetBeanName).append("'");
|
||||
if (this.targetClass != null) {
|
||||
sb.append(" of type [").append(this.targetClass.getName()).append("]");
|
||||
|
||||
+30
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,26 +27,18 @@ import org.aspectj.lang.annotation.control.CodeGenerationHint;
|
||||
* @since 2.5.2
|
||||
*/
|
||||
public abstract aspect AbstractDependencyInjectionAspect {
|
||||
/**
|
||||
* Select construction join points for objects to inject dependencies
|
||||
*/
|
||||
public abstract pointcut beanConstruction(Object bean);
|
||||
|
||||
private pointcut preConstructionCondition() :
|
||||
leastSpecificSuperTypeConstruction() && preConstructionConfiguration();
|
||||
|
||||
private pointcut postConstructionCondition() :
|
||||
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();
|
||||
|
||||
/**
|
||||
* Select deserialization join points for objects to inject dependencies
|
||||
* Select least specific super type that is marked for DI
|
||||
* (so that injection occurs only once with pre-construction injection).
|
||||
*/
|
||||
public abstract pointcut beanDeserialization(Object bean);
|
||||
|
||||
/**
|
||||
* Select join points in a configurable bean
|
||||
*/
|
||||
public abstract pointcut inConfigurableBean();
|
||||
|
||||
/**
|
||||
* Select join points in beans to be configured prior to construction?
|
||||
* By default, use post-construction injection matching the default in the Configurable annotation.
|
||||
*/
|
||||
public pointcut preConstructionConfiguration() : if(false);
|
||||
public abstract pointcut leastSpecificSuperTypeConstruction();
|
||||
|
||||
/**
|
||||
* Select the most-specific initialization join point
|
||||
@@ -54,24 +46,29 @@ public abstract aspect AbstractDependencyInjectionAspect {
|
||||
*/
|
||||
@CodeGenerationHint(ifNameSuffix="6f1")
|
||||
public pointcut mostSpecificSubTypeConstruction() :
|
||||
if(thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass());
|
||||
if (thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass());
|
||||
|
||||
/**
|
||||
* Select least specific super type that is marked for DI (so that injection occurs only once with pre-construction inejection
|
||||
* Select join points in beans to be configured prior to construction?
|
||||
* By default, use post-construction injection matching the default in the Configurable annotation.
|
||||
*/
|
||||
public abstract pointcut leastSpecificSuperTypeConstruction();
|
||||
public pointcut preConstructionConfiguration() : if (false);
|
||||
|
||||
/**
|
||||
* Configure the bean
|
||||
* Select construction join points for objects to inject dependencies.
|
||||
*/
|
||||
public abstract void configureBean(Object bean);
|
||||
public abstract pointcut beanConstruction(Object bean);
|
||||
|
||||
/**
|
||||
* Select deserialization join points for objects to inject dependencies.
|
||||
*/
|
||||
public abstract pointcut beanDeserialization(Object bean);
|
||||
|
||||
private pointcut preConstructionCondition() :
|
||||
leastSpecificSuperTypeConstruction() && preConstructionConfiguration();
|
||||
/**
|
||||
* Select join points in a configurable bean.
|
||||
*/
|
||||
public abstract pointcut inConfigurableBean();
|
||||
|
||||
private pointcut postConstructionCondition() :
|
||||
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();
|
||||
|
||||
/**
|
||||
* Pre-construction configuration.
|
||||
@@ -100,4 +97,10 @@ public abstract aspect AbstractDependencyInjectionAspect {
|
||||
configureBean(bean);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure the given bean.
|
||||
*/
|
||||
public abstract void configureBean(Object bean);
|
||||
|
||||
}
|
||||
|
||||
+50
-54
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,49 +20,48 @@ import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* An aspect that injects dependency into any object whose type implements the {@link ConfigurableObject} interface.
|
||||
* <p>
|
||||
* This aspect supports injecting into domain objects when they are created for the first time as well as
|
||||
* upon deserialization. Subaspects need to simply provide definition for the configureBean() method. This
|
||||
* method may be implemented without relying on Spring container if so desired.
|
||||
* </p>
|
||||
* <p>
|
||||
* There are two cases that needs to be handled:
|
||||
* An aspect that injects dependency into any object whose type implements the
|
||||
* {@link ConfigurableObject} interface.
|
||||
*
|
||||
* <p>This aspect supports injecting into domain objects when they are created
|
||||
* for the first time as well as upon deserialization. Subaspects need to simply
|
||||
* provide definition for the configureBean() method. This method may be
|
||||
* implemented without relying on Spring container if so desired.
|
||||
*
|
||||
* <p>There are two cases that needs to be handled:
|
||||
* <ol>
|
||||
* <li>Normal object creation via the '{@code new}' operator: this is
|
||||
* taken care of by advising {@code initialization()} join points.</li>
|
||||
* <li>Object creation through deserialization: since no constructor is
|
||||
* invoked during deserialization, the aspect needs to advise a method that a
|
||||
* deserialization mechanism is going to invoke. Ideally, we should not
|
||||
* require user classes to implement any specific method. This implies that
|
||||
* we need to <i>introduce</i> the chosen method. We should also handle the cases
|
||||
* where the chosen method is already implemented in classes (in which case,
|
||||
* the user's implementation for that method should take precedence over the
|
||||
* introduced implementation). There are a few choices for the chosen method:
|
||||
* <ul>
|
||||
* <li>readObject(ObjectOutputStream): Java requires that the method must be
|
||||
* {@code private}</p>. Since aspects cannot introduce a private member,
|
||||
* while preserving its name, this option is ruled out.</li>
|
||||
* <li>readResolve(): Java doesn't pose any restriction on an access specifier.
|
||||
* Problem solved! There is one (minor) limitation of this approach in
|
||||
* that if a user class already has this method, that method must be
|
||||
* {@code public}. However, this shouldn't be a big burden, since
|
||||
* use cases that need classes to implement readResolve() (custom enums,
|
||||
* for example) are unlikely to be marked as @Configurable, and
|
||||
* in any case asking to make that method {@code public} should not
|
||||
* pose any undue burden.</li>
|
||||
* </ul>
|
||||
* The minor collaboration needed by user classes (i.e., that the
|
||||
* implementation of {@code readResolve()}, if any, must be
|
||||
* {@code public}) can be lifted as well if we were to use an
|
||||
* experimental feature in AspectJ - the {@code hasmethod()} PCD.</li>
|
||||
* <li>Normal object creation via the '{@code new}' operator: this is
|
||||
* taken care of by advising {@code initialization()} join points.</li>
|
||||
* <li>Object creation through deserialization: since no constructor is
|
||||
* invoked during deserialization, the aspect needs to advise a method that a
|
||||
* deserialization mechanism is going to invoke. Ideally, we should not
|
||||
* require user classes to implement any specific method. This implies that
|
||||
* we need to <i>introduce</i> the chosen method. We should also handle the cases
|
||||
* where the chosen method is already implemented in classes (in which case,
|
||||
* the user's implementation for that method should take precedence over the
|
||||
* introduced implementation). There are a few choices for the chosen method:
|
||||
* <ul>
|
||||
* <li>readObject(ObjectOutputStream): Java requires that the method must be
|
||||
* {@code private}</p>. Since aspects cannot introduce a private member,
|
||||
* while preserving its name, this option is ruled out.</li>
|
||||
* <li>readResolve(): Java doesn't pose any restriction on an access specifier.
|
||||
* Problem solved! There is one (minor) limitation of this approach in
|
||||
* that if a user class already has this method, that method must be
|
||||
* {@code public}. However, this shouldn't be a big burden, since
|
||||
* use cases that need classes to implement readResolve() (custom enums,
|
||||
* for example) are unlikely to be marked as @Configurable, and
|
||||
* in any case asking to make that method {@code public} should not
|
||||
* pose any undue burden.</li>
|
||||
* </ul>
|
||||
* The minor collaboration needed by user classes (i.e., that the implementation of
|
||||
* {@code readResolve()}, if any, must be {@code public}) can be lifted as well if we
|
||||
* were to use an experimental feature in AspectJ - the {@code hasmethod()} PCD.</li>
|
||||
* </ol>
|
||||
|
||||
* <p>
|
||||
* While having type implement the {@link ConfigurableObject} interface is certainly a valid choice, an alternative
|
||||
* is to use a 'declare parents' statement another aspect (a subaspect of this aspect would be a logical choice)
|
||||
* that declares the classes that need to be configured by supplying the {@link ConfigurableObject} interface.
|
||||
* </p>
|
||||
*
|
||||
* <p>While having type implement the {@link ConfigurableObject} interface is certainly
|
||||
* a valid choice, an alternative is to use a 'declare parents' statement another aspect
|
||||
* (a subaspect of this aspect would be a logical choice) that declares the classes that
|
||||
* need to be configured by supplying the {@link ConfigurableObject} interface.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.5.2
|
||||
@@ -72,35 +71,33 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends
|
||||
* Select initialization join point as object construction
|
||||
*/
|
||||
public pointcut beanConstruction(Object bean) :
|
||||
initialization(ConfigurableObject+.new(..)) && this(bean);
|
||||
initialization(ConfigurableObject+.new(..)) && this(bean);
|
||||
|
||||
/**
|
||||
* Select deserialization join point made available through ITDs for ConfigurableDeserializationSupport
|
||||
*/
|
||||
public pointcut beanDeserialization(Object bean) :
|
||||
execution(Object ConfigurableDeserializationSupport+.readResolve()) &&
|
||||
this(bean);
|
||||
execution(Object ConfigurableDeserializationSupport+.readResolve()) && this(bean);
|
||||
|
||||
public pointcut leastSpecificSuperTypeConstruction() : initialization(ConfigurableObject.new(..));
|
||||
|
||||
|
||||
|
||||
// Implementation to support re-injecting dependencies once an object is deserialized
|
||||
|
||||
/**
|
||||
* Declare any class implementing Serializable and ConfigurableObject as also implementing
|
||||
* ConfigurableDeserializationSupport. This allows us to introduce the readResolve()
|
||||
* ConfigurableDeserializationSupport. This allows us to introduce the {@code readResolve()}
|
||||
* method and select it with the beanDeserialization() pointcut.
|
||||
*
|
||||
* <p>Here is an improved version that uses the hasmethod() pointcut and lifts
|
||||
* even the minor requirement on user classes:
|
||||
*
|
||||
* <pre class="code">declare parents: ConfigurableObject+ Serializable+
|
||||
* && !hasmethod(Object readResolve() throws ObjectStreamException)
|
||||
* implements ConfigurableDeserializationSupport;
|
||||
* <pre class="code">
|
||||
* declare parents: ConfigurableObject+ Serializable+
|
||||
* && !hasmethod(Object readResolve() throws ObjectStreamException)
|
||||
* implements ConfigurableDeserializationSupport;
|
||||
* </pre>
|
||||
*/
|
||||
declare parents:
|
||||
ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport;
|
||||
declare parents: ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport;
|
||||
|
||||
/**
|
||||
* A marker interface to which the {@code readResolve()} is introduced.
|
||||
@@ -111,7 +108,6 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends
|
||||
/**
|
||||
* Introduce the {@code readResolve()} method so that we can advise its
|
||||
* execution to configure the object.
|
||||
*
|
||||
* <p>Note if a method with the same signature already exists in a
|
||||
* {@code Serializable} class of ConfigurableObject type,
|
||||
* that implementation will take precedence (a good thing, since we are
|
||||
|
||||
+27
-28
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,7 +19,7 @@ package org.springframework.beans.factory.aspectj;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.aspectj.lang.annotation.control.CodeGenerationHint;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
@@ -44,48 +44,47 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
|
||||
* @see org.springframework.beans.factory.annotation.Configurable
|
||||
* @see org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver
|
||||
*/
|
||||
public aspect AnnotationBeanConfigurerAspect
|
||||
extends AbstractInterfaceDrivenDependencyInjectionAspect
|
||||
public aspect AnnotationBeanConfigurerAspect extends AbstractInterfaceDrivenDependencyInjectionAspect
|
||||
implements BeanFactoryAware, InitializingBean, DisposableBean {
|
||||
|
||||
private BeanConfigurerSupport beanConfigurerSupport = new BeanConfigurerSupport();
|
||||
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
|
||||
this.beanConfigurerSupport.setBeanFactory(beanFactory);
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.beanConfigurerSupport.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void configureBean(Object bean) {
|
||||
this.beanConfigurerSupport.configureBean(bean);
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
this.beanConfigurerSupport.destroy();
|
||||
}
|
||||
|
||||
|
||||
public pointcut inConfigurableBean() : @this(Configurable);
|
||||
|
||||
public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);
|
||||
|
||||
declare parents: @Configurable * implements ConfigurableObject;
|
||||
|
||||
public void configureBean(Object bean) {
|
||||
beanConfigurerSupport.configureBean(bean);
|
||||
}
|
||||
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
beanConfigurerSupport.setBeanFactory(beanFactory);
|
||||
beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
beanConfigurerSupport.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
beanConfigurerSupport.destroy();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* An intermediary to match preConstructionConfiguration signature (that doesn't expose the annotation object)
|
||||
*/
|
||||
@CodeGenerationHint(ifNameSuffix="bb0")
|
||||
private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if(c.preConstruction());
|
||||
private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if (c.preConstruction());
|
||||
|
||||
|
||||
declare parents: @Configurable * implements ConfigurableObject;
|
||||
|
||||
/*
|
||||
* This declaration shouldn't be needed,
|
||||
* except for an AspectJ bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=214559)
|
||||
*/
|
||||
declare parents: @Configurable Serializable+
|
||||
implements ConfigurableDeserializationSupport;
|
||||
declare parents: @Configurable Serializable+ implements ConfigurableDeserializationSupport;
|
||||
|
||||
}
|
||||
|
||||
Vendored
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -35,7 +35,7 @@ import org.springframework.context.annotation.Role;
|
||||
@Configuration
|
||||
public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
|
||||
|
||||
@Bean(name=AnnotationConfigUtils.CACHE_ASPECT_BEAN_NAME)
|
||||
@Bean(name = AnnotationConfigUtils.CACHE_ASPECT_BEAN_NAME)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public AnnotationCacheAspect cacheAspect() {
|
||||
AnnotationCacheAspect cacheAspect = AnnotationCacheAspect.aspectOf();
|
||||
@@ -47,4 +47,5 @@ public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
|
||||
}
|
||||
return cacheAspect;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
||||
@Configuration
|
||||
public class AspectJAsyncConfiguration extends AbstractAsyncConfiguration {
|
||||
|
||||
@Bean(name=AnnotationConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)
|
||||
@Bean(name = AnnotationConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public AnnotationAsyncExecutionAspect asyncAdvisor() {
|
||||
AnnotationAsyncExecutionAspect asyncAspect = AnnotationAsyncExecutionAspect.aspectOf();
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,7 @@ import org.springframework.transaction.config.TransactionManagementConfigUtils;
|
||||
@Configuration
|
||||
public class AspectJTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
|
||||
|
||||
@Bean(name=TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME)
|
||||
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public AnnotationTransactionAspect transactionAspect() {
|
||||
AnnotationTransactionAspect txAspect = AnnotationTransactionAspect.aspectOf();
|
||||
@@ -46,4 +46,5 @@ public class AspectJTransactionManagementConfiguration extends AbstractTransacti
|
||||
}
|
||||
return txAspect;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,6 +54,7 @@ import org.springframework.core.io.DescriptiveResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* A Groovy-based reader for Spring bean definitions: like a Groovy builder,
|
||||
@@ -213,7 +214,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
Binding binding = new Binding() {
|
||||
@Override
|
||||
public void setVariable(String name, Object value) {
|
||||
if (currentBeanDefinition !=null) {
|
||||
if (currentBeanDefinition != null) {
|
||||
applyPropertyToBeanDefinition(name, value);
|
||||
}
|
||||
else {
|
||||
@@ -269,10 +270,9 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
try {
|
||||
Closure callable = null;
|
||||
Collection constructorArgs = null;
|
||||
if (args != null && args.length > 0) {
|
||||
if (!ObjectUtils.isEmpty(args)) {
|
||||
int index = args.length;
|
||||
Object lastArg = args[index-1];
|
||||
|
||||
if (lastArg instanceof Closure) {
|
||||
callable = (Closure) lastArg;
|
||||
index--;
|
||||
@@ -410,7 +410,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
dp.apply();
|
||||
}
|
||||
deferredProperties.clear();
|
||||
this.deferredProperties.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,11 +49,12 @@ public class BeanInstantiationException extends FatalBeanException {
|
||||
this.beanClass = beanClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the offending bean class.
|
||||
*/
|
||||
public Class<?> getBeanClass() {
|
||||
return beanClass;
|
||||
return this.beanClass;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -379,13 +379,28 @@ public abstract class BeanUtils {
|
||||
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
|
||||
* with the method either being the read method or the write method for
|
||||
* that bean property.
|
||||
* @param method the method to find a corresponding PropertyDescriptor for
|
||||
* @param method the method to find a corresponding PropertyDescriptor for,
|
||||
* introspecting its declaring class
|
||||
* @return the corresponding PropertyDescriptor, or {@code null} if none
|
||||
* @throws BeansException if PropertyDescriptor lookup fails
|
||||
*/
|
||||
public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException {
|
||||
return findPropertyForMethod(method, method.getDeclaringClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
|
||||
* with the method either being the read method or the write method for
|
||||
* that bean property.
|
||||
* @param method the method to find a corresponding PropertyDescriptor for
|
||||
* @param clazz the (most specific) class to introspect for descriptors
|
||||
* @return the corresponding PropertyDescriptor, or {@code null} if none
|
||||
* @throws BeansException if PropertyDescriptor lookup fails
|
||||
* @since 3.2.13
|
||||
*/
|
||||
public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException {
|
||||
Assert.notNull(method, "Method must not be null");
|
||||
PropertyDescriptor[] pds = getPropertyDescriptors(method.getDeclaringClass());
|
||||
PropertyDescriptor[] pds = getPropertyDescriptors(clazz);
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
if (method.equals(pd.getReadMethod()) || method.equals(pd.getWriteMethod())) {
|
||||
return pd;
|
||||
@@ -591,11 +606,11 @@ public abstract class BeanUtils {
|
||||
actualEditable = editable;
|
||||
}
|
||||
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
|
||||
List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
|
||||
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
|
||||
|
||||
for (PropertyDescriptor targetPd : targetPds) {
|
||||
Method writeMethod = targetPd.getWriteMethod();
|
||||
if (writeMethod != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
|
||||
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
|
||||
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
|
||||
if (sourcePd != null) {
|
||||
Method readMethod = sourcePd.getReadMethod();
|
||||
|
||||
@@ -398,7 +398,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
if (pd.getReadMethod() != null || pd.getWriteMethod() != null) {
|
||||
return TypeDescriptor.nested(property(pd), tokens.keys.length);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (pd.getReadMethod() != null || pd.getWriteMethod() != null) {
|
||||
return new TypeDescriptor(property(pd));
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -196,7 +196,7 @@ public class CachedIntrospectionResults {
|
||||
}
|
||||
results = new CachedIntrospectionResults(beanClass);
|
||||
synchronized (classCache) {
|
||||
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
|
||||
classCache.put(beanClass, new SoftReference<CachedIntrospectionResults>(results));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -35,6 +35,9 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import static org.springframework.beans.PropertyDescriptorUtils.*;
|
||||
|
||||
/**
|
||||
@@ -73,6 +76,8 @@ import static org.springframework.beans.PropertyDescriptorUtils.*;
|
||||
*/
|
||||
class ExtendedBeanInfo implements BeanInfo {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ExtendedBeanInfo.class);
|
||||
|
||||
private final BeanInfo delegate;
|
||||
|
||||
private final Set<PropertyDescriptor> propertyDescriptors =
|
||||
@@ -94,14 +99,30 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException {
|
||||
this.delegate = delegate;
|
||||
for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) {
|
||||
this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
|
||||
new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
|
||||
new SimplePropertyDescriptor(pd));
|
||||
try {
|
||||
this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
|
||||
new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
|
||||
new SimplePropertyDescriptor(pd));
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
// Probably simply a method that wasn't meant to follow the JavaBeans pattern...
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring invalid bean property '" + pd.getName() + "': " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodDescriptor[] methodDescriptors = delegate.getMethodDescriptors();
|
||||
if (methodDescriptors != null) {
|
||||
for (Method method : findCandidateWriteMethods(methodDescriptors)) {
|
||||
handleCandidateWriteMethod(method);
|
||||
try {
|
||||
handleCandidateWriteMethod(method);
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
// We're only trying to find candidates, can easily ignore extra ones here...
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring candidate write method [" + method + "]: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +136,7 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
matches.add(method);
|
||||
}
|
||||
}
|
||||
// sort non-void returning write methods to guard against the ill effects of
|
||||
// Sort non-void returning write methods to guard against the ill effects of
|
||||
// non-deterministic sorting of methods returned from Class#getDeclaredMethods
|
||||
// under JDK 7. See http://bugs.sun.com/view_bug.do?bug_id=7023180
|
||||
Collections.sort(matches, new Comparator<Method>() {
|
||||
@@ -131,15 +152,15 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
String methodName = method.getName();
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
int nParams = parameterTypes.length;
|
||||
return methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
|
||||
return (methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
|
||||
(!void.class.isAssignableFrom(method.getReturnType()) || Modifier.isStatic(method.getModifiers())) &&
|
||||
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class)));
|
||||
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class))));
|
||||
}
|
||||
|
||||
private void handleCandidateWriteMethod(Method method) throws IntrospectionException {
|
||||
int nParams = method.getParameterTypes().length;
|
||||
String propertyName = propertyNameFor(method);
|
||||
Class<?> propertyType = method.getParameterTypes()[nParams-1];
|
||||
Class<?> propertyType = method.getParameterTypes()[nParams - 1];
|
||||
PropertyDescriptor existingPd = findExistingPropertyDescriptor(propertyName, propertyType);
|
||||
if (nParams == 1) {
|
||||
if (existingPd == null) {
|
||||
@@ -437,24 +458,24 @@ class SimpleIndexedPropertyDescriptor extends IndexedPropertyDescriptor {
|
||||
* See java.beans.IndexedPropertyDescriptor#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (obj != null && obj instanceof IndexedPropertyDescriptor) {
|
||||
IndexedPropertyDescriptor other = (IndexedPropertyDescriptor) obj;
|
||||
if (!compareMethods(getIndexedReadMethod(), other.getIndexedReadMethod())) {
|
||||
return false;
|
||||
}
|
||||
if (!compareMethods(getIndexedWriteMethod(), other.getIndexedWriteMethod())) {
|
||||
return false;
|
||||
}
|
||||
if (getIndexedPropertyType() != other.getIndexedPropertyType()) {
|
||||
return false;
|
||||
}
|
||||
return PropertyDescriptorUtils.equals(this, obj);
|
||||
if (!(other instanceof IndexedPropertyDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
IndexedPropertyDescriptor otherPd = (IndexedPropertyDescriptor) other;
|
||||
if (!compareMethods(getIndexedReadMethod(), otherPd.getIndexedReadMethod())) {
|
||||
return false;
|
||||
}
|
||||
if (!compareMethods(getIndexedWriteMethod(), otherPd.getIndexedWriteMethod())) {
|
||||
return false;
|
||||
}
|
||||
if (getIndexedPropertyType() != otherPd.getIndexedPropertyType()) {
|
||||
return false;
|
||||
}
|
||||
return PropertyDescriptorUtils.equals(this, other);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -595,25 +616,23 @@ class PropertyDescriptorUtils {
|
||||
* editor and flags are equivalent.
|
||||
* @see PropertyDescriptor#equals(Object)
|
||||
*/
|
||||
public static boolean equals(PropertyDescriptor pd1, Object obj) {
|
||||
if (pd1 == obj) {
|
||||
public static boolean equals(PropertyDescriptor pd, Object other) {
|
||||
if (pd == other) {
|
||||
return true;
|
||||
}
|
||||
if (obj != null && obj instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor pd2 = (PropertyDescriptor) obj;
|
||||
if (!compareMethods(pd1.getReadMethod(), pd2.getReadMethod())) {
|
||||
return false;
|
||||
}
|
||||
if (!compareMethods(pd1.getWriteMethod(), pd2.getWriteMethod())) {
|
||||
return false;
|
||||
}
|
||||
if (pd1.getPropertyType() == pd2.getPropertyType() &&
|
||||
pd1.getPropertyEditorClass() == pd2.getPropertyEditorClass() &&
|
||||
pd1.isBound() == pd2.isBound() && pd1.isConstrained() == pd2.isConstrained()) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof PropertyDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
PropertyDescriptor otherPd = (PropertyDescriptor) other;
|
||||
if (!compareMethods(pd.getReadMethod(), otherPd.getReadMethod())) {
|
||||
return false;
|
||||
}
|
||||
if (!compareMethods(pd.getWriteMethod(), otherPd.getWriteMethod())) {
|
||||
return false;
|
||||
}
|
||||
return (pd.getPropertyType() == otherPd.getPropertyType() &&
|
||||
pd.getPropertyEditorClass() == otherPd.getPropertyEditorClass() &&
|
||||
pd.isBound() == otherPd.isBound() && pd.isConstrained() == otherPd.isConstrained());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+48
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,6 +28,7 @@ import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -38,7 +39,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.2
|
||||
*/
|
||||
class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
|
||||
private final Class<?> beanClass;
|
||||
|
||||
@@ -46,13 +47,13 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
|
||||
private final Method writeMethod;
|
||||
|
||||
private final Class<?> propertyEditorClass;
|
||||
|
||||
private volatile Set<Method> ambiguousWriteMethods;
|
||||
|
||||
private MethodParameter writeMethodParameter;
|
||||
|
||||
private Class<?> propertyType;
|
||||
|
||||
private MethodParameter writeMethodParameter;
|
||||
private final Class<?> propertyEditorClass;
|
||||
|
||||
|
||||
public GenericTypeAwarePropertyDescriptor(Class<?> beanClass, String propertyName,
|
||||
@@ -60,8 +61,11 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
throws IntrospectionException {
|
||||
|
||||
super(propertyName, null, null);
|
||||
|
||||
if (beanClass == null) {
|
||||
throw new IntrospectionException("Bean class must not be null");
|
||||
}
|
||||
this.beanClass = beanClass;
|
||||
this.propertyEditorClass = propertyEditorClass;
|
||||
|
||||
Method readMethodToUse = BridgeMethodResolver.findBridgedMethod(readMethod);
|
||||
Method writeMethodToUse = BridgeMethodResolver.findBridgedMethod(writeMethod);
|
||||
@@ -93,8 +97,11 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
this.ambiguousWriteMethods = ambiguousCandidates;
|
||||
}
|
||||
}
|
||||
|
||||
this.propertyEditorClass = propertyEditorClass;
|
||||
}
|
||||
|
||||
|
||||
public Class<?> getBeanClass() {
|
||||
return this.beanClass;
|
||||
}
|
||||
@@ -120,9 +127,15 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
return this.writeMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getPropertyEditorClass() {
|
||||
return this.propertyEditorClass;
|
||||
public synchronized MethodParameter getWriteMethodParameter() {
|
||||
if (this.writeMethod == null) {
|
||||
return null;
|
||||
}
|
||||
if (this.writeMethodParameter == null) {
|
||||
this.writeMethodParameter = new MethodParameter(this.writeMethod, 0);
|
||||
GenericTypeResolver.resolveParameterType(this.writeMethodParameter, this.beanClass);
|
||||
}
|
||||
return this.writeMethodParameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,15 +157,34 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
return this.propertyType;
|
||||
}
|
||||
|
||||
public synchronized MethodParameter getWriteMethodParameter() {
|
||||
if (this.writeMethod == null) {
|
||||
return null;
|
||||
@Override
|
||||
public Class<?> getPropertyEditorClass() {
|
||||
return this.propertyEditorClass;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (this.writeMethodParameter == null) {
|
||||
this.writeMethodParameter = new MethodParameter(this.writeMethod, 0);
|
||||
GenericTypeResolver.resolveParameterType(this.writeMethodParameter, this.beanClass);
|
||||
if (!(other instanceof GenericTypeAwarePropertyDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
return this.writeMethodParameter;
|
||||
GenericTypeAwarePropertyDescriptor otherPd = (GenericTypeAwarePropertyDescriptor) other;
|
||||
return (getBeanClass().equals(otherPd.getBeanClass()) &&
|
||||
ObjectUtils.nullSafeEquals(getReadMethod(), otherPd.getReadMethod()) &&
|
||||
ObjectUtils.nullSafeEquals(getWriteMethod(), otherPd.getWriteMethod()) &&
|
||||
ObjectUtils.nullSafeEquals(getPropertyEditorClass(), otherPd.getPropertyEditorClass()) &&
|
||||
isBound() == otherPd.isBound() && isConstrained() == otherPd.isConstrained());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = getBeanClass().hashCode();
|
||||
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getReadMethod());
|
||||
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getWriteMethod());
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -263,6 +263,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
* Get the raw property value, if any.
|
||||
* @param propertyName the name to search for
|
||||
* @return the raw property value, or {@code null}
|
||||
* @since 4.0
|
||||
* @see #getPropertyValue(String)
|
||||
* @see PropertyValue#getValue()
|
||||
*/
|
||||
@@ -320,6 +321,16 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
this.processedProperties.add(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the "processed" registration of the given property, if any.
|
||||
* @since 3.2.13
|
||||
*/
|
||||
public void clearProcessedProperty(String propertyName) {
|
||||
if (this.processedProperties != null) {
|
||||
this.processedProperties.remove(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this holder as containing converted values only
|
||||
* (i.e. no runtime resolution needed anymore).
|
||||
|
||||
+13
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -47,4 +47,16 @@ public class NotReadablePropertyException extends InvalidPropertyException {
|
||||
super(beanClass, propertyName, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new NotReadablePropertyException.
|
||||
* @param beanClass the offending bean class
|
||||
* @param propertyName the offending property
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause
|
||||
* @since 4.0.9
|
||||
*/
|
||||
public NotReadablePropertyException(Class<?> beanClass, String propertyName, String msg, Throwable cause) {
|
||||
super(beanClass, propertyName, msg, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -89,7 +89,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
|
||||
|
||||
static {
|
||||
try {
|
||||
zoneIdClass = PropertyEditorRegistrySupport.class.getClassLoader().loadClass("java.time.ZoneId");
|
||||
zoneIdClass = ClassUtils.forName("java.time.ZoneId", PropertyEditorRegistrySupport.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Java 8 ZoneId class not available
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -172,7 +172,8 @@ final class PropertyMatches {
|
||||
char t_j = s2.charAt(j - 1);
|
||||
if (s_i == t_j) {
|
||||
cost = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
cost = 1;
|
||||
}
|
||||
d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -289,19 +289,19 @@ class TypeConverterDelegate {
|
||||
if (index > - 1) {
|
||||
String enumType = trimmedValue.substring(0, index);
|
||||
String fieldName = trimmedValue.substring(index + 1);
|
||||
ClassLoader loader = this.targetObject.getClass().getClassLoader();
|
||||
ClassLoader cl = this.targetObject.getClass().getClassLoader();
|
||||
try {
|
||||
Class<?> enumValueType = loader.loadClass(enumType);
|
||||
Class<?> enumValueType = ClassUtils.forName(enumType, cl);
|
||||
Field enumField = enumValueType.getField(fieldName);
|
||||
convertedValue = enumField.get(null);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
if(logger.isTraceEnabled()) {
|
||||
logger.trace("Enum class [" + enumType + "] cannot be loaded from [" + loader + "]", ex);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Enum class [" + enumType + "] cannot be loaded", ex);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Field [" + fieldName + "] isn't an enum value for type [" + enumType + "]", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -170,8 +170,7 @@ public interface BeanFactory {
|
||||
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
|
||||
* overriding the specified default arguments (if any) in the bean definition.
|
||||
* @param name the name of the bean to retrieve
|
||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
||||
* @param args arguments to use if creating a prototype using explicit arguments
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||
* @throws BeanDefinitionStoreException if arguments have been given but
|
||||
|
||||
+7
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,21 +20,23 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Exception thrown when a {@code BeanFactory} is asked for a bean instance
|
||||
* for which it cannot find a definition.
|
||||
* Exception thrown when a {@code BeanFactory} is asked for a bean instance for which it
|
||||
* cannot find a definition. This may point to a non-existing bean, a non-unique bean,
|
||||
* or a manually registered singleton instance without an associated bean definition.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @see BeanFactory#getBean(String)
|
||||
* @see BeanFactory#getBean(Class)
|
||||
* @see NoUniqueBeanDefinitionException
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class NoSuchBeanDefinitionException extends BeansException {
|
||||
|
||||
/** Name of the missing bean. */
|
||||
/** Name of the missing bean */
|
||||
private String beanName;
|
||||
|
||||
/** Required type of the missing bean. */
|
||||
/** Required type of the missing bean */
|
||||
private Class<?> beanType;
|
||||
|
||||
|
||||
|
||||
+47
-33
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -135,9 +135,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
public AutowiredAnnotationBeanPostProcessor() {
|
||||
this.autowiredAnnotationTypes.add(Autowired.class);
|
||||
this.autowiredAnnotationTypes.add(Value.class);
|
||||
ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();
|
||||
try {
|
||||
this.autowiredAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
|
||||
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
|
||||
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
|
||||
logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
@@ -218,7 +218,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
if (beanType != null) {
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType);
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
|
||||
metadata.checkConfigMembers(beanDefinition);
|
||||
}
|
||||
}
|
||||
@@ -236,24 +236,25 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
Constructor<?> requiredConstructor = null;
|
||||
Constructor<?> defaultConstructor = null;
|
||||
for (Constructor<?> candidate : rawCandidates) {
|
||||
AnnotationAttributes annotation = findAutowiredAnnotation(candidate);
|
||||
if (annotation != null) {
|
||||
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
|
||||
if (ann != null) {
|
||||
if (requiredConstructor != null) {
|
||||
throw new BeanCreationException("Invalid autowire-marked constructor: " + candidate +
|
||||
". Found another constructor with 'required' Autowired annotation: " +
|
||||
throw new BeanCreationException(beanName,
|
||||
"Invalid autowire-marked constructor: " + candidate +
|
||||
". Found constructor with 'required' Autowired annotation already: " +
|
||||
requiredConstructor);
|
||||
}
|
||||
if (candidate.getParameterTypes().length == 0) {
|
||||
throw new IllegalStateException(
|
||||
"Autowired annotation requires at least one argument: " + candidate);
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
boolean required = determineRequiredStatus(ann);
|
||||
if (required) {
|
||||
if (!candidates.isEmpty()) {
|
||||
throw new BeanCreationException(
|
||||
throw new BeanCreationException(beanName,
|
||||
"Invalid autowire-marked constructors: " + candidates +
|
||||
". Found another constructor with 'required' Autowired annotation: " +
|
||||
requiredConstructor);
|
||||
". Found constructor with 'required' Autowired annotation: " +
|
||||
candidate);
|
||||
}
|
||||
requiredConstructor = candidate;
|
||||
}
|
||||
@@ -265,8 +266,16 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
}
|
||||
if (!candidates.isEmpty()) {
|
||||
// Add default constructor to list of optional constructors, as fallback.
|
||||
if (requiredConstructor == null && defaultConstructor != null) {
|
||||
candidates.add(defaultConstructor);
|
||||
if (requiredConstructor == null) {
|
||||
if (defaultConstructor != null) {
|
||||
candidates.add(defaultConstructor);
|
||||
}
|
||||
else if (candidates.size() == 1 && logger.isWarnEnabled()) {
|
||||
logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
|
||||
"': single autowire-marked constructor flagged as optional - this constructor " +
|
||||
"is effectively required since there is no default constructor to fall back to: " +
|
||||
candidates.get(0));
|
||||
}
|
||||
}
|
||||
candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);
|
||||
}
|
||||
@@ -284,7 +293,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
|
||||
try {
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
@@ -302,7 +311,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
*/
|
||||
public void processInjection(Object bean) throws BeansException {
|
||||
Class<?> clazz = bean.getClass();
|
||||
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz);
|
||||
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
|
||||
try {
|
||||
metadata.inject(bean, null, null);
|
||||
}
|
||||
@@ -312,15 +321,18 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
}
|
||||
|
||||
|
||||
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz) {
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
|
||||
// Fall back to class name as cache key, for backwards compatibility with custom callers.
|
||||
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
|
||||
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
|
||||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(cacheKey);
|
||||
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
|
||||
if (metadata != null) {
|
||||
metadata.clear(pvs);
|
||||
}
|
||||
metadata = buildAutowiringMetadata(clazz);
|
||||
this.injectionMetadataCache.put(cacheKey, metadata);
|
||||
}
|
||||
@@ -336,23 +348,25 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
do {
|
||||
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
for (Field field : targetClass.getDeclaredFields()) {
|
||||
AnnotationAttributes annotation = findAutowiredAnnotation(field);
|
||||
if (annotation != null) {
|
||||
AnnotationAttributes ann = findAutowiredAnnotation(field);
|
||||
if (ann != null) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation is not supported on static fields: " + field);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
boolean required = determineRequiredStatus(ann);
|
||||
currElements.add(new AutowiredFieldElement(field, required));
|
||||
}
|
||||
}
|
||||
for (Method method : targetClass.getDeclaredMethods()) {
|
||||
AnnotationAttributes ann = null;
|
||||
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
|
||||
AnnotationAttributes annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
|
||||
findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method);
|
||||
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
|
||||
ann = findAutowiredAnnotation(bridgedMethod);
|
||||
}
|
||||
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation is not supported on static methods: " + method);
|
||||
@@ -364,8 +378,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
|
||||
}
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
boolean required = determineRequiredStatus(ann);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
|
||||
currElements.add(new AutowiredMethodElement(method, required, pd));
|
||||
}
|
||||
}
|
||||
@@ -379,9 +393,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
|
||||
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
|
||||
AnnotationAttributes annotation = AnnotatedElementUtils.getAnnotationAttributes(ao, type.getName());
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
AnnotationAttributes ann = AnnotatedElementUtils.getAnnotationAttributes(ao, type.getName());
|
||||
if (ann != null) {
|
||||
return ann;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -392,12 +406,12 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
* <p>A 'required' dependency means that autowiring should fail when no beans
|
||||
* are found. Otherwise, the autowiring process will simply bypass the field
|
||||
* or method when no beans are found.
|
||||
* @param annotation the Autowired annotation
|
||||
* @param ann the Autowired annotation
|
||||
* @return whether the annotation indicates that a dependency is required
|
||||
*/
|
||||
protected boolean determineRequiredStatus(AnnotationAttributes annotation) {
|
||||
return (!annotation.containsKey(this.requiredParameterName) ||
|
||||
this.requiredParameterValue == annotation.getBoolean(this.requiredParameterName));
|
||||
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
|
||||
return (!ann.containsKey(this.requiredParameterName) ||
|
||||
this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+8
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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,6 +34,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* Spring's {@link Qualifier @Qualifier} annotation.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1.2
|
||||
* @see BeanFactoryUtils
|
||||
*/
|
||||
@@ -90,9 +91,13 @@ public class BeanFactoryAnnotationUtils {
|
||||
if (matchingBean != null) {
|
||||
return matchingBean;
|
||||
}
|
||||
else if (bf.containsBean(qualifier)) {
|
||||
// Fallback: target bean at least found by bean name - probably a manually registered singleton.
|
||||
return bf.getBean(qualifier, beanType);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(qualifier, "No matching " + beanType.getSimpleName() +
|
||||
" bean found for qualifier '" + qualifier + "' - neither qualifier " + "match nor bean name match!");
|
||||
" bean found for qualifier '" + qualifier + "' - neither qualifier match nor bean name match!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +133,7 @@ public class BeanFactoryAnnotationUtils {
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// ignore - can't compare qualifiers for a manually registered singleton object
|
||||
// Ignore - can't compare qualifiers for a manually registered singleton object
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
+32
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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 @@ import org.springframework.util.ReflectionUtils;
|
||||
*/
|
||||
public class InjectionMetadata {
|
||||
|
||||
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||
|
||||
private final Class<?> targetClass;
|
||||
|
||||
@@ -60,6 +60,7 @@ public class InjectionMetadata {
|
||||
this.injectedElements = elements;
|
||||
}
|
||||
|
||||
|
||||
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
||||
Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
|
||||
for (InjectedElement element : this.injectedElements) {
|
||||
@@ -82,13 +83,26 @@ public class InjectionMetadata {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (InjectedElement element : elementsToIterate) {
|
||||
if (debug) {
|
||||
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
|
||||
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
|
||||
}
|
||||
element.inject(target, beanName, pvs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.13
|
||||
*/
|
||||
public void clear(PropertyValues pvs) {
|
||||
Collection<InjectedElement> elementsToIterate =
|
||||
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
|
||||
if (!elementsToIterate.isEmpty()) {
|
||||
for (InjectedElement element : elementsToIterate) {
|
||||
element.clearPropertySkipping(pvs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean needsRefresh(InjectionMetadata metadata, Class<?> clazz) {
|
||||
return (metadata == null || !metadata.targetClass.equals(clazz));
|
||||
@@ -170,7 +184,7 @@ public class InjectionMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this injector's property needs to be skipped due to
|
||||
* Check whether this injector's property needs to be skipped due to
|
||||
* an explicit property value having been specified. Also marks the
|
||||
* affected property as processed for other processors to ignore it.
|
||||
*/
|
||||
@@ -201,6 +215,20 @@ public class InjectionMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.13
|
||||
*/
|
||||
protected void clearPropertySkipping(PropertyValues pvs) {
|
||||
if (pvs == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (pvs) {
|
||||
if (Boolean.FALSE.equals(this.skip) && this.pd != null && pvs instanceof MutablePropertyValues) {
|
||||
((MutablePropertyValues) pvs).clearProcessedProperty(this.pd.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Either this or {@link #inject} needs to be overridden.
|
||||
*/
|
||||
|
||||
+13
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
@@ -53,7 +54,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {
|
||||
|
||||
private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<Class<? extends Annotation>>();
|
||||
private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<Class<? extends Annotation>>(2);
|
||||
|
||||
private Class<? extends Annotation> valueAnnotationType = Value.class;
|
||||
|
||||
@@ -66,9 +67,9 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||
@SuppressWarnings("unchecked")
|
||||
public QualifierAnnotationAutowireCandidateResolver() {
|
||||
this.qualifierTypes.add(Qualifier.class);
|
||||
ClassLoader cl = QualifierAnnotationAutowireCandidateResolver.class.getClassLoader();
|
||||
try {
|
||||
this.qualifierTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Qualifier"));
|
||||
this.qualifierTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Qualifier",
|
||||
QualifierAnnotationAutowireCandidateResolver.class.getClassLoader()));
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// JSR-330 API not available - simply skip.
|
||||
@@ -233,9 +234,14 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||
if (targetAnnotation == null) {
|
||||
// Look for matching annotation on the target class
|
||||
if (getBeanFactory() != null) {
|
||||
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
|
||||
if (beanType != null) {
|
||||
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
|
||||
try {
|
||||
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
|
||||
if (beanType != null) {
|
||||
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// Not the usual case - simply forget about the type check...
|
||||
}
|
||||
}
|
||||
if (targetAnnotation == null && bd.hasBeanClass()) {
|
||||
|
||||
+5
-4
@@ -286,7 +286,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
// Use prototype bean definition, to avoid registering bean as dependent bean.
|
||||
RootBeanDefinition bd = new RootBeanDefinition(beanClass);
|
||||
bd.setScope(SCOPE_PROTOTYPE);
|
||||
bd.allowCaching = false;
|
||||
bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
|
||||
return (T) createBean(beanClass.getName(), bd, null);
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.allowCaching = false;
|
||||
bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader());
|
||||
BeanWrapper bw = new BeanWrapperImpl(existingBean);
|
||||
initBeanWrapper(bw);
|
||||
populateBean(bd.getBeanClass().getName(), bd, bw);
|
||||
@@ -315,7 +315,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
bd = new RootBeanDefinition(mbd);
|
||||
}
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.allowCaching = false;
|
||||
bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
|
||||
}
|
||||
BeanWrapper bw = new BeanWrapperImpl(existingBean);
|
||||
initBeanWrapper(bw);
|
||||
@@ -832,7 +832,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (bw != null) {
|
||||
return (FactoryBean<?>) bw.getWrappedInstance();
|
||||
}
|
||||
if (isSingletonCurrentlyInCreation(beanName)) {
|
||||
if (isSingletonCurrentlyInCreation(beanName) ||
|
||||
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
|
||||
return null;
|
||||
}
|
||||
Object instance = null;
|
||||
|
||||
+12
-9
@@ -38,8 +38,8 @@ import org.springframework.util.StringUtils;
|
||||
/**
|
||||
* Base class for concrete, full-fledged
|
||||
* {@link org.springframework.beans.factory.config.BeanDefinition} classes,
|
||||
* factoring out common properties of {@link RootBeanDefinition} and
|
||||
* {@link ChildBeanDefinition}.
|
||||
* factoring out common properties of {@link GenericBeanDefinition},
|
||||
* {@link RootBeanDefinition} and {@link ChildBeanDefinition}.
|
||||
*
|
||||
* <p>The autowire constants match the ones defined in the
|
||||
* {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
|
||||
@@ -123,11 +123,14 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
public static final int DEPENDENCY_CHECK_ALL = 3;
|
||||
|
||||
/**
|
||||
* Constant that indicates the container should attempt to infer the {@link
|
||||
* #setDestroyMethodName destroy method name} for a bean as opposed to explicit
|
||||
* specification of a method name. The value {@value} is specifically designed to
|
||||
* include characters otherwise illegal in a method name, ensuring no possibility of
|
||||
* collisions with legitimately named methods having the same name.
|
||||
* Constant that indicates the container should attempt to infer the
|
||||
* {@link #setDestroyMethodName destroy method name} for a bean as opposed to
|
||||
* explicit specification of a method name. The value {@value} is specifically
|
||||
* designed to include characters otherwise illegal in a method name, ensuring
|
||||
* no possibility of collisions with legitimately named methods having the same
|
||||
* name.
|
||||
* <p>Currently, the method names detected during destroy method inference
|
||||
* are "close" and "shutdown", if present on the specific bean class.
|
||||
*/
|
||||
public static final String INFER_METHOD = "(inferred)";
|
||||
|
||||
@@ -644,8 +647,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
|
||||
/**
|
||||
* Specify whether to allow access to non-public constructors and methods,
|
||||
* for the case of externalized metadata pointing to those.
|
||||
* The default is {@code true}; switch this to {@false} for public access only.
|
||||
* for the case of externalized metadata pointing to those. The default is
|
||||
* {@code true}; switch this to {@code false} for public access only.
|
||||
* <p>This applies to constructor resolution, factory method resolution,
|
||||
* and also init/destroy methods. Bean property accessors have to be public
|
||||
* in any case and are not affected by this setting.
|
||||
|
||||
+11
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -124,7 +124,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
/** Resolution strategy for expressions in bean definition values */
|
||||
private BeanExpressionResolver beanExpressionResolver;
|
||||
|
||||
/** Spring 3.0 ConversionService to use instead of PropertyEditors */
|
||||
/** Spring ConversionService to use instead of PropertyEditors */
|
||||
private ConversionService conversionService;
|
||||
|
||||
/** Custom PropertyEditorRegistrars to apply to the beans of this factory */
|
||||
@@ -160,9 +160,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
|
||||
new ConcurrentHashMap<String, RootBeanDefinition>(64);
|
||||
|
||||
/**
|
||||
* Names of beans that have already been created at least once
|
||||
*/
|
||||
/** Names of beans that have already been created at least once */
|
||||
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(64));
|
||||
|
||||
/** Names of beans that are currently in creation */
|
||||
@@ -287,8 +285,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
if (dependsOn != null) {
|
||||
for (String dependsOnBean : dependsOn) {
|
||||
if (isDependent(beanName, dependsOnBean)) {
|
||||
throw new BeanCreationException("Circular depends-on relationship between '" +
|
||||
beanName + "' and '" + dependsOnBean + "'");
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
|
||||
}
|
||||
registerDependentBean(dependsOnBean, beanName);
|
||||
getBean(dependsOnBean);
|
||||
@@ -961,7 +959,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
|
||||
@Override
|
||||
public boolean isActuallyInCreation(String beanName) {
|
||||
return isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName);
|
||||
return (isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1276,7 +1274,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
// Check validity of the usage of the args parameter. This can
|
||||
// only be used for prototypes constructed via a factory method.
|
||||
if (args != null && !mbd.isPrototype()) {
|
||||
throw new BeanDefinitionStoreException(
|
||||
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
|
||||
"Can only specify arguments for the getBean method when referring to a prototype bean definition");
|
||||
}
|
||||
}
|
||||
@@ -1437,7 +1435,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @param beanName the name of the bean
|
||||
*/
|
||||
protected void markBeanAsCreated(String beanName) {
|
||||
this.alreadyCreated.add(beanName);
|
||||
if (!this.alreadyCreated.contains(beanName)) {
|
||||
this.alreadyCreated.add(beanName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1627,8 +1627,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* instantiation within this class is performed by this method.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the merged bean definition for the bean
|
||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
||||
* static factory method. This parameter must be {@code null} except in this case.
|
||||
* @param args arguments to use if creating a prototype using explicit arguments
|
||||
* @return a new instance of the bean
|
||||
* @throws BeanCreationException if the bean could not be created
|
||||
*/
|
||||
|
||||
+15
-21
@@ -25,7 +25,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
import org.springframework.cglib.core.SpringNamingPolicy;
|
||||
import org.springframework.cglib.proxy.Callback;
|
||||
import org.springframework.cglib.proxy.CallbackFilter;
|
||||
@@ -89,14 +88,13 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
*/
|
||||
private static class CglibSubclassCreator {
|
||||
|
||||
private static final Class<?>[] CALLBACK_TYPES = new Class<?>[] { NoOp.class,
|
||||
LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class };
|
||||
private static final Class<?>[] CALLBACK_TYPES = new Class<?>[]
|
||||
{NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class};
|
||||
|
||||
private final RootBeanDefinition beanDefinition;
|
||||
|
||||
private final BeanFactory owner;
|
||||
|
||||
|
||||
CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
|
||||
this.beanDefinition = beanDefinition;
|
||||
this.owner = owner;
|
||||
@@ -113,7 +111,6 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
*/
|
||||
Object instantiate(Constructor<?> ctor, Object[] args) {
|
||||
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
|
||||
|
||||
Object instance;
|
||||
if (ctor == null) {
|
||||
instance = BeanUtils.instantiate(subclass);
|
||||
@@ -123,19 +120,17 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
|
||||
instance = enhancedSubclassConstructor.newInstance(args);
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (Exception ex) {
|
||||
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(), String.format(
|
||||
"Failed to invoke construcor for CGLIB enhanced subclass [%s]", subclass.getName()), e);
|
||||
"Failed to invoke constructor for CGLIB enhanced subclass [%s]", subclass.getName()), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// SPR-10785: set callbacks directly on the instance instead of in the
|
||||
// enhanced class (via the Enhancer) in order to avoid memory leaks.
|
||||
Factory factory = (Factory) instance;
|
||||
factory.setCallbacks(new Callback[] { NoOp.INSTANCE,//
|
||||
new LookupOverrideMethodInterceptor(beanDefinition, owner),//
|
||||
new ReplaceOverrideMethodInterceptor(beanDefinition, owner) });
|
||||
|
||||
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
|
||||
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
|
||||
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -153,6 +148,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class providing hashCode and equals methods required by CGLIB to
|
||||
* ensure that CGLIB doesn't generate a distinct class per bean.
|
||||
@@ -162,7 +158,6 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
|
||||
private final RootBeanDefinition beanDefinition;
|
||||
|
||||
|
||||
CglibIdentitySupport(RootBeanDefinition beanDefinition) {
|
||||
this.beanDefinition = beanDefinition;
|
||||
}
|
||||
@@ -173,8 +168,8 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other.getClass().equals(this.getClass())
|
||||
&& ((CglibIdentitySupport) other).getBeanDefinition().equals(this.getBeanDefinition());
|
||||
return (getClass().equals(other.getClass()) &&
|
||||
this.beanDefinition.equals(((CglibIdentitySupport) other).beanDefinition));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,6 +178,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CGLIB callback for filtering method interception behavior.
|
||||
*/
|
||||
@@ -190,7 +186,6 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
|
||||
private static final Log logger = LogFactory.getLog(MethodOverrideCallbackFilter.class);
|
||||
|
||||
|
||||
MethodOverrideCallbackFilter(RootBeanDefinition beanDefinition) {
|
||||
super(beanDefinition);
|
||||
}
|
||||
@@ -210,11 +205,12 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
else if (methodOverride instanceof ReplaceOverride) {
|
||||
return METHOD_REPLACER;
|
||||
}
|
||||
throw new UnsupportedOperationException("Unexpected MethodOverride subclass: "
|
||||
+ methodOverride.getClass().getName());
|
||||
throw new UnsupportedOperationException("Unexpected MethodOverride subclass: " +
|
||||
methodOverride.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CGLIB MethodInterceptor to override methods, replacing them with an
|
||||
* implementation that returns a bean looked up in the container.
|
||||
@@ -223,7 +219,6 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
|
||||
private final BeanFactory owner;
|
||||
|
||||
|
||||
LookupOverrideMethodInterceptor(RootBeanDefinition beanDefinition, BeanFactory owner) {
|
||||
super(beanDefinition);
|
||||
this.owner = owner;
|
||||
@@ -245,7 +240,6 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
|
||||
private final BeanFactory owner;
|
||||
|
||||
|
||||
ReplaceOverrideMethodInterceptor(RootBeanDefinition beanDefinition, BeanFactory owner) {
|
||||
super(beanDefinition);
|
||||
this.owner = owner;
|
||||
@@ -255,7 +249,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
|
||||
ReplaceOverride ro = (ReplaceOverride) getBeanDefinition().getMethodOverrides().getOverride(method);
|
||||
// TODO could cache if a singleton for minor performance optimization
|
||||
MethodReplacer mr = owner.getBean(ro.getMethodReplacerBeanName(), MethodReplacer.class);
|
||||
MethodReplacer mr = this.owner.getBean(ro.getMethodReplacerBeanName(), MethodReplacer.class);
|
||||
return mr.reimplement(obj, method, args);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -370,7 +370,7 @@ class ConstructorResolver {
|
||||
factoryBean = this.beanFactory.getBean(factoryBeanName);
|
||||
if (factoryBean == null) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"factory-bean '" + factoryBeanName + "' returned null");
|
||||
"factory-bean '" + factoryBeanName + "' (or a BeanPostProcessor involved) returned null");
|
||||
}
|
||||
factoryClass = factoryBean.getClass();
|
||||
isStatic = false;
|
||||
|
||||
+27
-12
@@ -105,9 +105,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
private static Class<?> javaxInjectProviderClass = null;
|
||||
|
||||
static {
|
||||
ClassLoader cl = DefaultListableBeanFactory.class.getClassLoader();
|
||||
try {
|
||||
javaxInjectProviderClass = cl.loadClass("javax.inject.Provider");
|
||||
javaxInjectProviderClass =
|
||||
ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// JSR-330 API not available - Provider interface simply not supported then.
|
||||
@@ -140,14 +140,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
/** Map of bean definition objects, keyed by bean name */
|
||||
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
|
||||
|
||||
/** Map of singleton and non-singleton bean names keyed by dependency type */
|
||||
/** Map of singleton and non-singleton bean names, keyed by dependency type */
|
||||
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
|
||||
|
||||
/** Map of singleton-only bean names keyed by dependency type */
|
||||
/** Map of singleton-only bean names, keyed by dependency type */
|
||||
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
|
||||
|
||||
/** List of bean definition names, in registration order */
|
||||
private final List<String> beanDefinitionNames = new ArrayList<String>();
|
||||
private final List<String> beanDefinitionNames = new ArrayList<String>(64);
|
||||
|
||||
/** Whether bean definition metadata may be cached for all beans */
|
||||
private boolean configurationFrozen = false;
|
||||
@@ -284,7 +284,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (beanNames.length > 1) {
|
||||
ArrayList<String> autowireCandidates = new ArrayList<String>();
|
||||
for (String beanName : beanNames) {
|
||||
if (getBeanDefinition(beanName).isAutowireCandidate()) {
|
||||
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
|
||||
autowireCandidates.add(beanName);
|
||||
}
|
||||
}
|
||||
@@ -671,12 +671,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Pre-instantiating singletons in " + this);
|
||||
}
|
||||
|
||||
List<String> beanNames;
|
||||
synchronized (this.beanDefinitionMap) {
|
||||
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
|
||||
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
|
||||
beanNames = new ArrayList<String>(this.beanDefinitionNames);
|
||||
}
|
||||
|
||||
// Trigger initialization of all non-lazy singleton beans...
|
||||
for (String beanName : beanNames) {
|
||||
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
|
||||
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
|
||||
@@ -728,8 +731,10 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
|
||||
BeanDefinition oldBeanDefinition;
|
||||
|
||||
synchronized (this.beanDefinitionMap) {
|
||||
BeanDefinition oldBeanDefinition = this.beanDefinitionMap.get(beanName);
|
||||
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
|
||||
if (oldBeanDefinition != null) {
|
||||
if (!this.allowBeanDefinitionOverriding) {
|
||||
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
|
||||
@@ -758,7 +763,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
this.beanDefinitionMap.put(beanName, beanDefinition);
|
||||
}
|
||||
|
||||
resetBeanDefinition(beanName);
|
||||
if (oldBeanDefinition != null || containsSingleton(beanName)) {
|
||||
resetBeanDefinition(beanName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -794,9 +801,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
// (e.g. the default StaticMessageSource in a StaticApplicationContext).
|
||||
destroySingleton(beanName);
|
||||
|
||||
// Remove any assumptions about by-type mappings.
|
||||
clearByTypeCache();
|
||||
|
||||
// Reset all bean definitions that have the given bean as parent (recursively).
|
||||
for (String bdName : this.beanDefinitionNames) {
|
||||
if (!beanName.equals(bdName)) {
|
||||
@@ -1013,7 +1017,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
for (String candidateName : candidateNames) {
|
||||
if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) {
|
||||
if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, descriptor)) {
|
||||
result.put(candidateName, getBean(candidateName));
|
||||
}
|
||||
}
|
||||
@@ -1091,6 +1095,17 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
(candidateName.equals(beanName) || ObjectUtils.containsElement(getAliases(beanName), candidateName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given beanName/candidateName pair indicates a self reference,
|
||||
* i.e. whether the candidate points back to the original bean or to a factory method
|
||||
* on the original bean.
|
||||
*/
|
||||
private boolean isSelfReference(String beanName, String candidateName) {
|
||||
return (beanName != null && candidateName != null &&
|
||||
(beanName.equals(candidateName) || (containsBeanDefinition(candidateName) &&
|
||||
beanName.equals(getMergedLocalBeanDefinition(candidateName).getFactoryBeanName()))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Raise a NoSuchBeanDefinitionException for an unresolvable dependency.
|
||||
*/
|
||||
|
||||
+20
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -277,7 +278,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
|
||||
@Override
|
||||
public boolean containsSingleton(String beanName) {
|
||||
return (this.singletonObjects.containsKey(beanName));
|
||||
return this.singletonObjects.containsKey(beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -330,8 +331,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* @see #isSingletonCurrentlyInCreation
|
||||
*/
|
||||
protected void beforeSingletonCreation(String beanName) {
|
||||
if (!this.inCreationCheckExclusions.contains(beanName) &&
|
||||
!this.singletonsCurrentlyInCreation.add(beanName)) {
|
||||
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
|
||||
throw new BeanCurrentlyInCreationException(beanName);
|
||||
}
|
||||
}
|
||||
@@ -343,8 +343,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* @see #isSingletonCurrentlyInCreation
|
||||
*/
|
||||
protected void afterSingletonCreation(String beanName) {
|
||||
if (!this.inCreationCheckExclusions.contains(beanName) &&
|
||||
!this.singletonsCurrentlyInCreation.remove(beanName)) {
|
||||
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
|
||||
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
|
||||
}
|
||||
}
|
||||
@@ -417,9 +416,18 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* dependent on the given bean or on any of its transitive dependencies.
|
||||
* @param beanName the name of the bean to check
|
||||
* @param dependentBeanName the name of the dependent bean
|
||||
* @since 4.0
|
||||
*/
|
||||
protected boolean isDependent(String beanName, String dependentBeanName) {
|
||||
Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
|
||||
return isDependent(beanName, dependentBeanName, null);
|
||||
}
|
||||
|
||||
private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
|
||||
String canonicalName = canonicalName(beanName);
|
||||
if (alreadySeen != null && alreadySeen.contains(beanName)) {
|
||||
return false;
|
||||
}
|
||||
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
|
||||
if (dependentBeans == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -427,7 +435,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
return true;
|
||||
}
|
||||
for (String transitiveDependency : dependentBeans) {
|
||||
if (isDependent(transitiveDependency, dependentBeanName)) {
|
||||
if (alreadySeen == null) {
|
||||
alreadySeen = new HashSet<String>();
|
||||
}
|
||||
alreadySeen.add(beanName);
|
||||
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -69,7 +69,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
|
||||
static {
|
||||
try {
|
||||
closeableInterface = DisposableBeanAdapter.class.getClassLoader().loadClass("java.lang.AutoCloseable");
|
||||
closeableInterface = ClassUtils.forName("java.lang.AutoCloseable",
|
||||
DisposableBeanAdapter.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
closeableInterface = Closeable.class;
|
||||
|
||||
+32
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -90,7 +90,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
* Obtain an object to expose from the given FactoryBean.
|
||||
* @param factory the FactoryBean instance
|
||||
* @param beanName the name of the bean
|
||||
* @param shouldPostProcess whether the bean is subject for post-processing
|
||||
* @param shouldPostProcess whether the bean is subject to post-processing
|
||||
* @return the object obtained from the FactoryBean
|
||||
* @throws BeanCreationException if FactoryBean object creation failed
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||
@@ -100,14 +100,40 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
synchronized (getSingletonMutex()) {
|
||||
Object object = this.factoryBeanObjectCache.get(beanName);
|
||||
if (object == null) {
|
||||
object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
|
||||
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
|
||||
object = doGetObjectFromFactoryBean(factory, beanName);
|
||||
// Only post-process and store if not put there already during getObject() call above
|
||||
// (e.g. because of circular reference processing triggered by custom getBean calls)
|
||||
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
|
||||
if (alreadyThere != null) {
|
||||
object = alreadyThere;
|
||||
}
|
||||
else {
|
||||
if (object != null && shouldPostProcess) {
|
||||
try {
|
||||
object = postProcessObjectFromFactoryBean(object, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName,
|
||||
"Post-processing of FactoryBean's singleton object failed", ex);
|
||||
}
|
||||
}
|
||||
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
|
||||
}
|
||||
}
|
||||
return (object != NULL_OBJECT ? object : null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
|
||||
Object object = doGetObjectFromFactoryBean(factory, beanName);
|
||||
if (object != null && shouldPostProcess) {
|
||||
try {
|
||||
object = postProcessObjectFromFactoryBean(object, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,13 +141,11 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
* Obtain an object to expose from the given FactoryBean.
|
||||
* @param factory the FactoryBean instance
|
||||
* @param beanName the name of the bean
|
||||
* @param shouldPostProcess whether the bean is subject for post-processing
|
||||
* @return the object obtained from the FactoryBean
|
||||
* @throws BeanCreationException if FactoryBean object creation failed
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||
*/
|
||||
private Object doGetObjectFromFactoryBean(
|
||||
final FactoryBean<?> factory, final String beanName, final boolean shouldPostProcess)
|
||||
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
|
||||
throws BeanCreationException {
|
||||
|
||||
Object object;
|
||||
@@ -151,23 +175,12 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
|
||||
}
|
||||
|
||||
|
||||
// Do not accept a null value for a FactoryBean that's not fully
|
||||
// initialized yet: Many FactoryBeans just return null then.
|
||||
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
|
||||
throw new BeanCurrentlyInCreationException(
|
||||
beanName, "FactoryBean which is currently in creation returned null from getObject");
|
||||
}
|
||||
|
||||
if (object != null && shouldPostProcess) {
|
||||
try {
|
||||
object = postProcessObjectFromFactoryBean(object, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -89,7 +89,12 @@ public class GenericBeanDefinition extends AbstractBeanDefinition {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Generic bean: " + super.toString();
|
||||
StringBuilder sb = new StringBuilder("Generic bean");
|
||||
if (this.parentName != null) {
|
||||
sb.append(" with parent '").append(this.parentName).append("'");
|
||||
}
|
||||
sb.append(": ").append(super.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-6
@@ -37,8 +37,7 @@ public class LookupOverride extends MethodOverride {
|
||||
|
||||
/**
|
||||
* Construct a new LookupOverride.
|
||||
* @param methodName the name of the method to override.
|
||||
* This method must have no arguments.
|
||||
* @param methodName the name of the method to override
|
||||
* @param beanName the name of the bean in the current BeanFactory
|
||||
* that the overridden method should return
|
||||
*/
|
||||
@@ -48,6 +47,7 @@ public class LookupOverride extends MethodOverride {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the name of the bean that should be returned by this method.
|
||||
*/
|
||||
@@ -63,10 +63,6 @@ public class LookupOverride extends MethodOverride {
|
||||
return (method.getName().equals(getMethodName()) && method.getParameterTypes().length == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LookupOverride for method '" + getMethodName() + "'; will return bean '" + this.beanName + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
@@ -79,4 +75,9 @@ public class LookupOverride extends MethodOverride {
|
||||
return (29 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.beanName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LookupOverride for method '" + getMethodName() + "'";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
@@ -52,6 +52,7 @@ public abstract class MethodOverride implements BeanMetadataElement {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the name of the method to be overridden.
|
||||
*/
|
||||
@@ -99,6 +100,7 @@ public abstract class MethodOverride implements BeanMetadataElement {
|
||||
*/
|
||||
public abstract boolean matches(Method method);
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
|
||||
+9
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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 @@ public class ReplaceOverride extends MethodOverride {
|
||||
this.methodReplacerBeanName = methodReplacerBeanName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the name of the bean implementing MethodReplacer.
|
||||
*/
|
||||
@@ -68,28 +69,22 @@ public class ReplaceOverride extends MethodOverride {
|
||||
this.typeIdentifiers.add(identifier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method) {
|
||||
// TODO could cache result for efficiency
|
||||
if (!method.getName().equals(getMethodName())) {
|
||||
// It can't match.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isOverloaded()) {
|
||||
// No overloaded: don't worry about arg type matching.
|
||||
// Not overloaded: don't worry about arg type matching...
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we get to here, we need to insist on precise argument matching.
|
||||
// If we get here, we need to insist on precise argument matching...
|
||||
if (this.typeIdentifiers.size() != method.getParameterTypes().length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < this.typeIdentifiers.size(); i++) {
|
||||
String identifier = this.typeIdentifiers.get(i);
|
||||
if (!method.getParameterTypes()[i].getName().contains(identifier)) {
|
||||
// This parameter cannot match.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -97,12 +92,6 @@ public class ReplaceOverride extends MethodOverride {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Replace override for method '" + getMethodName() + "; will call bean '" +
|
||||
this.methodReplacerBeanName + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ReplaceOverride) || !super.equals(other)) {
|
||||
@@ -121,4 +110,9 @@ public class ReplaceOverride extends MethodOverride {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Replace override for method '" + getMethodName() + "'";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -133,7 +133,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
public Object getBean(String name, Object... args) throws BeansException {
|
||||
if (args != null) {
|
||||
throw new UnsupportedOperationException(
|
||||
"StaticListableBeanFactory does not support explicit bean creation arguments)");
|
||||
"StaticListableBeanFactory does not support explicit bean creation arguments");
|
||||
}
|
||||
return getBean(name);
|
||||
}
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ public abstract class AbstractSimpleBeanDefinitionParser extends AbstractSingleB
|
||||
*/
|
||||
protected boolean isEligibleAttribute(Attr attribute, ParserContext parserContext) {
|
||||
boolean eligible = isEligibleAttribute(attribute);
|
||||
if(!eligible) {
|
||||
if (!eligible) {
|
||||
String fullName = attribute.getName();
|
||||
eligible = (!fullName.equals("xmlns") && !fullName.startsWith("xmlns:") &&
|
||||
isEligibleAttribute(parserContext.getDelegate().getLocalName(attribute)));
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -41,7 +41,9 @@ public interface BeanDefinitionDocumentReader {
|
||||
* Set the Environment to use when reading bean definitions.
|
||||
* <p>Used for evaluating profile information to determine whether a
|
||||
* {@code <beans/>} document/element should be included or ignored.
|
||||
* @deprecated in favor of Environment access via XmlReaderContext
|
||||
*/
|
||||
@Deprecated
|
||||
void setEnvironment(Environment environment);
|
||||
|
||||
/**
|
||||
|
||||
+20
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -59,7 +59,6 @@ import org.springframework.beans.factory.support.ManagedSet;
|
||||
import org.springframework.beans.factory.support.MethodOverrides;
|
||||
import org.springframework.beans.factory.support.ReplaceOverride;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -137,6 +136,8 @@ public class BeanDefinitionParserDelegate {
|
||||
|
||||
public static final String SCOPE_ATTRIBUTE = "scope";
|
||||
|
||||
private static final String SINGLETON_ATTRIBUTE = "singleton";
|
||||
|
||||
public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
|
||||
|
||||
public static final String AUTOWIRE_ATTRIBUTE = "autowire";
|
||||
@@ -244,12 +245,12 @@ public class BeanDefinitionParserDelegate {
|
||||
|
||||
private final XmlReaderContext readerContext;
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();
|
||||
|
||||
private final ParseState parseState = new ParseState();
|
||||
|
||||
private Environment environment;
|
||||
|
||||
/**
|
||||
* Stores all used bean names so we can enforce uniqueness on a per
|
||||
* beans-element basis. Duplicate bean ids/names may not exist within the
|
||||
@@ -259,26 +260,24 @@ public class BeanDefinitionParserDelegate {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new BeanDefinitionParserDelegate associated with the
|
||||
* supplied {@link XmlReaderContext} and {@link Environment}.
|
||||
* Create a new BeanDefinitionParserDelegate associated with the supplied
|
||||
* {@link XmlReaderContext}.
|
||||
*/
|
||||
public BeanDefinitionParserDelegate(XmlReaderContext readerContext) {
|
||||
this(readerContext, readerContext.getReader().getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BeanDefinitionParserDelegate associated with the supplied
|
||||
* {@link XmlReaderContext}.
|
||||
*/
|
||||
public BeanDefinitionParserDelegate(XmlReaderContext readerContext, Environment environment) {
|
||||
Assert.notNull(readerContext, "XmlReaderContext must not be null");
|
||||
Assert.notNull(readerContext, "Environment must not be null");
|
||||
Assert.notNull(environment, "Environment must not be null");
|
||||
this.readerContext = readerContext;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BeanDefinitionParserDelegate associated with the
|
||||
* supplied {@link XmlReaderContext} and a new {@link StandardEnvironment}.
|
||||
* @deprecated since Spring 3.1 in favor of
|
||||
* {@link #BeanDefinitionParserDelegate(XmlReaderContext, Environment)}
|
||||
*/
|
||||
@Deprecated
|
||||
public BeanDefinitionParserDelegate(XmlReaderContext readerContext) {
|
||||
this(readerContext, new StandardEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link XmlReaderContext} associated with this helper instance.
|
||||
@@ -592,7 +591,10 @@ public class BeanDefinitionParserDelegate {
|
||||
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
|
||||
BeanDefinition containingBean, AbstractBeanDefinition bd) {
|
||||
|
||||
if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
|
||||
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
|
||||
this.readerContext.warning("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
|
||||
}
|
||||
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
|
||||
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
|
||||
}
|
||||
else if (containingBean != null) {
|
||||
|
||||
+25
-33
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -35,7 +35,6 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -84,20 +83,14 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
|
||||
private BeanDefinitionParserDelegate delegate;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Default value is {@code null}; property is required for parsing any
|
||||
* {@code <beans/>} element with a {@code profile} attribute present.
|
||||
* @see #doRegisterBeanDefinitions
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation parses bean definitions according to the "spring-beans" XSD
|
||||
* This implementation parses bean definitions according to the "spring-beans" XSD
|
||||
* (or DTD, historically).
|
||||
* <p>Opens a DOM Document; then initializes the default settings
|
||||
* specified at the {@code <beans/>} level; then parses the contained bean definitions.
|
||||
@@ -110,20 +103,35 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
|
||||
doRegisterBeanDefinitions(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the descriptor for the XML resource that this parser works on.
|
||||
*/
|
||||
protected final XmlReaderContext getReaderContext() {
|
||||
return this.readerContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the {@link org.springframework.beans.factory.parsing.SourceExtractor} to pull the
|
||||
* source metadata from the supplied {@link Element}.
|
||||
*/
|
||||
protected Object extractSource(Element ele) {
|
||||
return getReaderContext().extractSource(ele);
|
||||
}
|
||||
|
||||
private Environment getEnvironment() {
|
||||
return (this.environment != null ? this.environment : getReaderContext().getReader().getEnvironment());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register each bean definition within the given root {@code <beans/>} element.
|
||||
* @throws IllegalStateException if {@code <beans profile="..."} attribute is present
|
||||
* and Environment property has not been set
|
||||
* @see #setEnvironment
|
||||
*/
|
||||
protected void doRegisterBeanDefinitions(Element root) {
|
||||
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
|
||||
if (StringUtils.hasText(profileSpec)) {
|
||||
Assert.state(this.environment != null, "Environment must be set for evaluating profiles");
|
||||
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
|
||||
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
|
||||
if (!this.environment.acceptsProfiles(specifiedProfiles)) {
|
||||
if (!getEnvironment().acceptsProfiles(specifiedProfiles)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -147,27 +155,11 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
|
||||
protected BeanDefinitionParserDelegate createDelegate(
|
||||
XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {
|
||||
|
||||
BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext, this.environment);
|
||||
BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext, getEnvironment());
|
||||
delegate.initDefaults(root, parentDelegate);
|
||||
return delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the descriptor for the XML resource that this parser works on.
|
||||
*/
|
||||
protected final XmlReaderContext getReaderContext() {
|
||||
return this.readerContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the {@link org.springframework.beans.factory.parsing.SourceExtractor} to pull the
|
||||
* source metadata from the supplied {@link Element}.
|
||||
*/
|
||||
protected Object extractSource(Element ele) {
|
||||
return this.readerContext.extractSource(ele);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the elements at the root level in the document:
|
||||
* "import", "alias", "bean".
|
||||
@@ -222,7 +214,7 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
|
||||
}
|
||||
|
||||
// Resolve system properties: e.g. "${user.dir}"
|
||||
location = environment.resolveRequiredPlaceholders(location);
|
||||
location = getEnvironment().resolveRequiredPlaceholders(location);
|
||||
|
||||
Set<Resource> actualResources = new LinkedHashSet<Resource>(4);
|
||||
|
||||
|
||||
+20
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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,29 +13,30 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.xml;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Simple {@code NamespaceHandler} implementation that maps custom
|
||||
* attributes directly through to bean properties. An important point to note is
|
||||
* that this {@code NamespaceHandler} does not have a corresponding schema
|
||||
* since there is no way to know in advance all possible attribute names.
|
||||
*
|
||||
* <p>
|
||||
* An example of the usage of this {@code NamespaceHandler} is shown below:
|
||||
* <p>An example of the usage of this {@code NamespaceHandler} is shown below:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="author" class="..TestBean" c:name="Enescu" c:work-ref="compositions"/>
|
||||
@@ -51,14 +52,17 @@ import org.w3c.dom.Node;
|
||||
* support for indexes or types. Further more, the names are used as hints by
|
||||
* the container which, by default, does type introspection.
|
||||
*
|
||||
* @see SimplePropertyNamespaceHandler
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
* @see SimplePropertyNamespaceHandler
|
||||
*/
|
||||
public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||
|
||||
private static final String REF_SUFFIX = "-ref";
|
||||
|
||||
private static final String DELIMITER_PREFIX = "_";
|
||||
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
@@ -102,7 +106,8 @@ public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||
int index = -1;
|
||||
try {
|
||||
index = Integer.parseInt(arg);
|
||||
} catch (NumberFormatException ex) {
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' specifies an invalid integer", attr);
|
||||
}
|
||||
@@ -136,11 +141,8 @@ public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||
}
|
||||
|
||||
private boolean containsArgWithName(String name, ConstructorArgumentValues cvs) {
|
||||
if (!checkName(name, cvs.getGenericArgumentValues())) {
|
||||
return checkName(name, cvs.getIndexedArgumentValues().values());
|
||||
}
|
||||
|
||||
return true;
|
||||
return (checkName(name, cvs.getGenericArgumentValues()) ||
|
||||
checkName(name, cvs.getIndexedArgumentValues().values()));
|
||||
}
|
||||
|
||||
private boolean checkName(String name, Collection<ValueHolder> values) {
|
||||
@@ -151,4 +153,5 @@ public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -135,6 +135,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
super(registry);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to use XML validation. Default is {@code true}.
|
||||
* <p>This method switches namespace awareness on if validation is turned off,
|
||||
@@ -501,9 +502,10 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
* @see #setDocumentReaderClass
|
||||
* @see BeanDefinitionDocumentReader#registerBeanDefinitions
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
|
||||
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
|
||||
documentReader.setEnvironment(this.getEnvironment());
|
||||
documentReader.setEnvironment(getEnvironment());
|
||||
int countBefore = getRegistry().getBeanDefinitionCount();
|
||||
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
|
||||
return getRegistry().getBeanDefinitionCount() - countBefore;
|
||||
|
||||
+6
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.springframework.beans.propertyeditors;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link java.beans.PropertyEditor} implementation for
|
||||
* {@link java.util.ResourceBundle ResourceBundles}.
|
||||
@@ -87,7 +87,8 @@ public class ResourceBundleEditor extends PropertyEditorSupport {
|
||||
int indexOfBaseNameSeparator = rawBaseName.indexOf(BASE_NAME_SEPARATOR);
|
||||
if (indexOfBaseNameSeparator == -1) {
|
||||
bundle = ResourceBundle.getBundle(rawBaseName);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// it potentially has locale information
|
||||
String baseName = rawBaseName.substring(0, indexOfBaseNameSeparator);
|
||||
if (!StringUtils.hasText(baseName)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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 java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||
@@ -40,6 +39,8 @@ import org.springframework.tests.sample.beans.GenericIntegerBean;
|
||||
import org.springframework.tests.sample.beans.GenericSetOfIntegerBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
@@ -485,6 +486,29 @@ public class BeanWrapperGenericsTests {
|
||||
assertEquals(new Long(10), bean.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUntypedPropertyWithMapAtRuntime() {
|
||||
class Holder<D> {
|
||||
private final D data;
|
||||
public Holder(D data) {
|
||||
this.data = data;
|
||||
}
|
||||
public D getData() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> data = new HashMap<String, Object>();
|
||||
data.put("x", "y");
|
||||
Holder<Map<String, Object>> context = new Holder<Map<String,Object>>(data);
|
||||
|
||||
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(context);
|
||||
assertEquals("y", bw.getPropertyValue("data['x']"));
|
||||
|
||||
bw.setPropertyValue("data['message']", "it works!");
|
||||
assertEquals(data.get("message"), "it works!");
|
||||
}
|
||||
|
||||
|
||||
private static abstract class BaseGenericCollectionBean {
|
||||
|
||||
|
||||
+10
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,13 +16,12 @@
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DirectFieldAccessor}
|
||||
*
|
||||
@@ -34,12 +33,13 @@ public class DirectFieldAccessorTests {
|
||||
@Test
|
||||
public void withShadowedField() throws Exception {
|
||||
@SuppressWarnings("serial")
|
||||
JPanel p = new JPanel() {
|
||||
TestBean tb = new TestBean() {
|
||||
@SuppressWarnings("unused")
|
||||
JTextField name = new JTextField();
|
||||
StringBuilder name = new StringBuilder();
|
||||
};
|
||||
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(p);
|
||||
assertEquals(JTextField.class, dfa.getPropertyType("name"));
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(tb);
|
||||
assertEquals(StringBuilder.class, dfa.getPropertyType("name"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -922,6 +922,15 @@ public class ExtendedBeanInfoTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // SPR-12434
|
||||
public void shouldDetectValidPropertiesAndIgnoreInvalidProperties() throws IntrospectionException {
|
||||
BeanInfo bi = new ExtendedBeanInfo(Introspector.getBeanInfo(java.awt.Window.class));
|
||||
assertThat(hasReadMethodForProperty(bi, "locationByPlatform"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "locationByPlatform"), is(true));
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "locationByPlatform"), is(false));
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "locationByPlatform"), is(false));
|
||||
}
|
||||
|
||||
|
||||
interface Spr9453<T> {
|
||||
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -104,9 +104,11 @@ public class DefaultListableBeanFactoryTests {
|
||||
|
||||
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
|
||||
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void testUnreferencedSingletonWasInstantiated() {
|
||||
KnowsIfInstantiated.clearInstantiationRecord();
|
||||
@@ -2748,6 +2750,7 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class KnowsIfInstantiated {
|
||||
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<bean id="bean1" class="org.springframework.beans.factory.FactoryBeanTests$PassThroughFactoryBean" primary="true">
|
||||
<constructor-arg value="org.springframework.beans.factory.FactoryBeanTests$BeanImpl1"/>
|
||||
<property name="instanceName" value="beanImpl1"/>
|
||||
</bean>
|
||||
|
||||
<bean id="beanImpl1" class="org.springframework.beans.factory.FactoryBeanTests$BeanImpl1">
|
||||
<property name="impl2" ref="bean2"/>
|
||||
</bean>
|
||||
|
||||
<bean id="bean2" class="org.springframework.beans.factory.FactoryBeanTests$PassThroughFactoryBean" primary="true">
|
||||
<constructor-arg value="org.springframework.beans.factory.FactoryBeanTests$BeanImpl2"/>
|
||||
<property name="instanceName" value="beanImpl2"/>
|
||||
</bean>
|
||||
|
||||
<bean id="beanImpl2" class="org.springframework.beans.factory.FactoryBeanTests$BeanImpl2">
|
||||
<property name="impl1" ref="bean1"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
+135
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,19 +16,24 @@
|
||||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.springframework.tests.TestResourceUtils.qualifiedResource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.tests.TestResourceUtils.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
@@ -40,6 +45,7 @@ public final class FactoryBeanTests {
|
||||
private static final Resource RETURNS_NULL_CONTEXT = qualifiedResource(CLASS, "returnsNull.xml");
|
||||
private static final Resource WITH_AUTOWIRING_CONTEXT = qualifiedResource(CLASS, "withAutowiring.xml");
|
||||
private static final Resource ABSTRACT_CONTEXT = qualifiedResource(CLASS, "abstract.xml");
|
||||
private static final Resource CIRCULAR_CONTEXT = qualifiedResource(CLASS, "circular.xml");
|
||||
|
||||
@Test
|
||||
public void testFactoryBeanReturnsNull() throws Exception {
|
||||
@@ -96,6 +102,23 @@ public final class FactoryBeanTests {
|
||||
factory.getBeansOfType(AbstractFactoryBean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCircularReferenceWithPostProcessor() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(factory).loadBeanDefinitions(CIRCULAR_CONTEXT);
|
||||
|
||||
CountingPostProcessor counter = new CountingPostProcessor();
|
||||
factory.addBeanPostProcessor(counter);
|
||||
|
||||
BeanImpl1 impl1 = factory.getBean(BeanImpl1.class);
|
||||
assertNotNull(impl1);
|
||||
assertNotNull(impl1.getImpl2());
|
||||
assertNotNull(impl1.getImpl2());
|
||||
assertSame(impl1, impl1.getImpl2().getImpl1());
|
||||
assertEquals(1, counter.getCount("bean1"));
|
||||
assertEquals(1, counter.getCount("bean2"));
|
||||
}
|
||||
|
||||
|
||||
public static class NullReturningFactoryBean implements FactoryBean<Object> {
|
||||
|
||||
@@ -193,7 +216,114 @@ public final class FactoryBeanTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract static class AbstractFactoryBean implements FactoryBean<Object> {
|
||||
}
|
||||
|
||||
|
||||
public static class PassThroughFactoryBean<T> implements FactoryBean<T>, BeanFactoryAware {
|
||||
|
||||
private Class<T> type;
|
||||
|
||||
private String instanceName;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private T instance;
|
||||
|
||||
public PassThroughFactoryBean(Class<T> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setInstanceName(String instanceName) {
|
||||
this.instanceName = instanceName;
|
||||
}
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T getObject() {
|
||||
if (instance == null) {
|
||||
instance = beanFactory.getBean(instanceName, type);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class CountingPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final Map<String, AtomicInteger> count = new HashMap<String, AtomicInteger>();
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
if (bean instanceof FactoryBean) {
|
||||
return bean;
|
||||
}
|
||||
AtomicInteger c = count.get(beanName);
|
||||
if (c == null) {
|
||||
c = new AtomicInteger(0);
|
||||
count.put(beanName, c);
|
||||
}
|
||||
c.incrementAndGet();
|
||||
return bean;
|
||||
}
|
||||
|
||||
public int getCount(String beanName) {
|
||||
AtomicInteger c = count.get(beanName);
|
||||
if (c != null) {
|
||||
return c.intValue();
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class BeanImpl1 {
|
||||
|
||||
private BeanImpl2 impl2;
|
||||
|
||||
public BeanImpl2 getImpl2() {
|
||||
return impl2;
|
||||
}
|
||||
|
||||
public void setImpl2(BeanImpl2 impl2) {
|
||||
this.impl2 = impl2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class BeanImpl2 {
|
||||
|
||||
private BeanImpl1 impl1;
|
||||
|
||||
public BeanImpl1 getImpl1() {
|
||||
return impl1;
|
||||
}
|
||||
|
||||
public void setImpl1(BeanImpl1 impl1) {
|
||||
this.impl1 = impl1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+97
-13
@@ -26,6 +26,7 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
@@ -34,6 +35,7 @@ import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.TypedStringValue;
|
||||
@@ -549,6 +551,23 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
bf.destroySingletons();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructorResourceInjectionWithNoCandidatesAndNoFallback() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorWithoutFallbackBean.class));
|
||||
|
||||
try {
|
||||
bf.getBean("annotatedBean");
|
||||
fail("Should have thrown UnsatisfiedDependencyException");
|
||||
}
|
||||
catch (UnsatisfiedDependencyException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructorResourceInjectionWithMultipleCandidatesAsCollection() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
@@ -1716,6 +1735,18 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
assertSame(bf.getBean(StockMovementDaoImpl.class), service.stockMovementDao);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBridgeMethodHandling() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
bf.registerBeanDefinition("bean1", new RootBeanDefinition(MyCallable.class));
|
||||
bf.registerBeanDefinition("bean2", new RootBeanDefinition(SecondCallable.class));
|
||||
bf.registerBeanDefinition("bean3", new RootBeanDefinition(FooBar.class));
|
||||
assertNotNull(bf.getBean(FooBar.class));
|
||||
}
|
||||
|
||||
|
||||
public static class ResourceInjectionBean {
|
||||
|
||||
@@ -1742,7 +1773,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
|
||||
public static class ExtendedResourceInjectionBean<T> extends ResourceInjectionBean {
|
||||
static class NonPublicResourceInjectionBean<T> extends ResourceInjectionBean {
|
||||
|
||||
@Autowired
|
||||
public final ITestBean testBean3 = null;
|
||||
@@ -1755,7 +1786,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
public boolean baseInjected = false;
|
||||
|
||||
public ExtendedResourceInjectionBean() {
|
||||
public NonPublicResourceInjectionBean() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1798,12 +1829,11 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
|
||||
public static class TypedExtendedResourceInjectionBean extends ExtendedResourceInjectionBean<NestedTestBean> {
|
||||
|
||||
public static class TypedExtendedResourceInjectionBean extends NonPublicResourceInjectionBean<NestedTestBean> {
|
||||
}
|
||||
|
||||
|
||||
public static class OverriddenExtendedResourceInjectionBean extends ExtendedResourceInjectionBean<NestedTestBean> {
|
||||
public static class OverriddenExtendedResourceInjectionBean extends NonPublicResourceInjectionBean<NestedTestBean> {
|
||||
|
||||
public boolean subInjected = false;
|
||||
|
||||
@@ -2025,6 +2055,21 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
|
||||
public static class ConstructorWithoutFallbackBean {
|
||||
|
||||
protected ITestBean testBean3;
|
||||
|
||||
@Autowired(required = false)
|
||||
public ConstructorWithoutFallbackBean(ITestBean testBean3) {
|
||||
this.testBean3 = testBean3;
|
||||
}
|
||||
|
||||
public ITestBean getTestBean3() {
|
||||
return this.testBean3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ConstructorsCollectionResourceInjectionBean {
|
||||
|
||||
protected ITestBean testBean3;
|
||||
@@ -2090,7 +2135,6 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
@Autowired
|
||||
private Map<String, TestBean> testBeanMap;
|
||||
|
||||
|
||||
public Map<String, TestBean> getTestBeanMap() {
|
||||
return this.testBeanMap;
|
||||
}
|
||||
@@ -2184,7 +2228,6 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
private TestBean testBean3;
|
||||
|
||||
|
||||
@MyAutowired(optional = true)
|
||||
protected void setTestBean3(TestBean testBean3) {
|
||||
this.testBean3 = testBean3;
|
||||
@@ -2593,7 +2636,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T createMock(Class<T> toMock) {
|
||||
return (T) Proxy.newProxyInstance(AutowiredAnnotationBeanPostProcessorTests.class.getClassLoader(), new Class<?>[]{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 {
|
||||
@@ -2610,7 +2653,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
|
||||
public static class GenericInterface1Impl<T> implements GenericInterface1<T>{
|
||||
public static class GenericInterface1Impl<T> implements GenericInterface1<T> {
|
||||
|
||||
@Autowired
|
||||
private GenericInterface2<T> gi2;
|
||||
@@ -2620,11 +2663,11 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
return gi2.doSomethingMoreGeneric(o) + "_somethingGeneric_" + o;
|
||||
}
|
||||
|
||||
public static GenericInterface1<String> create(){
|
||||
public static GenericInterface1<String> create() {
|
||||
return new StringGenericInterface1Impl();
|
||||
}
|
||||
|
||||
public static GenericInterface1 createPlain(){
|
||||
public static GenericInterface1 createPlain() {
|
||||
return new GenericInterface1Impl();
|
||||
}
|
||||
}
|
||||
@@ -2640,7 +2683,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
|
||||
public static class GenericInterface2Impl implements GenericInterface2<String>{
|
||||
public static class GenericInterface2Impl implements GenericInterface2<String> {
|
||||
|
||||
@Override
|
||||
public String doSomethingMoreGeneric(String o) {
|
||||
@@ -2658,7 +2701,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
|
||||
public static class PlainGenericInterface2Impl implements GenericInterface2{
|
||||
public static class PlainGenericInterface2Impl implements GenericInterface2 {
|
||||
|
||||
@Override
|
||||
public String doSomethingMoreGeneric(Object o) {
|
||||
@@ -2697,4 +2740,45 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
||||
private StockMovementDao<StockMovement> stockMovementDao;
|
||||
}
|
||||
|
||||
|
||||
public static class MyCallable implements Callable<Thread> {
|
||||
|
||||
@Override
|
||||
public Thread call() throws Exception {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SecondCallable implements Callable<Thread>{
|
||||
|
||||
@Override
|
||||
public Thread call() throws Exception {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static abstract class Foo<T extends Runnable, RT extends Callable<T>> {
|
||||
|
||||
private RT obj;
|
||||
|
||||
protected void setObj(RT obj) {
|
||||
if (this.obj != null) {
|
||||
throw new IllegalStateException("Already called");
|
||||
}
|
||||
this.obj = obj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class FooBar extends Foo<Thread, MyCallable> {
|
||||
|
||||
@Override
|
||||
@Autowired
|
||||
public void setObj(MyCallable obj) {
|
||||
super.setObj(obj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+32
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -14,24 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.tests.sample.beans.DerivedTestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 04.07.2006
|
||||
*/
|
||||
public final class SharedBeanRegistryTests {
|
||||
public class DefaultSingletonBeanRegistryTests {
|
||||
|
||||
@Test
|
||||
public void testSingletons() {
|
||||
@@ -52,9 +51,10 @@ public final class SharedBeanRegistryTests {
|
||||
assertSame(tb, beanRegistry.getSingleton("tb"));
|
||||
assertSame(tb2, beanRegistry.getSingleton("tb2"));
|
||||
assertEquals(2, beanRegistry.getSingletonCount());
|
||||
assertEquals(2, beanRegistry.getSingletonNames().length);
|
||||
assertTrue(Arrays.asList(beanRegistry.getSingletonNames()).contains("tb"));
|
||||
assertTrue(Arrays.asList(beanRegistry.getSingletonNames()).contains("tb2"));
|
||||
String[] names = beanRegistry.getSingletonNames();
|
||||
assertEquals(2, names.length);
|
||||
assertEquals("tb", names[0]);
|
||||
assertEquals("tb2", names[1]);
|
||||
|
||||
beanRegistry.destroySingletons();
|
||||
assertEquals(0, beanRegistry.getSingletonCount());
|
||||
@@ -72,8 +72,9 @@ public final class SharedBeanRegistryTests {
|
||||
|
||||
assertSame(tb, beanRegistry.getSingleton("tb"));
|
||||
assertEquals(1, beanRegistry.getSingletonCount());
|
||||
assertEquals(1, beanRegistry.getSingletonNames().length);
|
||||
assertTrue(Arrays.asList(beanRegistry.getSingletonNames()).contains("tb"));
|
||||
String[] names = beanRegistry.getSingletonNames();
|
||||
assertEquals(1, names.length);
|
||||
assertEquals("tb", names[0]);
|
||||
assertFalse(tb.wasDestroyed());
|
||||
|
||||
beanRegistry.destroySingletons();
|
||||
@@ -82,4 +83,22 @@ public final class SharedBeanRegistryTests {
|
||||
assertTrue(tb.wasDestroyed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDependentRegistration() {
|
||||
DefaultSingletonBeanRegistry beanRegistry = new DefaultSingletonBeanRegistry();
|
||||
|
||||
beanRegistry.registerDependentBean("a", "b");
|
||||
beanRegistry.registerDependentBean("b", "c");
|
||||
beanRegistry.registerDependentBean("c", "b");
|
||||
assertTrue(beanRegistry.isDependent("a", "b"));
|
||||
assertTrue(beanRegistry.isDependent("b", "c"));
|
||||
assertTrue(beanRegistry.isDependent("c", "b"));
|
||||
assertTrue(beanRegistry.isDependent("a", "c"));
|
||||
assertFalse(beanRegistry.isDependent("c", "a"));
|
||||
assertFalse(beanRegistry.isDependent("b", "a"));
|
||||
assertFalse(beanRegistry.isDependent("a", "a"));
|
||||
assertTrue(beanRegistry.isDependent("b", "b"));
|
||||
assertTrue(beanRegistry.isDependent("c", "c"));
|
||||
}
|
||||
|
||||
}
|
||||
+71
-30
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,14 +17,15 @@
|
||||
package org.springframework.beans.factory.xml;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.config.FieldRetrievingFactoryBean;
|
||||
import org.springframework.beans.factory.config.PropertiesFactoryBean;
|
||||
@@ -35,19 +36,23 @@ import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.tests.beans.CollectingReaderEventListener;
|
||||
import org.springframework.tests.sample.beans.CustomEnum;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.util.LinkedCaseInsensitiveMap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class UtilNamespaceHandlerTests extends TestCase {
|
||||
public class UtilNamespaceHandlerTests {
|
||||
|
||||
private DefaultListableBeanFactory beanFactory;
|
||||
|
||||
private CollectingReaderEventListener listener = new CollectingReaderEventListener();
|
||||
|
||||
@Override
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.beanFactory = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory);
|
||||
@@ -55,17 +60,21 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
reader.loadBeanDefinitions(new ClassPathResource("testUtilNamespace.xml", getClass()));
|
||||
}
|
||||
|
||||
public void testConstant() throws Exception {
|
||||
|
||||
@Test
|
||||
public void testConstant() {
|
||||
Integer min = (Integer) this.beanFactory.getBean("min");
|
||||
assertEquals(Integer.MIN_VALUE, min.intValue());
|
||||
}
|
||||
|
||||
public void testConstantWithDefaultName() throws Exception {
|
||||
@Test
|
||||
public void testConstantWithDefaultName() {
|
||||
Integer max = (Integer) this.beanFactory.getBean("java.lang.Integer.MAX_VALUE");
|
||||
assertEquals(Integer.MAX_VALUE, max.intValue());
|
||||
}
|
||||
|
||||
public void testEvents() throws Exception {
|
||||
@Test
|
||||
public void testEvents() {
|
||||
ComponentDefinition propertiesComponent = this.listener.getComponentDefinition("myProperties");
|
||||
assertNotNull("Event for 'myProperties' not sent", propertiesComponent);
|
||||
AbstractBeanDefinition propertiesBean = (AbstractBeanDefinition) propertiesComponent.getBeanDefinitions()[0];
|
||||
@@ -77,30 +86,35 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertEquals("Incorrect BeanDefinition", FieldRetrievingFactoryBean.class, constantBean.getBeanClass());
|
||||
}
|
||||
|
||||
public void testNestedProperties() throws Exception {
|
||||
@Test
|
||||
public void testNestedProperties() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("testBean");
|
||||
Properties props = bean.getSomeProperties();
|
||||
assertEquals("Incorrect property value", "bar", props.get("foo"));
|
||||
}
|
||||
|
||||
public void testPropertyPath() throws Exception {
|
||||
@Test
|
||||
public void testPropertyPath() {
|
||||
String name = (String) this.beanFactory.getBean("name");
|
||||
assertEquals("Rob Harrop", name);
|
||||
}
|
||||
|
||||
public void testNestedPropertyPath() throws Exception {
|
||||
@Test
|
||||
public void testNestedPropertyPath() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("testBean");
|
||||
assertEquals("Rob Harrop", bean.getName());
|
||||
}
|
||||
|
||||
public void testSimpleMap() throws Exception {
|
||||
@Test
|
||||
public void testSimpleMap() {
|
||||
Map map = (Map) this.beanFactory.getBean("simpleMap");
|
||||
assertEquals("bar", map.get("foo"));
|
||||
Map map2 = (Map) this.beanFactory.getBean("simpleMap");
|
||||
assertTrue(map == map2);
|
||||
}
|
||||
|
||||
public void testScopedMap() throws Exception {
|
||||
@Test
|
||||
public void testScopedMap() {
|
||||
Map map = (Map) this.beanFactory.getBean("scopedMap");
|
||||
assertEquals("bar", map.get("foo"));
|
||||
Map map2 = (Map) this.beanFactory.getBean("scopedMap");
|
||||
@@ -108,14 +122,16 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertTrue(map != map2);
|
||||
}
|
||||
|
||||
public void testSimpleList() throws Exception {
|
||||
@Test
|
||||
public void testSimpleList() {
|
||||
List list = (List) this.beanFactory.getBean("simpleList");
|
||||
assertEquals("Rob Harrop", list.get(0));
|
||||
List list2 = (List) this.beanFactory.getBean("simpleList");
|
||||
assertTrue(list == list2);
|
||||
}
|
||||
|
||||
public void testScopedList() throws Exception {
|
||||
@Test
|
||||
public void testScopedList() {
|
||||
List list = (List) this.beanFactory.getBean("scopedList");
|
||||
assertEquals("Rob Harrop", list.get(0));
|
||||
List list2 = (List) this.beanFactory.getBean("scopedList");
|
||||
@@ -123,14 +139,16 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertTrue(list != list2);
|
||||
}
|
||||
|
||||
public void testSimpleSet() throws Exception {
|
||||
@Test
|
||||
public void testSimpleSet() {
|
||||
Set set = (Set) this.beanFactory.getBean("simpleSet");
|
||||
assertTrue(set.contains("Rob Harrop"));
|
||||
Set set2 = (Set) this.beanFactory.getBean("simpleSet");
|
||||
assertTrue(set == set2);
|
||||
}
|
||||
|
||||
public void testScopedSet() throws Exception {
|
||||
@Test
|
||||
public void testScopedSet() {
|
||||
Set set = (Set) this.beanFactory.getBean("scopedSet");
|
||||
assertTrue(set.contains("Rob Harrop"));
|
||||
Set set2 = (Set) this.beanFactory.getBean("scopedSet");
|
||||
@@ -138,13 +156,22 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertTrue(set != set2);
|
||||
}
|
||||
|
||||
public void testMapWithRef() throws Exception {
|
||||
@Test
|
||||
public void testMapWithRef() {
|
||||
Map map = (Map) this.beanFactory.getBean("mapWithRef");
|
||||
assertTrue(map instanceof TreeMap);
|
||||
assertEquals(this.beanFactory.getBean("testBean"), map.get("bean"));
|
||||
}
|
||||
|
||||
public void testNestedCollections() throws Exception {
|
||||
@Test
|
||||
public void testMapWithTypes() {
|
||||
Map map = (Map) this.beanFactory.getBean("mapWithTypes");
|
||||
assertTrue(map instanceof LinkedCaseInsensitiveMap);
|
||||
assertEquals(this.beanFactory.getBean("testBean"), map.get("bean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedCollections() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("nestedCollectionsBean");
|
||||
|
||||
List list = bean.getSomeList();
|
||||
@@ -171,7 +198,8 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertFalse(map == bean2.getSomeMap());
|
||||
}
|
||||
|
||||
public void testNestedShortcutCollections() throws Exception {
|
||||
@Test
|
||||
public void testNestedShortcutCollections() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("nestedShortcutCollections");
|
||||
|
||||
assertEquals(1, bean.getStringArray().length);
|
||||
@@ -194,7 +222,8 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertFalse(set == bean2.getSomeSet());
|
||||
}
|
||||
|
||||
public void testNestedInCollections() throws Exception {
|
||||
@Test
|
||||
public void testNestedInCollections() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("nestedCustomTagBean");
|
||||
|
||||
List list = bean.getSomeList();
|
||||
@@ -219,7 +248,8 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertFalse(map == bean2.getSomeMap());
|
||||
}
|
||||
|
||||
public void testCircularCollections() throws Exception {
|
||||
@Test
|
||||
public void testCircularCollections() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionsBean");
|
||||
|
||||
List list = bean.getSomeList();
|
||||
@@ -235,7 +265,8 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertEquals(bean, map.get("foo"));
|
||||
}
|
||||
|
||||
public void testCircularCollectionBeansStartingWithList() throws Exception {
|
||||
@Test
|
||||
public void testCircularCollectionBeansStartingWithList() {
|
||||
this.beanFactory.getBean("circularList");
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean");
|
||||
|
||||
@@ -255,7 +286,8 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertEquals(bean, map.get("foo"));
|
||||
}
|
||||
|
||||
public void testCircularCollectionBeansStartingWithSet() throws Exception {
|
||||
@Test
|
||||
public void testCircularCollectionBeansStartingWithSet() {
|
||||
this.beanFactory.getBean("circularSet");
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean");
|
||||
|
||||
@@ -275,7 +307,8 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertEquals(bean, map.get("foo"));
|
||||
}
|
||||
|
||||
public void testCircularCollectionBeansStartingWithMap() throws Exception {
|
||||
@Test
|
||||
public void testCircularCollectionBeansStartingWithMap() {
|
||||
this.beanFactory.getBean("circularMap");
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean");
|
||||
|
||||
@@ -295,12 +328,14 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertEquals(bean, map.get("foo"));
|
||||
}
|
||||
|
||||
public void testNestedInConstructor() throws Exception {
|
||||
@Test
|
||||
public void testNestedInConstructor() {
|
||||
TestBean bean = (TestBean) this.beanFactory.getBean("constructedTestBean");
|
||||
assertEquals("Rob Harrop", bean.getName());
|
||||
}
|
||||
|
||||
public void testLoadProperties() throws Exception {
|
||||
@Test
|
||||
public void testLoadProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myProperties");
|
||||
assertEquals("Incorrect property value", "bar", props.get("foo"));
|
||||
assertEquals("Incorrect property value", null, props.get("foo2"));
|
||||
@@ -308,7 +343,8 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertTrue(props == props2);
|
||||
}
|
||||
|
||||
public void testScopedProperties() throws Exception {
|
||||
@Test
|
||||
public void testScopedProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myScopedProperties");
|
||||
assertEquals("Incorrect property value", "bar", props.get("foo"));
|
||||
assertEquals("Incorrect property value", null, props.get("foo2"));
|
||||
@@ -318,30 +354,35 @@ public class UtilNamespaceHandlerTests extends TestCase {
|
||||
assertTrue(props != props2);
|
||||
}
|
||||
|
||||
public void testLocalProperties() throws Exception {
|
||||
@Test
|
||||
public void testLocalProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myLocalProperties");
|
||||
assertEquals("Incorrect property value", null, props.get("foo"));
|
||||
assertEquals("Incorrect property value", "bar2", props.get("foo2"));
|
||||
}
|
||||
|
||||
public void testMergedProperties() throws Exception {
|
||||
@Test
|
||||
public void testMergedProperties() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("myMergedProperties");
|
||||
assertEquals("Incorrect property value", "bar", props.get("foo"));
|
||||
assertEquals("Incorrect property value", "bar2", props.get("foo2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalOverrideDefault() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("defaultLocalOverrideProperties");
|
||||
assertEquals("Incorrect property value", "bar", props.get("foo"));
|
||||
assertEquals("Incorrect property value", "local2", props.get("foo2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalOverrideFalse() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("falseLocalOverrideProperties");
|
||||
assertEquals("Incorrect property value", "bar", props.get("foo"));
|
||||
assertEquals("Incorrect property value", "local2", props.get("foo2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalOverrideTrue() {
|
||||
Properties props = (Properties) this.beanFactory.getBean("trueLocalOverrideProperties");
|
||||
assertEquals("Incorrect property value", "local", props.get("foo"));
|
||||
|
||||
+6
-1
@@ -15,7 +15,7 @@
|
||||
<util:property-path id="name" path="
|
||||
configuredBean.
|
||||
name
|
||||
"/>
|
||||
"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.tests.sample.beans.TestBean" scope="prototype">
|
||||
<property name="name">
|
||||
@@ -49,6 +49,11 @@
|
||||
<entry key="bean" value-ref="testBean"/>
|
||||
</util:map>
|
||||
|
||||
<util:map id="mapWithTypes" map-class="org.springframework.util.LinkedCaseInsensitiveMap"
|
||||
key-type="java.lang.String" value-type="org.springframework.tests.sample.beans.TestBean">
|
||||
<entry key="bean" value-ref="testBean"/>
|
||||
</util:map>
|
||||
|
||||
<util:list id="simpleList">
|
||||
<value>Rob Harrop</value>
|
||||
</util:list>
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,7 +45,7 @@ import org.springframework.core.io.Resource;
|
||||
* also necessary for loading EhCache configuration from a non-default config location.
|
||||
*
|
||||
* <p>Note: As of Spring 4.0, Spring's EhCache support requires EhCache 2.1 or higher.
|
||||
* We recommend the use of EhCache 2.5 or higher.
|
||||
* We strongly recommend the use of EhCache 2.5 or higher.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Dmitriy Kopylenko
|
||||
@@ -132,7 +132,7 @@ public class EhCacheManagerFactoryBean implements FactoryBean<CacheManager>, Ini
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws IOException, CacheException {
|
||||
public void afterPropertiesSet() throws CacheException, IOException {
|
||||
logger.info("Initializing EhCache CacheManager");
|
||||
InputStream is = (this.configLocation != null ? this.configLocation.getInputStream() : null);
|
||||
try {
|
||||
|
||||
Vendored
+36
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cache.guava;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
@@ -29,6 +30,7 @@ import com.google.common.cache.CacheLoader;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link CacheManager} implementation that lazily builds {@link GuavaCache}
|
||||
@@ -45,6 +47,7 @@ import org.springframework.util.Assert;
|
||||
* <p>Requires Google Guava 12.0 or higher.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.0
|
||||
* @see GuavaCache
|
||||
*/
|
||||
@@ -81,6 +84,8 @@ public class GuavaCacheManager implements CacheManager {
|
||||
* Specify the set of cache names for this CacheManager's 'static' mode.
|
||||
* <p>The number of caches and their names will be fixed after a call to this method,
|
||||
* with no creation of further cache regions at runtime.
|
||||
* <p>Calling this with a {@code null} collection argument resets the
|
||||
* mode to 'dynamic', allowing for further creation of caches again.
|
||||
*/
|
||||
public void setCacheNames(Collection<String> cacheNames) {
|
||||
if (cacheNames != null) {
|
||||
@@ -89,6 +94,9 @@ public class GuavaCacheManager implements CacheManager {
|
||||
}
|
||||
this.dynamic = false;
|
||||
}
|
||||
else {
|
||||
this.dynamic = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +107,7 @@ public class GuavaCacheManager implements CacheManager {
|
||||
*/
|
||||
public void setCacheBuilder(CacheBuilder<Object, Object> cacheBuilder) {
|
||||
Assert.notNull(cacheBuilder, "CacheBuilder must not be null");
|
||||
this.cacheBuilder = cacheBuilder;
|
||||
doSetCacheBuilder(cacheBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +117,7 @@ public class GuavaCacheManager implements CacheManager {
|
||||
* @see com.google.common.cache.CacheBuilder#from(CacheBuilderSpec)
|
||||
*/
|
||||
public void setCacheBuilderSpec(CacheBuilderSpec cacheBuilderSpec) {
|
||||
this.cacheBuilder = CacheBuilder.from(cacheBuilderSpec);
|
||||
doSetCacheBuilder(CacheBuilder.from(cacheBuilderSpec));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +128,7 @@ public class GuavaCacheManager implements CacheManager {
|
||||
* @see com.google.common.cache.CacheBuilder#from(String)
|
||||
*/
|
||||
public void setCacheSpecification(String cacheSpecification) {
|
||||
this.cacheBuilder = CacheBuilder.from(cacheSpecification);
|
||||
doSetCacheBuilder(CacheBuilder.from(cacheSpecification));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +139,10 @@ public class GuavaCacheManager implements CacheManager {
|
||||
* @see com.google.common.cache.LoadingCache
|
||||
*/
|
||||
public void setCacheLoader(CacheLoader<Object, Object> cacheLoader) {
|
||||
this.cacheLoader = cacheLoader;
|
||||
if (!ObjectUtils.nullSafeEquals(this.cacheLoader, cacheLoader)) {
|
||||
this.cacheLoader = cacheLoader;
|
||||
refreshKnownCaches();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +152,10 @@ public class GuavaCacheManager implements CacheManager {
|
||||
* An internal holder object will be used to store user-level {@code null}s.
|
||||
*/
|
||||
public void setAllowNullValues(boolean allowNullValues) {
|
||||
this.allowNullValues = allowNullValues;
|
||||
if (this.allowNullValues != allowNullValues) {
|
||||
this.allowNullValues = allowNullValues;
|
||||
refreshKnownCaches();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,4 +210,20 @@ public class GuavaCacheManager implements CacheManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void doSetCacheBuilder(CacheBuilder<Object, Object> cacheBuilder) {
|
||||
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
|
||||
this.cacheBuilder = cacheBuilder;
|
||||
refreshKnownCaches();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the known caches again with the current state of this manager.
|
||||
*/
|
||||
private void refreshKnownCaches() {
|
||||
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
|
||||
entry.setValue(createGuavaCache(entry.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vendored
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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 java.net.URI;
|
||||
import java.util.Properties;
|
||||
import javax.cache.CacheManager;
|
||||
import javax.cache.Caching;
|
||||
import javax.cache.spi.CachingProvider;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
@@ -75,8 +74,7 @@ public class JCacheManagerFactoryBean
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
CachingProvider provider = Caching.getCachingProvider();
|
||||
this.cacheManager = provider.getCacheManager(
|
||||
this.cacheManager = Caching.getCachingProvider().getCacheManager(
|
||||
this.cacheManagerUri, this.beanClassLoader, this.cacheManagerProperties);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -68,7 +68,7 @@ public class TransactionAwareCacheManagerProxy implements CacheManager, Initiali
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (this.targetCacheManager == null) {
|
||||
throw new IllegalStateException("'targetCacheManager' is required");
|
||||
throw new IllegalArgumentException("Property 'targetCacheManager' is required");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -93,7 +93,7 @@ public class ConfigurableMimeFileTypeMap extends FileTypeMap implements Initiali
|
||||
* Java Activation Framework, for example:<br>
|
||||
* {@code text/html html htm HTML HTM}
|
||||
*/
|
||||
public void setMappings(String[] mappings) {
|
||||
public void setMappings(String... mappings) {
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,6 +34,7 @@ import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.Constants;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
@@ -261,7 +262,7 @@ public class CronTriggerFactoryBean implements FactoryBean<CronTrigger>, BeanNam
|
||||
Class<?> cronTriggerClass;
|
||||
Method jobKeyMethod;
|
||||
try {
|
||||
cronTriggerClass = getClass().getClassLoader().loadClass("org.quartz.impl.triggers.CronTriggerImpl");
|
||||
cronTriggerClass = ClassUtils.forName("org.quartz.impl.triggers.CronTriggerImpl", getClass().getClassLoader());
|
||||
jobKeyMethod = JobDetail.class.getMethod("getKey");
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,6 +30,7 @@ import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* A Spring {@link FactoryBean} for creating a Quartz {@link org.quartz.JobDetail}
|
||||
@@ -210,7 +211,7 @@ public class JobDetailFactoryBean
|
||||
|
||||
Class<?> jobDetailClass;
|
||||
try {
|
||||
jobDetailClass = getClass().getClassLoader().loadClass("org.quartz.impl.JobDetailImpl");
|
||||
jobDetailClass = ClassUtils.forName("org.quartz.impl.JobDetailImpl", getClass().getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
jobDetailClass = JobDetail.class;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -87,7 +87,7 @@ public class LocalTaskExecutorThreadPool implements ThreadPool {
|
||||
|
||||
@Override
|
||||
public int blockForAvailableThreads() {
|
||||
// The present implementation always returns 1, making Quartz (1.6)
|
||||
// The present implementation always returns 1, making Quartz
|
||||
// always schedule any tasks that it feels like scheduling.
|
||||
// This could be made smarter for specific TaskExecutors,
|
||||
// for example calling {@code getMaximumPoolSize() - getActiveCount()}
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -87,14 +87,15 @@ public class MethodInvokingJobDetailFactoryBean extends ArgumentConvertingMethod
|
||||
|
||||
static {
|
||||
try {
|
||||
jobDetailImplClass = Class.forName("org.quartz.impl.JobDetailImpl");
|
||||
jobDetailImplClass = ClassUtils.forName("org.quartz.impl.JobDetailImpl",
|
||||
MethodInvokingJobDetailFactoryBean.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
jobDetailImplClass = null;
|
||||
}
|
||||
try {
|
||||
Class<?> jobExecutionContextClass =
|
||||
QuartzJobBean.class.getClassLoader().loadClass("org.quartz.JobExecutionContext");
|
||||
Class<?> jobExecutionContextClass = ClassUtils.forName("org.quartz.JobExecutionContext",
|
||||
MethodInvokingJobDetailFactoryBean.class.getClassLoader());
|
||||
setResultMethod = jobExecutionContextClass.getMethod("setResult", Object.class);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,6 +28,7 @@ import org.quartz.SchedulerException;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyAccessorFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
@@ -77,7 +78,7 @@ public abstract class QuartzJobBean implements Job {
|
||||
static {
|
||||
try {
|
||||
Class<?> jobExecutionContextClass =
|
||||
QuartzJobBean.class.getClassLoader().loadClass("org.quartz.JobExecutionContext");
|
||||
ClassUtils.forName("org.quartz.JobExecutionContext", QuartzJobBean.class.getClassLoader());
|
||||
getSchedulerMethod = jobExecutionContextClass.getMethod("getScheduler");
|
||||
getMergedJobDataMapMethod = jobExecutionContextClass.getMethod("getMergedJobDataMap");
|
||||
}
|
||||
|
||||
+4
-9
@@ -43,6 +43,7 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
@@ -68,8 +69,8 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
|
||||
static {
|
||||
// Quartz 2.0 job/trigger key available?
|
||||
try {
|
||||
jobKeyClass = Class.forName("org.quartz.JobKey");
|
||||
triggerKeyClass = Class.forName("org.quartz.TriggerKey");
|
||||
jobKeyClass = ClassUtils.forName("org.quartz.JobKey", SchedulerAccessor.class.getClassLoader());
|
||||
triggerKeyClass = ClassUtils.forName("org.quartz.TriggerKey", SchedulerAccessor.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
jobKeyClass = null;
|
||||
@@ -151,12 +152,10 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
|
||||
* in combination with the Trigger.
|
||||
* @see #setTriggers
|
||||
* @see org.quartz.JobDetail
|
||||
* @see JobDetailBean
|
||||
* @see JobDetailAwareTrigger
|
||||
*/
|
||||
public void setJobDetails(JobDetail... jobDetails) {
|
||||
// Use modifiable ArrayList here, to allow for further adding of
|
||||
// JobDetail objects during autodetection of JobDetailAwareTriggers.
|
||||
// JobDetail objects during autodetection of JobDetail-aware Triggers.
|
||||
this.jobDetails = new ArrayList<JobDetail>(Arrays.asList(jobDetails));
|
||||
}
|
||||
|
||||
@@ -180,15 +179,11 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
|
||||
* "jobDetails" property of this FactoryBean.
|
||||
* @see #setJobDetails
|
||||
* @see org.quartz.JobDetail
|
||||
* @see JobDetailAwareTrigger
|
||||
* @see CronTriggerBean
|
||||
* @see SimpleTriggerBean
|
||||
*/
|
||||
public void setTriggers(Trigger... triggers) {
|
||||
this.triggers = Arrays.asList(triggers);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify Quartz SchedulerListeners to be registered with the Scheduler.
|
||||
*/
|
||||
|
||||
+7
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -86,8 +86,8 @@ import org.springframework.util.CollectionUtils;
|
||||
* @see org.quartz.impl.StdSchedulerFactory
|
||||
* @see org.springframework.transaction.interceptor.TransactionProxyFactoryBean
|
||||
*/
|
||||
public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBean<Scheduler>, BeanNameAware,
|
||||
ApplicationContextAware, InitializingBean, DisposableBean, SmartLifecycle {
|
||||
public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBean<Scheduler>,
|
||||
BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean, SmartLifecycle {
|
||||
|
||||
public static final String PROP_THREAD_COUNT = "org.quartz.threadPool.threadCount";
|
||||
|
||||
@@ -311,7 +311,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
* reference into the JobDataMap but rather into the SchedulerContext.
|
||||
* @param schedulerContextAsMap Map with String keys and any objects as
|
||||
* values (for example Spring-managed beans)
|
||||
* @see JobDetailBean#setJobDataAsMap
|
||||
* @see JobDetailFactoryBean#setJobDataAsMap
|
||||
*/
|
||||
public void setSchedulerContextAsMap(Map<String, ?> schedulerContextAsMap) {
|
||||
this.schedulerContextMap = schedulerContextAsMap;
|
||||
@@ -329,8 +329,8 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
* correspond to a "setApplicationContext" method in that scenario.
|
||||
* <p>Note that BeanFactory callback interfaces like ApplicationContextAware
|
||||
* are not automatically applied to Quartz Job instances, because Quartz
|
||||
* itself is reponsible for the lifecycle of its Jobs.
|
||||
* @see JobDetailBean#setApplicationContextJobDataKey
|
||||
* itself is responsible for the lifecycle of its Jobs.
|
||||
* @see JobDetailFactoryBean#setApplicationContextJobDataKey
|
||||
* @see org.springframework.context.ApplicationContext
|
||||
*/
|
||||
public void setApplicationContextSchedulerContextKey(String applicationContextSchedulerContextKey) {
|
||||
@@ -476,7 +476,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
|
||||
}
|
||||
|
||||
|
||||
// Get Scheduler instance from SchedulerFactory.
|
||||
try {
|
||||
this.scheduler = createScheduler(schedulerFactory, this.schedulerName);
|
||||
@@ -707,7 +706,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of Lifecycle interface
|
||||
// Implementation of SmartLifecycle interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -33,6 +33,7 @@ import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.Constants;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
@@ -245,14 +246,14 @@ public class SimpleTriggerFactoryBean implements FactoryBean<SimpleTrigger>, Bea
|
||||
sti.setRepeatCount(this.repeatCount);
|
||||
sti.setPriority(this.priority);
|
||||
sti.setMisfireInstruction(this.misfireInstruction);
|
||||
cti.setDescription(this.description);
|
||||
sti.setDescription(this.description);
|
||||
this.simpleTrigger = sti;
|
||||
*/
|
||||
|
||||
Class<?> simpleTriggerClass;
|
||||
Method jobKeyMethod;
|
||||
try {
|
||||
simpleTriggerClass = getClass().getClassLoader().loadClass("org.quartz.impl.triggers.SimpleTriggerImpl");
|
||||
simpleTriggerClass = ClassUtils.forName("org.quartz.impl.triggers.SimpleTriggerImpl", getClass().getClassLoader());
|
||||
jobKeyMethod = JobDetail.class.getMethod("getKey");
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,6 +45,7 @@ public abstract class FreeMarkerTemplateUtils {
|
||||
*/
|
||||
public static String processTemplateIntoString(Template template, Object model)
|
||||
throws IOException, TemplateException {
|
||||
|
||||
StringWriter result = new StringWriter();
|
||||
template.process(model, result);
|
||||
return result.toString();
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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,9 +28,9 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
||||
/**
|
||||
* FreeMarker TemplateLoader adapter that loads via a Spring ResourceLoader.
|
||||
* Used by FreeMarkerConfigurationFactory for any resource loader path that
|
||||
* cannot be resolved to a java.io.File.
|
||||
* FreeMarker {@link TemplateLoader} adapter that loads via a Spring {@link ResourceLoader}.
|
||||
* Used by {@link FreeMarkerConfigurationFactory} for any resource loader path that cannot
|
||||
* be resolved to a {@link java.io.File}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 14.03.2004
|
||||
@@ -63,6 +63,7 @@ public class SpringTemplateLoader implements TemplateLoader {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object findTemplateSource(String name) throws IOException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -86,7 +87,6 @@ public class SpringTemplateLoader implements TemplateLoader {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getLastModified(Object templateSource) {
|
||||
Resource resource = (Resource) templateSource;
|
||||
|
||||
Vendored
+79
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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,15 +16,19 @@
|
||||
|
||||
package org.springframework.cache.guava;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class GuavaCacheManagerTests {
|
||||
|
||||
@@ -56,7 +60,7 @@ public class GuavaCacheManagerTests {
|
||||
|
||||
@Test
|
||||
public void testStaticMode() {
|
||||
CacheManager cm = new GuavaCacheManager("c1", "c2");
|
||||
GuavaCacheManager cm = new GuavaCacheManager("c1", "c2");
|
||||
Cache cache1 = cm.getCache("c1");
|
||||
assertTrue(cache1 instanceof GuavaCache);
|
||||
Cache cache1again = cm.getCache("c1");
|
||||
@@ -76,6 +80,79 @@ public class GuavaCacheManagerTests {
|
||||
assertNull(cache1.get("key3").get());
|
||||
cache1.evict("key3");
|
||||
assertNull(cache1.get("key3"));
|
||||
|
||||
cm.setAllowNullValues(false);
|
||||
Cache cache1x = cm.getCache("c1");
|
||||
assertTrue(cache1x instanceof GuavaCache);
|
||||
assertTrue(cache1x != cache1);
|
||||
Cache cache2x = cm.getCache("c2");
|
||||
assertTrue(cache2x instanceof GuavaCache);
|
||||
assertTrue(cache2x != cache2);
|
||||
Cache cache3x = cm.getCache("c3");
|
||||
assertNull(cache3x);
|
||||
|
||||
cache1x.put("key1", "value1");
|
||||
assertEquals("value1", cache1x.get("key1").get());
|
||||
cache1x.put("key2", 2);
|
||||
assertEquals(2, cache1x.get("key2").get());
|
||||
try {
|
||||
cache1x.put("key3", null);
|
||||
fail("Should have thrown NullPointerException");
|
||||
}
|
||||
catch (NullPointerException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
cm.setAllowNullValues(true);
|
||||
Cache cache1y = cm.getCache("c1");
|
||||
|
||||
cache1y.put("key3", null);
|
||||
assertNull(cache1y.get("key3").get());
|
||||
cache1y.evict("key3");
|
||||
assertNull(cache1y.get("key3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeCacheSpecificationRecreateCache() {
|
||||
GuavaCacheManager cm = new GuavaCacheManager("c1");
|
||||
Cache cache1 = cm.getCache("c1");
|
||||
|
||||
CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder().maximumSize(10);
|
||||
cm.setCacheBuilder(cacheBuilder);
|
||||
Cache cache1x = cm.getCache("c1");
|
||||
assertTrue(cache1x != cache1);
|
||||
|
||||
cm.setCacheBuilder(cacheBuilder); // Set same instance
|
||||
Cache cache1xx = cm.getCache("c1");
|
||||
assertSame(cache1x, cache1xx);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeCacheLoaderRecreateCache() {
|
||||
GuavaCacheManager cm = new GuavaCacheManager("c1");
|
||||
Cache cache1 = cm.getCache("c1");
|
||||
|
||||
CacheLoader<Object,Object> loader = mockCacheLoader();
|
||||
cm.setCacheLoader(loader);
|
||||
Cache cache1x = cm.getCache("c1");
|
||||
assertTrue(cache1x != cache1);
|
||||
|
||||
cm.setCacheLoader(loader); // Set same instance
|
||||
Cache cache1xx = cm.getCache("c1");
|
||||
assertSame(cache1x, cache1xx);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setCacheNameNullRestoreDynamicMode() {
|
||||
GuavaCacheManager cm = new GuavaCacheManager("c1");
|
||||
assertNull(cm.getCache("someCache"));
|
||||
cm.setCacheNames(null);
|
||||
assertNotNull(cm.getCache("someCache"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private CacheLoader<Object, Object> mockCacheLoader() {
|
||||
return mock(CacheLoader.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user