mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fe7a8aea2a |
@@ -33,6 +33,14 @@ do not find something similar, please create a new JIRA issue before submitting
|
||||
a pull request unless the change is truly trivial -- for example: typo fixes,
|
||||
removing compiler warnings, etc.
|
||||
|
||||
### Discuss non-trivial contribution ideas with committers
|
||||
|
||||
If you're considering anything more than correcting a typo or fixing a minor
|
||||
bug, please discuss it on the [spring-framework-contrib][] mailing list before
|
||||
submitting a pull request. We're happy to provide guidance, but please spend an
|
||||
hour or two researching the subject on your own, including searching the mailing
|
||||
list for prior discussions.
|
||||
|
||||
### Sign the Individual Contributor License Agreement (ICLA)
|
||||
|
||||
If you have not previously done so, please fill out and submit the
|
||||
|
||||
+96
-82
@@ -31,13 +31,13 @@ configure(allprojects) { project ->
|
||||
group = "org.springframework"
|
||||
version = qualifyVersionIfNecessary(version)
|
||||
|
||||
ext.aspectjVersion = "1.8.9"
|
||||
ext.caffeineVersion = "2.3.0"
|
||||
ext.aspectjVersion = "1.9.0.BETA-3"
|
||||
ext.caffeineVersion = "2.2.6"
|
||||
ext.eclipselinkVersion = "2.4.2"
|
||||
ext.ehcacheVersion = "2.10.2"
|
||||
ext.ehcacheVersion = "2.10.1"
|
||||
ext.ehcachejcacheVersion = "1.0.1"
|
||||
ext.ehcache3Version = "3.0.0"
|
||||
ext.ejbVersion = "3.0"
|
||||
ext.ehcache3Version = "3.0.0.rc2"
|
||||
ext.ejbApiVersion = "3.0"
|
||||
ext.fileuploadVersion = "1.3.1"
|
||||
ext.freemarkerVersion = "2.3.23"
|
||||
ext.groovyVersion = "2.4.6"
|
||||
@@ -50,23 +50,28 @@ configure(allprojects) { project ->
|
||||
ext.hibval4Version = "4.3.2.Final"
|
||||
ext.hibval5Version = "5.2.4.Final"
|
||||
ext.hsqldbVersion = "2.3.3"
|
||||
ext.htmlunitVersion = "2.20"
|
||||
ext.httpasyncVersion = "4.1.1"
|
||||
ext.httpclientVersion = "4.5.2"
|
||||
ext.jackson2Version = "2.7.4"
|
||||
ext.jackson2Version = "2.7.3"
|
||||
ext.jasperreportsVersion = "6.2.1"
|
||||
ext.javamailVersion = "1.5.5"
|
||||
ext.jettyVersion = "9.3.8.v20160314"
|
||||
ext.jodaVersion = "2.9.3"
|
||||
ext.jrubyVersion = "1.7.25" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
|
||||
ext.jrubyVersion = "1.7.24" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
|
||||
ext.jsonassertVersion = "1.3.0"
|
||||
ext.jsonpathVersion = "2.2.0"
|
||||
ext.jtaVersion = "1.2"
|
||||
ext.junitVersion = "4.12"
|
||||
ext.nettyVersion = "4.1.0.CR7"
|
||||
ext.nettyVersion = "4.0.36.Final"
|
||||
ext.okhttp3Version = "3.2.0"
|
||||
ext.okhttpVersion = "2.7.5"
|
||||
ext.okhttp3Version = "3.2.0"
|
||||
ext.openjpaVersion = "2.4.1"
|
||||
ext.poiVersion = "3.14"
|
||||
ext.reactorVersion = "2.0.8.RELEASE"
|
||||
ext.protobufVersion = "2.6.1"
|
||||
ext.reactorVersion = "2.0.7.RELEASE"
|
||||
ext.romeVersion = "1.6.0"
|
||||
ext.seleniumVersion = "2.52.0"
|
||||
ext.slf4jVersion = "1.7.21"
|
||||
ext.snakeyamlVersion = "1.17"
|
||||
ext.snifferVersion = "1.15"
|
||||
@@ -75,7 +80,8 @@ configure(allprojects) { project ->
|
||||
ext.tiles3Version = "3.0.5"
|
||||
ext.tomcatVersion = "8.0.33"
|
||||
ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support
|
||||
ext.undertowVersion = "1.3.22.Final"
|
||||
ext.undertowVersion = "1.3.20.Final"
|
||||
ext.woodstoxVersion = "5.0.2"
|
||||
ext.xmlunitVersion = "1.6"
|
||||
ext.xstreamVersion = "1.4.9"
|
||||
|
||||
@@ -130,6 +136,8 @@ configure(allprojects) { project ->
|
||||
|
||||
repositories {
|
||||
maven { url "https://repo.spring.io/libs-release" }
|
||||
maven { url "https://repo.spring.io/milestone" }
|
||||
maven { url "https://repo.spring.io/snapshot" } // reactor 2.0.6 snapshot
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -289,7 +297,7 @@ project("spring-core") {
|
||||
// both into the spring-core jar. cglib 3.2 itself depends on asm 5.0 and is therefore
|
||||
// further transformed by the JarJar task to depend on org.springframework.asm; this
|
||||
// avoids including two different copies of asm unnecessarily.
|
||||
def cglibVersion = "3.2.2"
|
||||
def cglibVersion = "3.2.0"
|
||||
def objenesisVersion = "2.2"
|
||||
|
||||
configurations {
|
||||
@@ -350,11 +358,11 @@ project("spring-core") {
|
||||
compile("commons-logging:commons-logging:1.2")
|
||||
optional("commons-codec:commons-codec:1.10")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("net.sf.jopt-simple:jopt-simple:5.0.1")
|
||||
optional("net.sf.jopt-simple:jopt-simple:5.0")
|
||||
optional("log4j:log4j:1.2.17")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
testCompile("com.fasterxml.woodstox:woodstox-core:5.0.2") {
|
||||
testCompile("com.fasterxml.woodstox:woodstox-core:${woodstoxVersion}") {
|
||||
exclude group: "stax", module: "stax-api"
|
||||
}
|
||||
}
|
||||
@@ -384,7 +392,7 @@ project("spring-beans") {
|
||||
optional("org.yaml:snakeyaml:${snakeyamlVersion}")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-beans-groovy") {
|
||||
@@ -474,7 +482,7 @@ project("spring-context") {
|
||||
compile(files(project(":spring-core").cglibRepackJar))
|
||||
optional(project(":spring-instrument"))
|
||||
optional("javax.inject:javax.inject:1")
|
||||
optional("javax.ejb:ejb-api:${ejbVersion}")
|
||||
optional("javax.ejb:ejb-api:${ejbApiVersion}")
|
||||
optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0")
|
||||
optional("javax.money:money-api:1.0")
|
||||
optional("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
@@ -544,7 +552,7 @@ project("spring-tx") {
|
||||
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
|
||||
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
|
||||
optional("javax.resource:connector-api:1.5")
|
||||
optional("javax.ejb:ejb-api:${ejbVersion}")
|
||||
optional("javax.ejb:ejb-api:${ejbApiVersion}")
|
||||
optional("com.ibm.websphere:uow:6.0.2.17")
|
||||
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
testCompile("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
@@ -563,6 +571,11 @@ project("spring-oxm") {
|
||||
targetCompatibility = 1.6
|
||||
}
|
||||
|
||||
if (!System.getProperty("java.version").contains("1.8.")) {
|
||||
// necessary because castor and xjc tasks cannot find the JDK's compiler on JDK 9
|
||||
compileTestJava.enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
@@ -641,7 +654,7 @@ project("spring-context-support") {
|
||||
optional("com.google.guava:guava:${guavaVersion}")
|
||||
optional("com.github.ben-manes.caffeine:caffeine:${caffeineVersion}")
|
||||
optional("net.sf.ehcache:ehcache:${ehcacheVersion}")
|
||||
optional("org.quartz-scheduler:quartz:2.2.3")
|
||||
optional("org.quartz-scheduler:quartz:2.2.2")
|
||||
optional("org.codehaus.fabric3.api:commonj:1.1.0")
|
||||
optional("org.apache.velocity:velocity:1.7")
|
||||
optional("org.freemarker:freemarker:${freemarkerVersion}")
|
||||
@@ -702,8 +715,8 @@ project("spring-web") {
|
||||
optional("org.apache.httpcomponents:httpclient:${httpclientVersion}")
|
||||
optional("org.apache.httpcomponents:httpasyncclient:${httpasyncVersion}")
|
||||
optional("io.netty:netty-all:${nettyVersion}")
|
||||
optional("com.squareup.okhttp:okhttp:${okhttpVersion}")
|
||||
optional("com.squareup.okhttp3:okhttp:${okhttp3Version}")
|
||||
optional("com.squareup.okhttp:okhttp:${okhttpVersion}")
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
|
||||
optional("com.google.code.gson:gson:${gsonVersion}")
|
||||
@@ -715,8 +728,8 @@ project("spring-web") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet-api"
|
||||
}
|
||||
optional("log4j:log4j:1.2.17")
|
||||
optional("com.google.protobuf:protobuf-java:2.6.1")
|
||||
optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.4")
|
||||
optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.2")
|
||||
optional("com.google.protobuf:protobuf-java:${protobufVersion}")
|
||||
optional("javax.mail:javax.mail-api:${javamailVersion}")
|
||||
testCompile(project(":spring-context-support")) // for JafMediaTypeFactory
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
@@ -731,6 +744,52 @@ project("spring-web") {
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-websocket") {
|
||||
description = "Spring WebSocket"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-core"))
|
||||
compile(project(":spring-context"))
|
||||
compile(project(":spring-web"))
|
||||
optional(project(":spring-messaging"))
|
||||
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:${tomcatVersion}") {
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-websocket-api"
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-servlet-api"
|
||||
}
|
||||
optional("org.glassfish.tyrus:tyrus-spi:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-core:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-server:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-container-servlet:${tyrusVersion}")
|
||||
optional("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-server:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
|
||||
optional("org.eclipse.jetty:jetty-client:${jettyVersion}")
|
||||
optional("io.undertow:undertow-core:${undertowVersion}")
|
||||
optional("io.undertow:undertow-servlet:${undertowVersion}") {
|
||||
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:${undertowVersion}") {
|
||||
exclude group: "org.jboss.spec.javax.websocket", module: "jboss-websocket-api_1.1_spec"
|
||||
}
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
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("io.projectreactor:reactor-net:${reactorVersion}")
|
||||
testCompile("io.netty:netty-all:${nettyVersion}")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-orm") {
|
||||
description = "Spring Object/Relational Mapping"
|
||||
|
||||
@@ -815,7 +874,7 @@ project("spring-webmvc") {
|
||||
compile(files(project(":spring-core").objenesisRepackJar))
|
||||
compile(project(":spring-expression"))
|
||||
compile(project(":spring-web"))
|
||||
provided("javax.servlet:javax.servlet-api:3.1.0")
|
||||
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:javax.servlet.jsp-api:2.2.1")
|
||||
@@ -857,8 +916,8 @@ project("spring-webmvc") {
|
||||
exclude group: "org.slf4j", module: "jcl-over-slf4j"
|
||||
exclude group: "org.springframework", module: "spring-web"
|
||||
}
|
||||
optional('org.webjars:webjars-locator:0.30')
|
||||
testCompile("org.mozilla:rhino:1.7.7.1")
|
||||
optional('org.webjars:webjars-locator:0.28')
|
||||
testCompile("rhino:js:1.7R1")
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
testCompile("dom4j:dom4j:1.6.1") {
|
||||
exclude group: "xml-apis", module: "xml-apis"
|
||||
@@ -934,52 +993,6 @@ project("spring-webmvc-portlet") {
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-websocket") {
|
||||
description = "Spring WebSocket"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-core"))
|
||||
compile(project(":spring-context"))
|
||||
compile(project(":spring-web"))
|
||||
optional(project(":spring-messaging"))
|
||||
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:${tomcatVersion}") {
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-websocket-api"
|
||||
exclude group: "org.apache.tomcat", module: "tomcat-servlet-api"
|
||||
}
|
||||
optional("org.glassfish.tyrus:tyrus-spi:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-core:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-server:${tyrusVersion}")
|
||||
optional("org.glassfish.tyrus:tyrus-container-servlet:${tyrusVersion}")
|
||||
optional("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-server:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet"
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
|
||||
optional("org.eclipse.jetty:jetty-client:${jettyVersion}")
|
||||
optional("io.undertow:undertow-core:${undertowVersion}")
|
||||
optional("io.undertow:undertow-servlet:${undertowVersion}") {
|
||||
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:${undertowVersion}") {
|
||||
exclude group: "org.jboss.spec.javax.websocket", module: "jboss-websocket-api_1.1_spec"
|
||||
}
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
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("io.projectreactor:reactor-net:${reactorVersion}")
|
||||
testCompile("io.netty:netty-all:${nettyVersion}")
|
||||
testCompile("log4j:log4j:1.2.17")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-test") {
|
||||
description = "Spring TestContext Framework"
|
||||
|
||||
@@ -1007,16 +1020,15 @@ project("spring-test") {
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
optional("org.hamcrest:hamcrest-core:${hamcrestVersion}")
|
||||
optional("com.jayway.jsonpath:json-path:${jsonpathVersion}")
|
||||
optional("org.skyscreamer:jsonassert:${jsonassertVersion}")
|
||||
optional("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
optional("net.sourceforge.htmlunit:htmlunit:2.21")
|
||||
optional("org.seleniumhq.selenium:htmlunit-driver:2.20")
|
||||
optional("org.seleniumhq.selenium:selenium-java:2.53.0")
|
||||
optional("org.skyscreamer:jsonassert:1.3.0")
|
||||
optional("com.jayway.jsonpath:json-path:2.2.0")
|
||||
optional("net.sourceforge.htmlunit:htmlunit:${htmlunitVersion}")
|
||||
optional("org.seleniumhq.selenium:selenium-htmlunit-driver:${seleniumVersion}")
|
||||
testCompile(project(":spring-context-support"))
|
||||
testCompile(project(":spring-oxm"))
|
||||
testCompile("javax.mail:javax.mail-api:${javamailVersion}")
|
||||
testCompile("javax.ejb:ejb-api:${ejbVersion}")
|
||||
testCompile("javax.ejb:ejb-api:${ejbApiVersion}")
|
||||
testCompile("org.hibernate:hibernate-core:${hibernate4Version}")
|
||||
testCompile("org.hibernate:hibernate-entitymanager:${hibernate4Version}")
|
||||
testCompile("org.hibernate:hibernate-validator:${hibval5Version}")
|
||||
@@ -1070,9 +1082,9 @@ project("spring-aspects") {
|
||||
|
||||
dependencies {
|
||||
aspects(project(":spring-orm"))
|
||||
ajc("org.aspectj:aspectjtools:${aspectjVersion}")
|
||||
rt("org.aspectj:aspectjrt:${aspectjVersion}")
|
||||
compile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
ajc("org.aspectj:aspectjtools:${aspectjVersion}") // for the ability to build on JDK 9, not exposed in the POMs yet
|
||||
rt("org.aspectj:aspectjrt:1.8.7") // regular AspectJ version here, to be exposed in the POMs
|
||||
compile("org.aspectj:aspectjweaver:1.8.7")
|
||||
provided("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
optional(project(":spring-aop")) // for @Async support
|
||||
optional(project(":spring-beans")) // for @Configurable support
|
||||
@@ -1157,7 +1169,9 @@ configure(rootProject) {
|
||||
separateOutputDirs = false
|
||||
backends = ['docbook']
|
||||
options doctype: 'book', eruby: 'erubis'
|
||||
attributes 'spring-version': project.version, 'revnumber': project.version, 'docinfo': ""
|
||||
attributes 'spring-version': project.version,
|
||||
'revnumber' : project.version,
|
||||
'docinfo' : ""
|
||||
}
|
||||
|
||||
reference {
|
||||
@@ -1293,7 +1307,7 @@ configure(rootProject) {
|
||||
baseName = "spring-framework"
|
||||
classifier = "dist"
|
||||
description = "Builds -${classifier} archive, containing all jars and docs, " +
|
||||
"suitable for community download page."
|
||||
"suitable for community download page."
|
||||
|
||||
ext.baseDir = "${baseName}-${project.version}";
|
||||
|
||||
@@ -1366,7 +1380,7 @@ configure(rootProject) {
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
description = "Generates gradlew[.bat] scripts"
|
||||
gradleVersion = "2.13"
|
||||
gradleVersion = "2.12"
|
||||
|
||||
doLast() {
|
||||
def gradleOpts = "-XX:MaxMetaspaceSize=1024m -Xmx1024m"
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.3.0.RC2
|
||||
version=4.3.0.RC1
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Mon Apr 25 12:42:24 CEST 2016
|
||||
#Mon Mar 14 14:42:52 CET 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip
|
||||
|
||||
@@ -6,31 +6,13 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
GRADLE_OPTS="-XX:MaxMetaspaceSize=1024m -Xmx1024m $GRADLE_OPTS"
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
@@ -49,7 +31,6 @@ die ( ) {
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
@@ -60,11 +41,26 @@ case "`uname`" in
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -90,7 +86,7 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
|
||||
Vendored
+4
-4
@@ -8,15 +8,15 @@
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set GRADLE_OPTS=-XX:MaxMetaspaceSize=1024m -Xmx1024m -XX:MaxHeapSize=256m %GRADLE_OPTS%
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set GRADLE_OPTS=-XX:MaxMetaspaceSize=1024m -Xmx1024m -XX:MaxHeapSize=256m %GRADLE_OPTS%
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ REM - generates OXM test classes to avoid errors on import into Eclipse
|
||||
REM - generates metadata for all subprojects
|
||||
REM - skips metadata gen for the root project (-x :eclipse) to work
|
||||
REM around Eclipse's inability to import hierarchical project structures
|
||||
REM SET COMMAND="./gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
|
||||
SET COMMAND=gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse
|
||||
REM SET COMMAND="./gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
|
||||
SET COMMAND=gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse
|
||||
|
||||
echo.
|
||||
echo -----------------------------------------------------------------------
|
||||
@@ -69,7 +69,7 @@ echo When the above is complete, return here and press the enter key.
|
||||
|
||||
pause
|
||||
|
||||
set COMMAND=gradlew --no-daemon :eclipse
|
||||
set COMMAND=gradlew :eclipse
|
||||
|
||||
echo.
|
||||
echo -----------------------------------------------------------------------
|
||||
|
||||
@@ -42,7 +42,7 @@ read
|
||||
# - generates metadata for all subprojects
|
||||
# - skips metadata gen for the root project (-x :eclipse) to work
|
||||
# around Eclipse's inability to import hierarchical project structures
|
||||
COMMAND="./gradlew --no-daemon cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
|
||||
COMMAND="./gradlew cleanEclipse :spring-oxm:compileTestJava eclipse -x :eclipse"
|
||||
|
||||
cat <<EOM
|
||||
|
||||
@@ -84,7 +84,7 @@ EOM
|
||||
|
||||
read
|
||||
|
||||
COMMAND="./gradlew --no-daemon :eclipse"
|
||||
COMMAND="./gradlew :eclipse"
|
||||
|
||||
cat <<EOM
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.aopalliance.aop.Advice;
|
||||
* in) joinpoints. Runtime joinpoints can be invocations, field
|
||||
* access, exceptions...
|
||||
*
|
||||
* <p>This interface is not used directly. Use the sub-interfaces
|
||||
* <p>This interface is not used directly. Use the the sub-interfaces
|
||||
* to intercept specific events. For instance, the following class
|
||||
* implements some specific interceptors in order to implement a
|
||||
* debugger:
|
||||
|
||||
@@ -65,7 +65,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
|
||||
/**
|
||||
* Private constructor to share common code between impl-based delegate and reference-based delegate
|
||||
* (cannot use method such as init() to share common code, due the use of final fields)
|
||||
* (cannot use method such as init() to share common code, due the the use of final fields)
|
||||
* @param interfaceType static field defining the introduction
|
||||
* @param typePattern type pattern the introduction is restricted to
|
||||
* @param implementationClass implementation class
|
||||
|
||||
+7
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,6 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.OrderUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -70,8 +69,6 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
* @param type the type that should be introspected by AspectJ
|
||||
*/
|
||||
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class<?> type) {
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
Assert.notNull(name, "Bean name must not be null");
|
||||
this.beanFactory = beanFactory;
|
||||
this.name = name;
|
||||
this.aspectMetadata = new AspectMetadata(type, name);
|
||||
@@ -85,9 +82,12 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
|
||||
@Override
|
||||
public ClassLoader getAspectClassLoader() {
|
||||
return (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
|
||||
ClassUtils.getDefaultClassLoader());
|
||||
if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
|
||||
}
|
||||
else {
|
||||
return ClassUtils.getDefaultClassLoader();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,12 +95,6 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
return this.aspectMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex() : this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the order for this factory's target aspect, either
|
||||
* an instance-specific order expressed through implementing the
|
||||
|
||||
+3
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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,9 +46,9 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
|
||||
|
||||
@Override
|
||||
public Object getAspectInstance() {
|
||||
public synchronized Object getAspectInstance() {
|
||||
if (this.materialized == null) {
|
||||
synchronized (this.maaif.getAspectCreationMutex()) {
|
||||
synchronized (this) {
|
||||
if (this.materialized == null) {
|
||||
this.materialized = this.maaif.getAspectInstance();
|
||||
}
|
||||
@@ -71,11 +71,6 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
return this.maaif.getAspectMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return this.maaif.getAspectCreationMutex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.maaif.getOrder();
|
||||
|
||||
+1
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,11 +39,4 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor
|
||||
*/
|
||||
AspectMetadata getAspectMetadata();
|
||||
|
||||
/**
|
||||
* Return the best possible creation mutex for this factory.
|
||||
* @return the mutex object (never {@code null})
|
||||
* @since 4.3
|
||||
*/
|
||||
Object getAspectCreationMutex();
|
||||
|
||||
}
|
||||
|
||||
+1
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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,11 +50,6 @@ public class SimpleMetadataAwareAspectInstanceFactory extends SimpleAspectInstan
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getOrderForAspectClass(Class<?> aspectClass) {
|
||||
return OrderUtils.getOrder(aspectClass, Ordered.LOWEST_PRECEDENCE);
|
||||
|
||||
+1
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -55,11 +55,6 @@ public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspect
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getOrderForAspectClass(Class<?> aspectClass) {
|
||||
return OrderUtils.getOrder(aspectClass, Ordered.LOWEST_PRECEDENCE);
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.framework.AopInfrastructureBean;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
@@ -371,7 +370,6 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
*/
|
||||
protected boolean isInfrastructureClass(Class<?> beanClass) {
|
||||
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
|
||||
Pointcut.class.isAssignableFrom(beanClass) ||
|
||||
Advisor.class.isAssignableFrom(beanClass) ||
|
||||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
|
||||
if (retVal && logger.isTraceEnabled()) {
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public abstract class AutoProxyUtils {
|
||||
* to be proxied with its target class (in case of it getting proxied in the first
|
||||
* place). The value is {@code Boolean.TRUE} or {@code Boolean.FALSE}.
|
||||
* <p>Proxy factories can set this attribute if they built a target class proxy
|
||||
* for a specific bean, and want to enforce that bean can always be cast
|
||||
* for a specific bean, and want to enforce that that bean can always be cast
|
||||
* to its target class (even if AOP advices get applied through auto-proxying).
|
||||
* @see #shouldProxyTargetClass
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -222,11 +222,6 @@ public abstract class AopUtils {
|
||||
}
|
||||
|
||||
MethodMatcher methodMatcher = pc.getMethodMatcher();
|
||||
if (methodMatcher == MethodMatcher.TRUE) {
|
||||
// No need to iterate the methods if we're matching any method anyway...
|
||||
return true;
|
||||
}
|
||||
|
||||
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
|
||||
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
|
||||
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
|
||||
@@ -235,7 +230,7 @@ public abstract class AopUtils {
|
||||
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
|
||||
classes.add(targetClass);
|
||||
for (Class<?> clazz : classes) {
|
||||
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (Method method : methods) {
|
||||
if ((introductionAwareMethodMatcher != null &&
|
||||
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
|
||||
|
||||
+1
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -693,11 +693,6 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
|
||||
return new AspectMetadata(PerTypeWithinAspect.class, "perTypeWithin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
+22
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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,10 +87,10 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int autoGrowCollectionLimit = Integer.MAX_VALUE;
|
||||
|
||||
Object wrappedObject;
|
||||
/** The wrapped object */
|
||||
private Object object;
|
||||
|
||||
private String nestedPath = "";
|
||||
|
||||
@@ -204,23 +204,23 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
public void setWrappedInstance(Object object, String nestedPath, Object rootObject) {
|
||||
Assert.notNull(object, "Target object must not be null");
|
||||
if (object.getClass() == javaUtilOptionalClass) {
|
||||
this.wrappedObject = OptionalUnwrapper.unwrap(object);
|
||||
this.object = OptionalUnwrapper.unwrap(object);
|
||||
}
|
||||
else {
|
||||
this.wrappedObject = object;
|
||||
this.object = object;
|
||||
}
|
||||
this.nestedPath = (nestedPath != null ? nestedPath : "");
|
||||
this.rootObject = (!"".equals(this.nestedPath) ? rootObject : this.wrappedObject);
|
||||
this.rootObject = (!"".equals(this.nestedPath) ? rootObject : this.object);
|
||||
this.nestedPropertyAccessors = null;
|
||||
this.typeConverterDelegate = new TypeConverterDelegate(this, this.wrappedObject);
|
||||
this.typeConverterDelegate = new TypeConverterDelegate(this, this.object);
|
||||
}
|
||||
|
||||
public final Object getWrappedInstance() {
|
||||
return this.wrappedObject;
|
||||
return this.object;
|
||||
}
|
||||
|
||||
public final Class<?> getWrappedClass() {
|
||||
return (this.wrappedObject != null ? this.wrappedObject.getClass() : null);
|
||||
return (this.object != null ? this.object.getClass() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,7 +303,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
catch (NotReadablePropertyException ex) {
|
||||
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Cannot access indexed value in property referenced " +
|
||||
"in indexed property path '" + propertyName + "'", ex);
|
||||
"in indexed property path '" + propertyName + "'", ex);
|
||||
}
|
||||
// Set value for last key.
|
||||
String key = tokens.keys[tokens.keys.length - 1];
|
||||
@@ -318,7 +318,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
else {
|
||||
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Cannot access indexed value in property referenced " +
|
||||
"in indexed property path '" + propertyName + "': returned null");
|
||||
"in indexed property path '" + propertyName + "': returned null");
|
||||
}
|
||||
}
|
||||
if (propValue.getClass().isArray()) {
|
||||
@@ -367,8 +367,8 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
catch (NullPointerException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Cannot set element with index " + index + " in List of size " +
|
||||
size + ", accessed using property path '" + propertyName +
|
||||
"': List does not support filling up gaps with null elements");
|
||||
size + ", accessed using property path '" + propertyName +
|
||||
"': List does not support filling up gaps with null elements");
|
||||
}
|
||||
}
|
||||
list.add(convertedValue);
|
||||
@@ -405,7 +405,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
else {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Property referenced in indexed property path '" + propertyName +
|
||||
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
|
||||
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
}
|
||||
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
|
||||
}
|
||||
ph.setValue(this.wrappedObject, valueToApply);
|
||||
ph.setValue(object, valueToApply);
|
||||
}
|
||||
catch (TypeMismatchException ex) {
|
||||
throw ex;
|
||||
@@ -800,7 +800,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
|
||||
/**
|
||||
* Recursively navigate to return a property accessor for the nested property path.
|
||||
* @param propertyPath property path, which may be nested
|
||||
* @param propertyPath property property path, which may be nested
|
||||
* @return a property accessor for the target bean
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // avoid nested generic
|
||||
@@ -953,9 +953,10 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
tokens.actualName = (actualName != null ? actualName : propertyName);
|
||||
tokens.canonicalName = tokens.actualName;
|
||||
if (!keys.isEmpty()) {
|
||||
tokens.canonicalName += PROPERTY_KEY_PREFIX +
|
||||
StringUtils.collectionToDelimitedString(keys, PROPERTY_KEY_SUFFIX + PROPERTY_KEY_PREFIX) +
|
||||
PROPERTY_KEY_SUFFIX;
|
||||
tokens.canonicalName +=
|
||||
PROPERTY_KEY_PREFIX +
|
||||
StringUtils.collectionToDelimitedString(keys, PROPERTY_KEY_SUFFIX + PROPERTY_KEY_PREFIX) +
|
||||
PROPERTY_KEY_SUFFIX;
|
||||
tokens.keys = StringUtils.toStringArray(keys);
|
||||
}
|
||||
return tokens;
|
||||
@@ -964,8 +965,8 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(getClass().getName());
|
||||
if (this.wrappedObject != null) {
|
||||
sb.append(": wrapping object [").append(ObjectUtils.identityToString(this.wrappedObject)).append("]");
|
||||
if (this.object != null) {
|
||||
sb.append(": wrapping object [").append(ObjectUtils.identityToString(this.object)).append("]");
|
||||
}
|
||||
else {
|
||||
sb.append(": no wrapped object set");
|
||||
|
||||
+2
-57
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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,9 +16,6 @@
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Exception thrown when instantiation of a bean failed.
|
||||
* Carries the offending bean class.
|
||||
@@ -31,10 +28,6 @@ public class BeanInstantiationException extends FatalBeanException {
|
||||
|
||||
private Class<?> beanClass;
|
||||
|
||||
private Constructor<?> constructor;
|
||||
|
||||
private Method constructingMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new BeanInstantiationException.
|
||||
@@ -56,60 +49,12 @@ public class BeanInstantiationException extends FatalBeanException {
|
||||
this.beanClass = beanClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BeanInstantiationException.
|
||||
* @param constructor the offending constructor
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause
|
||||
* @since 4.3
|
||||
*/
|
||||
public BeanInstantiationException(Constructor<?> constructor, String msg, Throwable cause) {
|
||||
super("Failed to instantiate [" + constructor.getDeclaringClass().getName() + "]: " + msg, cause);
|
||||
this.beanClass = constructor.getDeclaringClass();
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BeanInstantiationException.
|
||||
* @param constructingMethod the delegate for bean construction purposes
|
||||
* (typically, but not necessarily, a static factory method)
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause
|
||||
* @since 4.3
|
||||
*/
|
||||
public BeanInstantiationException(Method constructingMethod, String msg, Throwable cause) {
|
||||
super("Failed to instantiate [" + constructingMethod.getReturnType().getName() + "]: " + msg, cause);
|
||||
this.beanClass = constructingMethod.getReturnType();
|
||||
this.constructingMethod = constructingMethod;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the offending bean class (never {@code null}).
|
||||
* @return the class that was to be instantiated
|
||||
* Return the offending bean class.
|
||||
*/
|
||||
public Class<?> getBeanClass() {
|
||||
return this.beanClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the offending constructor, if known.
|
||||
* @return the constructor in use, or {@code null} in case of a
|
||||
* factory method or in case of default instantiation
|
||||
* @since 4.3
|
||||
*/
|
||||
public Constructor<?> getConstructor() {
|
||||
return this.constructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the delegate for bean construction purposes, if known.
|
||||
* @return the method in use (typically a static factory method),
|
||||
* or {@code null} in case of constructor-based instantiation
|
||||
* @since 4.3
|
||||
*/
|
||||
public Method getConstructingMethod() {
|
||||
return this.constructingMethod;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public abstract class BeanUtils {
|
||||
|
||||
/**
|
||||
* Instantiate a class using its no-arg constructor and return the new instance
|
||||
* as the specified assignable type.
|
||||
* as the the specified assignable type.
|
||||
* <p>Useful in cases where
|
||||
* the type of the class to instantiate (clazz) is not available, but the type
|
||||
* desired (assignableTo) is known.
|
||||
@@ -147,16 +147,20 @@ public abstract class BeanUtils {
|
||||
return ctor.newInstance(args);
|
||||
}
|
||||
catch (InstantiationException ex) {
|
||||
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
|
||||
throw new BeanInstantiationException(ctor.getDeclaringClass(),
|
||||
"Is it an abstract class?", ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
|
||||
throw new BeanInstantiationException(ctor.getDeclaringClass(),
|
||||
"Is the constructor accessible?", ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
|
||||
throw new BeanInstantiationException(ctor.getDeclaringClass(),
|
||||
"Illegal arguments for constructor", ex);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
|
||||
throw new BeanInstantiationException(ctor.getDeclaringClass(),
|
||||
"Constructor threw exception", ex.getTargetException());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -48,19 +48,6 @@ import java.beans.PropertyDescriptor;
|
||||
*/
|
||||
public interface BeanWrapper extends ConfigurablePropertyAccessor {
|
||||
|
||||
/**
|
||||
* Specify a limit for array and collection auto-growing.
|
||||
* <p>Default is unlimited on a plain BeanWrapper.
|
||||
* @since 4.1
|
||||
*/
|
||||
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
|
||||
|
||||
/**
|
||||
* Return the limit for array and collection auto-growing.
|
||||
* @since 4.1
|
||||
*/
|
||||
int getAutoGrowCollectionLimit();
|
||||
|
||||
/**
|
||||
* Return the bean instance wrapped by this object, if any.
|
||||
* @return the bean instance, or {@code null} if none set
|
||||
@@ -91,4 +78,15 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
|
||||
*/
|
||||
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
|
||||
|
||||
/**
|
||||
* Specify a limit for array and collection auto-growing.
|
||||
* <p>Default is unlimited on a plain BeanWrapper.
|
||||
*/
|
||||
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
|
||||
|
||||
/**
|
||||
* Return the limit for array and collection auto-growing.
|
||||
*/
|
||||
int getAutoGrowCollectionLimit();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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,45 +133,10 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a bean instance to hold, without any unwrapping of {@link java.util.Optional}.
|
||||
* @param object the actual target object
|
||||
* @since 4.3
|
||||
* @see #setWrappedInstance(Object)
|
||||
*/
|
||||
public void setBeanInstance(Object object) {
|
||||
this.wrappedObject = object;
|
||||
this.typeConverterDelegate = new TypeConverterDelegate(this, this.wrappedObject);
|
||||
setIntrospectionClass(object.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWrappedInstance(Object object, String nestedPath, Object rootObject) {
|
||||
super.setWrappedInstance(object, nestedPath, rootObject);
|
||||
setIntrospectionClass(getWrappedClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class to introspect.
|
||||
* Needs to be called when the target object changes.
|
||||
* @param clazz the class to introspect
|
||||
*/
|
||||
protected void setIntrospectionClass(Class<?> clazz) {
|
||||
if (this.cachedIntrospectionResults != null && this.cachedIntrospectionResults.getBeanClass() != clazz) {
|
||||
this.cachedIntrospectionResults = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a lazily initializted CachedIntrospectionResults instance
|
||||
* for the wrapped object.
|
||||
*/
|
||||
private CachedIntrospectionResults getCachedIntrospectionResults() {
|
||||
Assert.state(getWrappedInstance() != null, "BeanWrapper does not hold a bean instance");
|
||||
if (this.cachedIntrospectionResults == null) {
|
||||
this.cachedIntrospectionResults = CachedIntrospectionResults.forClass(getWrappedClass());
|
||||
}
|
||||
return this.cachedIntrospectionResults;
|
||||
setIntrospectionClass(getWrappedInstance().getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,6 +155,30 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
return this.acc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class to introspect.
|
||||
* Needs to be called when the target object changes.
|
||||
* @param clazz the class to introspect
|
||||
*/
|
||||
protected void setIntrospectionClass(Class<?> clazz) {
|
||||
if (this.cachedIntrospectionResults != null &&
|
||||
!clazz.equals(this.cachedIntrospectionResults.getBeanClass())) {
|
||||
this.cachedIntrospectionResults = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a lazily initializted CachedIntrospectionResults instance
|
||||
* for the wrapped object.
|
||||
*/
|
||||
private CachedIntrospectionResults getCachedIntrospectionResults() {
|
||||
Assert.state(getWrappedInstance() != null, "BeanWrapper does not hold a bean instance");
|
||||
if (this.cachedIntrospectionResults == null) {
|
||||
this.cachedIntrospectionResults = CachedIntrospectionResults.forClass(getWrappedClass());
|
||||
}
|
||||
return this.cachedIntrospectionResults;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert the given value for the specified property to the latter's type.
|
||||
|
||||
+1
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -303,24 +303,6 @@ public class CachedIntrospectionResults {
|
||||
this.propertyDescriptorCache.put(pd.getName(), pd);
|
||||
}
|
||||
|
||||
// Explicitly check implemented interfaces for setter/getter methods as well,
|
||||
// in particular for Java 8 default methods...
|
||||
Class<?> clazz = beanClass;
|
||||
while (clazz != null) {
|
||||
Class<?>[] ifcs = clazz.getInterfaces();
|
||||
for (Class<?> ifc : ifcs) {
|
||||
BeanInfo ifcInfo = Introspector.getBeanInfo(ifc, Introspector.IGNORE_ALL_BEANINFO);
|
||||
PropertyDescriptor[] ifcPds = ifcInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor pd : ifcPds) {
|
||||
if (!this.propertyDescriptorCache.containsKey(pd.getName())) {
|
||||
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
||||
this.propertyDescriptorCache.put(pd.getName(), pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
|
||||
this.typeDescriptorCache = new ConcurrentReferenceHashMap<PropertyDescriptor, TypeDescriptor>();
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
|
||||
+3
-3
@@ -88,7 +88,7 @@ import org.springframework.core.io.support.ResourcePatternUtils;
|
||||
* use object from a BeanFactory/ApplicationContext. One solutions is to make the
|
||||
* class created by the third party code be just a stub or proxy, which gets the
|
||||
* real object from a BeanFactory/ApplicationContext, and delegates to it. However,
|
||||
* it is not normally workable for the stub to create the BeanFactory on each
|
||||
* it is is not normally workable for the stub to create the BeanFactory on each
|
||||
* use, as depending on what is inside it, that can be an expensive operation.
|
||||
* Additionally, there is a fairly tight coupling between the stub and the name of
|
||||
* the definition resource for the BeanFactory/ApplicationContext. This is where
|
||||
@@ -291,7 +291,7 @@ public class SingletonBeanFactoryLocator implements BeanFactoryLocator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance which uses the specified selector, as the name of the
|
||||
* Returns an instance which uses the the specified selector, as the name of the
|
||||
* definition file(s). In the case of a name with a Spring 'classpath*:' prefix,
|
||||
* or with no prefix, which is treated the same, the current thread context
|
||||
* ClassLoader's {@code getResources} method will be called with this value
|
||||
@@ -341,7 +341,7 @@ public class SingletonBeanFactoryLocator implements BeanFactoryLocator {
|
||||
|
||||
|
||||
/**
|
||||
* Constructor which uses the specified name as the resource name
|
||||
* Constructor which uses the the specified name as the resource name
|
||||
* of the definition file(s).
|
||||
* @param resourceLocation the Spring resource location to use
|
||||
* (either a URL or a "classpath:" / "classpath*:" pseudo URL)
|
||||
|
||||
+1
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -209,13 +209,6 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
|
||||
*/
|
||||
void addEmbeddedValueResolver(StringValueResolver valueResolver);
|
||||
|
||||
/**
|
||||
* Determine whether an embedded value resolver has been registered with this
|
||||
* bean factory, to be applied through {@link #resolveEmbeddedValue(String)}.
|
||||
* @since 4.3
|
||||
*/
|
||||
boolean hasEmbeddedValueResolver();
|
||||
|
||||
/**
|
||||
* Resolve the given embedded value, e.g. an annotation attribute.
|
||||
* @param value the value to resolve
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
|
||||
* dependency types - which the factory handles specifically - already filtered out)
|
||||
* @param bean the bean instance created, but whose properties have not yet been set
|
||||
* @param beanName the name of the bean
|
||||
* @return the actual property values to apply to the given bean
|
||||
* @return the actual property values to apply to to the given bean
|
||||
* (can be the passed-in PropertyValues instance), or {@code null}
|
||||
* to skip property population
|
||||
* @throws org.springframework.beans.BeansException in case of errors
|
||||
|
||||
@@ -100,7 +100,7 @@ public interface Scope {
|
||||
* at the appropriate time. If such a callback is not supported by the
|
||||
* underlying runtime environment at all, the callback <i>must be
|
||||
* ignored and a corresponding warning should be logged</i>.
|
||||
* <p>Note that 'destruction' refers to automatic destruction of
|
||||
* <p>Note that 'destruction' refers to to automatic destruction of
|
||||
* the object as part of the scope's own lifecycle, not to the individual
|
||||
* scoped object having been explicitly removed by the application.
|
||||
* If a scoped object gets removed via this facade's {@link #remove(String)}
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
|
||||
* {@link org.springframework.context.ApplicationContext} implementations.
|
||||
* <p>If given a plain BeanDefinitionRegistry, the default ResourceLoader will be a
|
||||
* {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver}.
|
||||
* <p>If the passed-in bean factory also implements {@link EnvironmentCapable} its
|
||||
* <p>If the the passed-in bean factory also implements {@link EnvironmentCapable} its
|
||||
* environment will be used by this reader. Otherwise, the reader will initialize and
|
||||
* use a {@link StandardEnvironment}. All ApplicationContext implementations are
|
||||
* EnvironmentCapable, while normal BeanFactory implementations are not.
|
||||
|
||||
+1
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -798,11 +798,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
this.embeddedValueResolvers.add(valueResolver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEmbeddedValueResolver() {
|
||||
return !this.embeddedValueResolvers.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveEmbeddedValue(String value) {
|
||||
String result = value;
|
||||
|
||||
+1
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -166,17 +166,6 @@ public class BeanDefinitionBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an indexed constructor arg value. The current index is tracked internally
|
||||
* and all additions are at the present point.
|
||||
* @deprecated since Spring 2.5, in favor of {@link #addConstructorArgValue}.
|
||||
* This variant just remains around for Spring Security 2.x compatibility.
|
||||
*/
|
||||
@Deprecated
|
||||
public BeanDefinitionBuilder addConstructorArg(Object value) {
|
||||
return addConstructorArgValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an indexed constructor arg value. The current index is tracked internally
|
||||
* and all additions are at the present point.
|
||||
|
||||
+2
-2
@@ -272,7 +272,7 @@ class ConstructorResolver {
|
||||
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
|
||||
}
|
||||
|
||||
bw.setBeanInstance(beanInstance);
|
||||
bw.setWrappedInstance(beanInstance);
|
||||
return bw;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
@@ -592,7 +592,7 @@ class ConstructorResolver {
|
||||
if (beanInstance == null) {
|
||||
return null;
|
||||
}
|
||||
bw.setBeanInstance(beanInstance);
|
||||
bw.setWrappedInstance(beanInstance);
|
||||
return bw;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -171,12 +171,12 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new BeanInstantiationException(factoryMethod,
|
||||
throw new BeanInstantiationException(factoryMethod.getReturnType(),
|
||||
"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
|
||||
"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new BeanInstantiationException(factoryMethod,
|
||||
throw new BeanInstantiationException(factoryMethod.getReturnType(),
|
||||
"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
@@ -186,7 +186,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
||||
msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
|
||||
"declaring the factory method as static for independence from its containing instance. " + msg;
|
||||
}
|
||||
throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
|
||||
throw new BeanInstantiationException(factoryMethod.getReturnType(), msg, ex.getTargetException());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -84,7 +84,7 @@ public class StringArrayPropertyEditor extends PropertyEditorSupport {
|
||||
* @param emptyArrayAsNull {@code true} if an empty String array
|
||||
* is to be transformed into {@code null}
|
||||
* @param trimValues {@code true} if the values in the parsed arrays
|
||||
* are to be trimmed of whitespace (default is true).
|
||||
* are to be be trimmed of whitespace (default is true).
|
||||
*/
|
||||
public StringArrayPropertyEditor(String separator, boolean emptyArrayAsNull, boolean trimValues) {
|
||||
this(separator, null, emptyArrayAsNull, trimValues);
|
||||
@@ -112,7 +112,7 @@ public class StringArrayPropertyEditor extends PropertyEditorSupport {
|
||||
* @param emptyArrayAsNull {@code true} if an empty String array
|
||||
* is to be transformed into {@code null}
|
||||
* @param trimValues {@code true} if the values in the parsed arrays
|
||||
* are to be trimmed of whitespace (default is true).
|
||||
* are to be be trimmed of whitespace (default is true).
|
||||
*/
|
||||
public StringArrayPropertyEditor(String separator, String charsToDelete, boolean emptyArrayAsNull, boolean trimValues) {
|
||||
this.separator = separator;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -61,14 +61,6 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
assertTrue("Set name to tom", target.getName().equals("tom"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aliasedSetterThroughDefaultMethod() {
|
||||
GetterBean target = new GetterBean();
|
||||
BeanWrapper accessor = createAccessor(target);
|
||||
accessor.setPropertyValue("aliasedName", "tom");
|
||||
assertTrue("Set name to tom", target.getAliasedName().equals("tom"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setValidAndInvalidPropertyValuesShouldContainExceptionDetails() {
|
||||
TestBean target = new TestBean();
|
||||
@@ -204,24 +196,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private interface AliasedProperty {
|
||||
|
||||
default void setAliasedName(String name) {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
default String getAliasedName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
void setName(String name);
|
||||
|
||||
String getName();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class GetterBean implements AliasedProperty {
|
||||
private static class GetterBean {
|
||||
|
||||
private String name;
|
||||
|
||||
@@ -237,7 +212,6 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class IntelliBean {
|
||||
|
||||
|
||||
+1
-21
@@ -31,7 +31,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -2712,7 +2711,7 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveEmbeddedValue() {
|
||||
public void resolveEmbeddedValue() throws Exception {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
StringValueResolver r1 = mock(StringValueResolver.class);
|
||||
StringValueResolver r2 = mock(StringValueResolver.class);
|
||||
@@ -2731,25 +2730,6 @@ public class DefaultListableBeanFactoryTests {
|
||||
verify(r3, never()).resolveStringValue(isNull(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void populatedJavaUtilOptionalBean() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd = new RootBeanDefinition(Optional.class);
|
||||
bd.setFactoryMethodName("of");
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue("CONTENT");
|
||||
bf.registerBeanDefinition("optionalBean", bd);
|
||||
assertEquals(Optional.of("CONTENT"), bf.getBean(Optional.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyJavaUtilOptionalBean() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd = new RootBeanDefinition(Optional.class);
|
||||
bd.setFactoryMethodName("empty");
|
||||
bf.registerBeanDefinition("optionalBean", bd);
|
||||
assertSame(Optional.empty(), bf.getBean(Optional.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that by-type bean lookup caching is working effectively by searching for a
|
||||
* bean of type B 10K times within a container having 1K additional beans of type A.
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Transaction-aware decorators for the org.springframework.cache package.
|
||||
* Transaction-aware decorators for the the org.springframework.cache package.
|
||||
* Provides synchronization of put operations with Spring-managed transactions.
|
||||
*/
|
||||
package org.springframework.cache.transaction;
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -72,8 +72,8 @@ public class SpringBeanJobFactory extends AdaptableJobFactory implements Schedul
|
||||
@Override
|
||||
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
|
||||
Object job = super.createJobInstance(bundle);
|
||||
if (isEligibleForPropertyPopulation(job)) {
|
||||
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);
|
||||
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);
|
||||
if (isEligibleForPropertyPopulation(bw.getWrappedInstance())) {
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
if (this.schedulerContext != null) {
|
||||
pvs.addPropertyValues(this.schedulerContext);
|
||||
|
||||
+3
-3
@@ -358,12 +358,12 @@ public class FreeMarkerConfigurationFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* To be overridden by subclasses that want to register custom
|
||||
* To be overridden by subclasses that want to to register custom
|
||||
* TemplateLoader instances after this factory created its default
|
||||
* template loaders.
|
||||
* <p>Called by {@code createConfiguration()}. Note that specified
|
||||
* "postTemplateLoaders" will be registered <i>after</i> any loaders
|
||||
* registered by this callback; as a consequence, they are <i>not</i>
|
||||
* registered by this callback; as a consequence, they are are <i>not</i>
|
||||
* included in the given List.
|
||||
* @param templateLoaders the current List of TemplateLoader instances,
|
||||
* to be modified by a subclass
|
||||
@@ -395,7 +395,7 @@ public class FreeMarkerConfigurationFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* To be overridden by subclasses that want to perform custom
|
||||
* To be overridden by subclasses that want to to perform custom
|
||||
* post-processing of the Configuration object after this factory
|
||||
* performed its default initialization.
|
||||
* <p>Called by {@code createConfiguration()}.
|
||||
|
||||
+1
-1
@@ -340,7 +340,7 @@ public class VelocityEngineFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* To be implemented by subclasses that want to perform custom
|
||||
* To be implemented by subclasses that want to to perform custom
|
||||
* post-processing of the VelocityEngine after this FactoryBean
|
||||
* performed its default configuration (but before VelocityEngine.init).
|
||||
* <p>Called by {@code createVelocityEngine()}.
|
||||
|
||||
+1
@@ -24,6 +24,7 @@ import org.quartz.CronTrigger;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CronTriggerFactoryBeanTests {
|
||||
|
||||
+1
@@ -24,6 +24,7 @@ import org.quartz.SimpleTrigger;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class SimpleTriggerFactoryBeanTests {
|
||||
|
||||
@@ -37,7 +37,7 @@ public interface Cache {
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Return the underlying native cache provider.
|
||||
* Return the the underlying native cache provider.
|
||||
*/
|
||||
Object getNativeCache();
|
||||
|
||||
|
||||
+5
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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,16 +27,14 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* Enables Spring's annotation-driven cache management capability, similar to the
|
||||
* support found in Spring's {@code <cache:*>} XML namespace. To be used together
|
||||
* Enables Spring's annotation-driven cache management capability, similar to
|
||||
* the support found in Spring's {@code <cache:*>} XML namespace. To be used together
|
||||
* with @{@link org.springframework.context.annotation.Configuration Configuration}
|
||||
* classes as follows:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableCaching
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public MyService myService() {
|
||||
* // configure and return a class having @Cacheable methods
|
||||
@@ -54,15 +52,11 @@ import org.springframework.core.Ordered;
|
||||
*
|
||||
* <p>For reference, the example above can be compared to the following Spring XML
|
||||
* configuration:
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
* <beans>
|
||||
*
|
||||
* <cache:annotation-driven/>
|
||||
*
|
||||
* <bean id="myService" class="com.foo.MyService"/>
|
||||
*
|
||||
* <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
|
||||
* <property name="caches">
|
||||
* <set>
|
||||
@@ -72,10 +66,8 @@ import org.springframework.core.Ordered;
|
||||
* </set>
|
||||
* </property>
|
||||
* </bean>
|
||||
*
|
||||
* </beans>
|
||||
* }</pre>
|
||||
*
|
||||
* In both of the scenarios above, {@code @EnableCaching} and {@code
|
||||
* <cache:annotation-driven/>} are responsible for registering the necessary Spring
|
||||
* components that power annotation-driven cache management, such as the
|
||||
@@ -98,14 +90,12 @@ import org.springframework.core.Ordered;
|
||||
*
|
||||
* <p>For those that wish to establish a more direct relationship between
|
||||
* {@code @EnableCaching} and the exact cache manager bean to be used,
|
||||
* the {@link CachingConfigurer} callback interface may be implemented.
|
||||
* Notice the {@code @Override}-annotated methods below:
|
||||
*
|
||||
* the {@link CachingConfigurer} callback interface may be implemented - notice the
|
||||
* the {@code @Override}-annotated methods below:
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableCaching
|
||||
* public class AppConfig extends CachingConfigurerSupport {
|
||||
*
|
||||
* @Bean
|
||||
* public MyService myService() {
|
||||
* // configure and return a class having @Cacheable methods
|
||||
@@ -128,7 +118,6 @@ import org.springframework.core.Ordered;
|
||||
* return new MyKeyGenerator();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* This approach may be desirable simply because it is more explicit, or it may be
|
||||
* necessary in order to distinguish between two {@code CacheManager} beans present in the
|
||||
* same container.
|
||||
|
||||
Vendored
+1
-4
@@ -87,10 +87,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
if (!cachings.isEmpty()) {
|
||||
ops = lazyInit(ops);
|
||||
for (Caching caching : cachings) {
|
||||
Collection<CacheOperation> cachingOps = parseCachingAnnotation(ae, cachingConfig, caching);
|
||||
if (cachingOps != null) {
|
||||
ops.addAll(cachingOps);
|
||||
}
|
||||
ops.addAll(parseCachingAnnotation(ae, cachingConfig, caching));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {
|
||||
}
|
||||
else {
|
||||
if (this.caches == null) {
|
||||
readerCtx.error("No cache specified for " + element.getNodeName(), element);
|
||||
readerCtx.error("No cache specified specified for " + element.getNodeName(), element);
|
||||
}
|
||||
}
|
||||
builder.setCacheNames(localCaches);
|
||||
|
||||
+44
-104
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,6 @@ import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -31,8 +30,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.framework.AopProxyUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
@@ -40,10 +37,11 @@ import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.support.SimpleValueWrapper;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.expression.AnnotatedElementKey;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -79,26 +77,17 @@ import org.springframework.util.StringUtils;
|
||||
* @since 3.1
|
||||
*/
|
||||
public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
implements BeanFactoryAware, InitializingBean, SmartInitializingSingleton {
|
||||
|
||||
private static Class<?> javaUtilOptionalClass = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
javaUtilOptionalClass =
|
||||
ClassUtils.forName("java.util.Optional", CacheAspectSupport.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Java 8 not available - Optional references simply not supported then.
|
||||
}
|
||||
}
|
||||
implements InitializingBean, SmartInitializingSingleton, ApplicationContextAware {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
* Cache of CacheOperationMetadata, keyed by {@link CacheOperationCacheKey}.
|
||||
*/
|
||||
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache =
|
||||
new ConcurrentHashMap<CacheOperationCacheKey, CacheOperationMetadata>(1024);
|
||||
|
||||
private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
|
||||
private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
|
||||
|
||||
private CacheOperationSource cacheOperationSource;
|
||||
|
||||
@@ -106,7 +95,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
|
||||
private CacheResolver cacheResolver;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
@@ -175,26 +164,12 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
return this.cacheResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the containing {@link BeanFactory} for {@link CacheManager} and other
|
||||
* service lookups.
|
||||
* @since 4.3
|
||||
*/
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 4.3, in favor of {@link #setBeanFactory}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.beanFactory = applicationContext;
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.state(getCacheOperationSource() != null, "The 'cacheOperationSources' property is required: " +
|
||||
"If there are no cacheable methods, then don't use a cache aspect.");
|
||||
@@ -206,7 +181,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
if (getCacheResolver() == null) {
|
||||
// Lazily initialize cache resolver via default cache manager...
|
||||
try {
|
||||
setCacheManager(this.beanFactory.getBean(CacheManager.class));
|
||||
setCacheManager(this.applicationContext.getBean(CacheManager.class));
|
||||
}
|
||||
catch (NoUniqueBeanDefinitionException ex) {
|
||||
throw new IllegalStateException("No CacheResolver specified, and no unique bean of type " +
|
||||
@@ -299,7 +274,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
* Return a bean with the specified name and type. Used to resolve services that
|
||||
* are referenced by name in a {@link CacheOperation}.
|
||||
* @param beanName the name of the bean, as defined by the operation
|
||||
* @param expectedType type for the bean
|
||||
* @param expectedType type type for the bean
|
||||
* @return the bean matching that name
|
||||
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException if such bean does not exist
|
||||
* @see CacheOperation#keyGenerator
|
||||
@@ -307,7 +282,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
* @see CacheOperation#cacheResolver
|
||||
*/
|
||||
protected <T> T getBean(String beanName, Class<T> expectedType) {
|
||||
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.beanFactory, expectedType, beanName);
|
||||
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.applicationContext, expectedType, beanName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,12 +294,13 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
}
|
||||
|
||||
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
|
||||
// Check whether aspect is enabled (to cope with cases where the AJ is pulled in automatically)
|
||||
// check whether aspect is enabled
|
||||
// to cope with cases where the AJ is pulled in automatically
|
||||
if (this.initialized) {
|
||||
Class<?> targetClass = getTargetClass(target);
|
||||
Collection<CacheOperation> operations = getCacheOperationSource().getCacheOperations(method, targetClass);
|
||||
if (!CollectionUtils.isEmpty(operations)) {
|
||||
return execute(invoker, method, new CacheOperationContexts(operations, method, args, target, targetClass));
|
||||
return execute(invoker, new CacheOperationContexts(operations, method, args, target, targetClass));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,12 +329,12 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
return targetClass;
|
||||
}
|
||||
|
||||
private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
|
||||
private Object execute(final CacheOperationInvoker invoker, CacheOperationContexts contexts) {
|
||||
// Special handling of synchronized invocation
|
||||
if (contexts.isSynchronized()) {
|
||||
CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
|
||||
if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {
|
||||
Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
|
||||
if (isConditionPassing(context, ExpressionEvaluator.NO_RESULT)) {
|
||||
Object key = generateKey(context, ExpressionEvaluator.NO_RESULT);
|
||||
Cache cache = context.getCaches().iterator().next();
|
||||
try {
|
||||
return cache.get(key, new Callable<Object>() {
|
||||
@@ -382,8 +358,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
|
||||
|
||||
// Process any early evictions
|
||||
processCacheEvicts(contexts.get(CacheEvictOperation.class), true,
|
||||
CacheOperationExpressionEvaluator.NO_RESULT);
|
||||
processCacheEvicts(contexts.get(CacheEvictOperation.class), true, ExpressionEvaluator.NO_RESULT);
|
||||
|
||||
// Check if we have a cached item matching the conditions
|
||||
Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
|
||||
@@ -391,56 +366,42 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
// Collect puts from any @Cacheable miss, if no cached item is found
|
||||
List<CachePutRequest> cachePutRequests = new LinkedList<CachePutRequest>();
|
||||
if (cacheHit == null) {
|
||||
collectPutRequests(contexts.get(CacheableOperation.class),
|
||||
CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
|
||||
collectPutRequests(contexts.get(CacheableOperation.class), ExpressionEvaluator.NO_RESULT, cachePutRequests);
|
||||
}
|
||||
|
||||
Object cacheValue;
|
||||
Object returnValue;
|
||||
Cache.ValueWrapper result = null;
|
||||
|
||||
if (cacheHit != null && cachePutRequests.isEmpty() && !hasCachePut(contexts)) {
|
||||
// If there are no put requests, just use the cache hit
|
||||
cacheValue = cacheHit.get();
|
||||
if (method.getReturnType() == javaUtilOptionalClass &&
|
||||
(cacheValue == null || cacheValue.getClass() != javaUtilOptionalClass)) {
|
||||
returnValue = OptionalUnwrapper.wrap(cacheValue);
|
||||
}
|
||||
else {
|
||||
returnValue = cacheValue;
|
||||
}
|
||||
// If there are no put requests, just use the cache hit
|
||||
if (cachePutRequests.isEmpty() && !hasCachePut(contexts)) {
|
||||
result = cacheHit;
|
||||
}
|
||||
else {
|
||||
// Invoke the method if we don't have a cache hit
|
||||
returnValue = invokeOperation(invoker);
|
||||
if (returnValue != null && returnValue.getClass() == javaUtilOptionalClass) {
|
||||
cacheValue = OptionalUnwrapper.unwrap(returnValue);
|
||||
}
|
||||
else {
|
||||
cacheValue = returnValue;
|
||||
}
|
||||
|
||||
// Invoke the method if don't have a cache hit
|
||||
if (result == null) {
|
||||
result = new SimpleValueWrapper(invokeOperation(invoker));
|
||||
}
|
||||
|
||||
// Collect any explicit @CachePuts
|
||||
collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);
|
||||
collectPutRequests(contexts.get(CachePutOperation.class), result.get(), cachePutRequests);
|
||||
|
||||
// Process any collected put requests, either from @CachePut or a @Cacheable miss
|
||||
for (CachePutRequest cachePutRequest : cachePutRequests) {
|
||||
cachePutRequest.apply(cacheValue);
|
||||
cachePutRequest.apply(result.get());
|
||||
}
|
||||
|
||||
// Process any late evictions
|
||||
processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);
|
||||
processCacheEvicts(contexts.get(CacheEvictOperation.class), false, result.get());
|
||||
|
||||
return returnValue;
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private boolean hasCachePut(CacheOperationContexts contexts) {
|
||||
// Evaluate the conditions *without* the result object because we don't have it yet...
|
||||
// Evaluate the conditions *without* the result object because we don't have it yet.
|
||||
Collection<CacheOperationContext> cachePutContexts = contexts.get(CachePutOperation.class);
|
||||
Collection<CacheOperationContext> excluded = new ArrayList<CacheOperationContext>();
|
||||
for (CacheOperationContext context : cachePutContexts) {
|
||||
try {
|
||||
if (!context.isConditionPassing(CacheOperationExpressionEvaluator.RESULT_UNAVAILABLE)) {
|
||||
if (!context.isConditionPassing(ExpressionEvaluator.RESULT_UNAVAILABLE)) {
|
||||
excluded.add(context);
|
||||
}
|
||||
}
|
||||
@@ -492,7 +453,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
* or {@code null} if none is found
|
||||
*/
|
||||
private Cache.ValueWrapper findCachedItem(Collection<CacheOperationContext> contexts) {
|
||||
Object result = CacheOperationExpressionEvaluator.NO_RESULT;
|
||||
Object result = ExpressionEvaluator.NO_RESULT;
|
||||
for (CacheOperationContext context : contexts) {
|
||||
if (isConditionPassing(context, result)) {
|
||||
Object key = generateKey(context, result);
|
||||
@@ -590,7 +551,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
|
||||
private boolean determineSyncFlag(Method method) {
|
||||
List<CacheOperationContext> cacheOperationContexts = this.contexts.get(CacheableOperation.class);
|
||||
if (cacheOperationContexts == null) { // no @Cacheable operation at all
|
||||
if (cacheOperationContexts == null) { // No @Cacheable operation
|
||||
return false;
|
||||
}
|
||||
boolean syncEnabled = false;
|
||||
@@ -602,18 +563,18 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
}
|
||||
if (syncEnabled) {
|
||||
if (this.contexts.size() > 1) {
|
||||
throw new IllegalStateException("@Cacheable(sync=true) cannot be combined with other cache operations on '" + method + "'");
|
||||
throw new IllegalStateException("@Cacheable(sync = true) cannot be combined with other cache operations on '" + method + "'");
|
||||
}
|
||||
if (cacheOperationContexts.size() > 1) {
|
||||
throw new IllegalStateException("Only one @Cacheable(sync=true) entry is allowed on '" + method + "'");
|
||||
throw new IllegalStateException("Only one @Cacheable(sync = true) entry is allowed on '" + method + "'");
|
||||
}
|
||||
CacheOperationContext cacheOperationContext = cacheOperationContexts.iterator().next();
|
||||
CacheableOperation operation = (CacheableOperation) cacheOperationContext.getOperation();
|
||||
if (cacheOperationContext.getCaches().size() > 1) {
|
||||
throw new IllegalStateException("@Cacheable(sync=true) only allows a single cache on '" + operation + "'");
|
||||
throw new IllegalStateException("@Cacheable(sync = true) only allows a single cache on '" + operation + "'");
|
||||
}
|
||||
if (StringUtils.hasText(operation.getUnless())) {
|
||||
throw new IllegalStateException("@Cacheable(sync=true) does not support unless attribute on '" + operation + "'");
|
||||
throw new IllegalStateException("@Cacheable(sync = true) does not support unless attribute on '" + operation + "'");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -741,8 +702,9 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
}
|
||||
|
||||
private EvaluationContext createEvaluationContext(Object result) {
|
||||
return evaluator.createEvaluationContext(this.caches, this.metadata.method, this.args,
|
||||
this.target, this.metadata.targetClass, result, beanFactory);
|
||||
return evaluator.createEvaluationContext(
|
||||
this.caches, this.metadata.method, this.args, this.target, this.metadata.targetClass,
|
||||
result, applicationContext);
|
||||
}
|
||||
|
||||
protected Collection<? extends Cache> getCaches() {
|
||||
@@ -828,26 +790,4 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard dependency on Java 8.
|
||||
*/
|
||||
@UsesJava8
|
||||
private static class OptionalUnwrapper {
|
||||
|
||||
public static Object unwrap(Object optionalObject) {
|
||||
Optional<?> optional = (Optional<?>) optionalObject;
|
||||
if (!optional.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
Object result = optional.get();
|
||||
Assert.isTrue(!(result instanceof Optional), "Multi-level Optional usage not supported");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Object wrap(Object value) {
|
||||
return Optional.ofNullable(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vendored
-4
@@ -30,16 +30,12 @@ public class CacheEvictOperation extends CacheOperation {
|
||||
private final boolean beforeInvocation;
|
||||
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public CacheEvictOperation(CacheEvictOperation.Builder b) {
|
||||
super(b);
|
||||
this.cacheWide = b.cacheWide;
|
||||
this.beforeInvocation = b.beforeInvocation;
|
||||
}
|
||||
|
||||
|
||||
public boolean isCacheWide() {
|
||||
return this.cacheWide;
|
||||
}
|
||||
|
||||
+4
-3
@@ -49,9 +49,6 @@ public abstract class CacheOperation implements BasicOperation {
|
||||
private final String toString;
|
||||
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
protected CacheOperation(Builder b) {
|
||||
this.name = b.name;
|
||||
this.cacheNames = b.cacheNames;
|
||||
@@ -77,18 +74,22 @@ public abstract class CacheOperation implements BasicOperation {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
|
||||
public String getKeyGenerator() {
|
||||
return this.keyGenerator;
|
||||
}
|
||||
|
||||
|
||||
public String getCacheManager() {
|
||||
return this.cacheManager;
|
||||
}
|
||||
|
||||
|
||||
public String getCacheResolver() {
|
||||
return this.cacheResolver;
|
||||
}
|
||||
|
||||
|
||||
public String getCondition() {
|
||||
return this.condition;
|
||||
}
|
||||
|
||||
Vendored
+3
-4
@@ -21,8 +21,8 @@ package org.springframework.cache.interceptor;
|
||||
*
|
||||
* <p>Does not provide a way to transmit checked exceptions but
|
||||
* provide a special exception that should be used to wrap any
|
||||
* exception that was thrown by the underlying invocation.
|
||||
* Callers are expected to handle this issue type specifically.
|
||||
* exception that was thrown by the underlying invocation. Callers
|
||||
* are expected to handle this issue type specifically.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
@@ -38,9 +38,8 @@ public interface CacheOperationInvoker {
|
||||
*/
|
||||
Object invoke() throws ThrowableWrapper;
|
||||
|
||||
|
||||
/**
|
||||
* Wrap any exception thrown while invoking {@link #invoke()}.
|
||||
* Wrap any exception thrown while invoking {@link #invoke()}
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
class ThrowableWrapper extends RuntimeException {
|
||||
|
||||
-4
@@ -29,15 +29,11 @@ public class CachePutOperation extends CacheOperation {
|
||||
private final String unless;
|
||||
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public CachePutOperation(CachePutOperation.Builder b) {
|
||||
super(b);
|
||||
this.unless = b.unless;
|
||||
}
|
||||
|
||||
|
||||
public String getUnless() {
|
||||
return this.unless;
|
||||
}
|
||||
|
||||
+1
-8
@@ -28,19 +28,15 @@ public class CacheableOperation extends CacheOperation {
|
||||
|
||||
private final String unless;
|
||||
|
||||
private final boolean sync;
|
||||
private boolean sync;
|
||||
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public CacheableOperation(CacheableOperation.Builder b) {
|
||||
super(b);
|
||||
this.unless = b.unless;
|
||||
this.sync = b.sync;
|
||||
}
|
||||
|
||||
|
||||
public String getUnless() {
|
||||
return this.unless;
|
||||
}
|
||||
@@ -50,9 +46,6 @@ public class CacheableOperation extends CacheOperation {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public static class Builder extends CacheOperation.Builder {
|
||||
|
||||
private String unless;
|
||||
|
||||
+10
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,8 @@ import org.springframework.cache.Cache;
|
||||
import org.springframework.context.expression.AnnotatedElementKey;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.context.expression.CachedExpressionEvaluator;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
|
||||
@@ -43,7 +45,7 @@ import org.springframework.expression.Expression;
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
*/
|
||||
class CacheOperationExpressionEvaluator extends CachedExpressionEvaluator {
|
||||
class ExpressionEvaluator extends CachedExpressionEvaluator {
|
||||
|
||||
/**
|
||||
* Indicate that there is no result variable.
|
||||
@@ -60,6 +62,8 @@ class CacheOperationExpressionEvaluator extends CachedExpressionEvaluator {
|
||||
*/
|
||||
public static final String RESULT_VARIABLE = "result";
|
||||
|
||||
// shared param discoverer since it caches data internally
|
||||
private final ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
private final Map<ExpressionKey, Expression> keyCache = new ConcurrentHashMap<ExpressionKey, Expression>(64);
|
||||
|
||||
@@ -96,11 +100,11 @@ class CacheOperationExpressionEvaluator extends CachedExpressionEvaluator {
|
||||
Method method, Object[] args, Object target, Class<?> targetClass, Object result,
|
||||
BeanFactory beanFactory) {
|
||||
|
||||
CacheExpressionRootObject rootObject = new CacheExpressionRootObject(
|
||||
caches, method, args, target, targetClass);
|
||||
CacheExpressionRootObject rootObject = new CacheExpressionRootObject(caches,
|
||||
method, args, target, targetClass);
|
||||
Method targetMethod = getTargetMethod(targetClass, method);
|
||||
CacheEvaluationContext evaluationContext = new CacheEvaluationContext(
|
||||
rootObject, targetMethod, args, getParameterNameDiscoverer());
|
||||
CacheEvaluationContext evaluationContext = new CacheEvaluationContext(rootObject,
|
||||
targetMethod, args, this.paramNameDiscoverer);
|
||||
if (result == RESULT_UNAVAILABLE) {
|
||||
evaluationContext.addUnavailableVariable(RESULT_VARIABLE);
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Support classes for the org.springframework.cache package.
|
||||
* Support classes for the the org.springframework.cache package.
|
||||
* Provides abstract classes for cache managers and caches.
|
||||
*/
|
||||
package org.springframework.cache.support;
|
||||
|
||||
+2
-2
@@ -70,7 +70,7 @@ public class ContextSingletonBeanFactoryLocator extends SingletonBeanFactoryLoca
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance which uses the specified selector, as the name of the
|
||||
* Returns an instance which uses the the specified selector, as the name of the
|
||||
* definition file(s). In the case of a name with a Spring "classpath*:" prefix,
|
||||
* or with no prefix, which is treated the same, the current thread's context class
|
||||
* loader's {@code getResources} method will be called with this value to get
|
||||
@@ -112,7 +112,7 @@ public class ContextSingletonBeanFactoryLocator extends SingletonBeanFactoryLoca
|
||||
|
||||
|
||||
/**
|
||||
* Constructor which uses the specified name as the resource name
|
||||
* Constructor which uses the the specified name as the resource name
|
||||
* of the definition file(s).
|
||||
* @param resourceLocation the Spring resource location to use
|
||||
* (either a URL or a "classpath:" / "classpath*:" pseudo URL)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -39,8 +39,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
* public MyBean myBean() {
|
||||
* // instantiate and configure MyBean obj
|
||||
* return obj;
|
||||
* }
|
||||
* </pre>
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Bean Names</h3>
|
||||
*
|
||||
@@ -56,8 +55,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
* public MyBean myBean() {
|
||||
* // instantiate and configure MyBean obj
|
||||
* return obj;
|
||||
* }
|
||||
* </pre>
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Scope, DependsOn, Primary, and Lazy</h3>
|
||||
*
|
||||
@@ -72,8 +70,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
* public MyBean myBean() {
|
||||
* // instantiate and configure MyBean obj
|
||||
* return obj;
|
||||
* }
|
||||
* </pre>
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>{@code @Bean} Methods in {@code @Configuration} Classes</h3>
|
||||
*
|
||||
@@ -90,17 +87,14 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public FooService fooService() {
|
||||
* return new FooService(fooRepository());
|
||||
* }
|
||||
*
|
||||
* @Bean
|
||||
* public FooRepository fooRepository() {
|
||||
* return new JdbcFooRepository(dataSource());
|
||||
* }
|
||||
*
|
||||
* // ...
|
||||
* }</pre>
|
||||
*
|
||||
@@ -158,8 +152,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
* @Bean
|
||||
* public static PropertyPlaceholderConfigurer ppc() {
|
||||
* // instantiate, configure and return ppc ...
|
||||
* }
|
||||
* </pre>
|
||||
* }</pre>
|
||||
*
|
||||
* By marking this method as {@code static}, it can be invoked without causing instantiation of its
|
||||
* declaring {@code @Configuration} class, thus avoiding the above-mentioned lifecycle conflicts.
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
|
||||
* implementations.
|
||||
* <p>If given a plain {@code BeanDefinitionRegistry}, the default {@code ResourceLoader}
|
||||
* will be a {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver}.
|
||||
* <p>If the passed-in bean factory also implements {@link EnvironmentCapable} its
|
||||
* <p>If the the passed-in bean factory also implements {@link EnvironmentCapable} its
|
||||
* environment will be used by this reader. Otherwise, the reader will initialize and
|
||||
* use a {@link org.springframework.core.env.StandardEnvironment}. All
|
||||
* {@code ApplicationContext} implementations are {@code EnvironmentCapable}, while
|
||||
|
||||
+18
-51
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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,14 +27,12 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Indicates that a class declares one or more {@link Bean @Bean} methods and
|
||||
* may be processed by the Spring container to generate bean definitions and
|
||||
* service requests for those beans at runtime, for example:
|
||||
*
|
||||
* Indicates that a class declares one or more {@link Bean @Bean} methods and may be processed
|
||||
* by the Spring container to generate bean definitions and service requests for those
|
||||
* beans at runtime, for example:
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public MyBean myBean() {
|
||||
* // instantiate, configure and return bean ...
|
||||
@@ -42,28 +40,25 @@ import org.springframework.stereotype.Component;
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Bootstrapping {@code @Configuration} classes</h2>
|
||||
*
|
||||
* <h3>Via {@code AnnotationConfigApplicationContext}</h3>
|
||||
*
|
||||
* {@code @Configuration} classes are typically bootstrapped using either
|
||||
* {@link AnnotationConfigApplicationContext} or its web-capable variant,
|
||||
* {@link org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
||||
* AnnotationConfigWebApplicationContext}. A simple example with the former follows:
|
||||
*
|
||||
* AnnotationConfigWebApplicationContext}.
|
||||
* A simple example with the former follows:
|
||||
* <pre class="code">
|
||||
* AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
* AnnotationConfigApplicationContext ctx =
|
||||
* new AnnotationConfigApplicationContext();
|
||||
* ctx.register(AppConfig.class);
|
||||
* ctx.refresh();
|
||||
* MyBean myBean = ctx.getBean(MyBean.class);
|
||||
* // use myBean ...
|
||||
* </pre>
|
||||
* // use myBean ...</pre>
|
||||
*
|
||||
* See {@link AnnotationConfigApplicationContext} Javadoc for further details and see
|
||||
* {@link org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
||||
* AnnotationConfigWebApplicationContext} for {@code web.xml} configuration instructions.
|
||||
*
|
||||
* <h3>Via Spring {@code <beans>} XML</h3>
|
||||
*
|
||||
* <p>As an alternative to registering {@code @Configuration} classes directly against an
|
||||
* {@code AnnotationConfigApplicationContext}, {@code @Configuration} classes may be
|
||||
* declared as normal {@code <bean>} definitions within Spring XML files:
|
||||
@@ -79,7 +74,6 @@ import org.springframework.stereotype.Component;
|
||||
* post processors that facilitate handling {@code @Configuration} classes.
|
||||
*
|
||||
* <h3>Via component scanning</h3>
|
||||
*
|
||||
* <p>{@code @Configuration} is meta-annotated with {@link Component @Component}, therefore
|
||||
* {@code @Configuration} classes are candidates for component scanning (typically using
|
||||
* Spring XML's {@code <context:component-scan/>} element) and therefore may also take
|
||||
@@ -88,7 +82,6 @@ import org.springframework.stereotype.Component;
|
||||
* <p>{@code @Configuration} classes may not only be bootstrapped using
|
||||
* component scanning, but may also themselves <em>configure</em> component scanning using
|
||||
* the {@link ComponentScan @ComponentScan} annotation:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @ComponentScan("com.acme.app.services")
|
||||
@@ -96,20 +89,18 @@ import org.springframework.stereotype.Component;
|
||||
* // various @Bean definitions ...
|
||||
* }</pre>
|
||||
*
|
||||
* See the {@link ComponentScan @ComponentScan} javadoc for details.
|
||||
* See {@link ComponentScan @ComponentScan} Javadoc for details.
|
||||
*
|
||||
*
|
||||
* <h2>Working with externalized values</h2>
|
||||
*
|
||||
* <h3>Using the {@code Environment} API</h3>
|
||||
*
|
||||
* Externalized values may be looked up by injecting the Spring
|
||||
* {@link org.springframework.core.env.Environment} into a {@code @Configuration}
|
||||
* class using the {@code @Autowired} or the {@code @Inject} annotation:
|
||||
*
|
||||
* {@link org.springframework.core.env.Environment Environment} into a
|
||||
* {@code @Configuration} class using the {@code @Autowired} or the {@code @Inject}
|
||||
* annotation:
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Inject Environment env;
|
||||
*
|
||||
* @Bean
|
||||
@@ -124,12 +115,10 @@ import org.springframework.stereotype.Component;
|
||||
* source" objects, and {@code @Configuration} classes may contribute property sources to
|
||||
* the {@code Environment} object using
|
||||
* the {@link org.springframework.core.env.PropertySources @PropertySources} annotation:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @PropertySource("classpath:/com/acme/app.properties")
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Inject Environment env;
|
||||
*
|
||||
* @Bean
|
||||
@@ -142,15 +131,12 @@ import org.springframework.stereotype.Component;
|
||||
* and {@link PropertySource @PropertySource} Javadoc for further details.
|
||||
*
|
||||
* <h3>Using the {@code @Value} annotation</h3>
|
||||
*
|
||||
* Externalized values may be 'wired into' {@code @Configuration} classes using
|
||||
* the {@link Value @Value} annotation:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @PropertySource("classpath:/com/acme/app.properties")
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Value("${bean.name}") String beanName;
|
||||
*
|
||||
* @Bean
|
||||
@@ -169,18 +155,14 @@ import org.springframework.stereotype.Component;
|
||||
* {@code PropertySourcesPlaceholderConfigurer}.
|
||||
*
|
||||
* <h2>Composing {@code @Configuration} classes</h2>
|
||||
*
|
||||
* <h3>With the {@code @Import} annotation</h3>
|
||||
*
|
||||
* <p>{@code @Configuration} classes may be composed using the {@link Import @Import} annotation,
|
||||
* not unlike the way that {@code <import>} works in Spring XML. Because
|
||||
* {@code @Configuration} objects are managed as Spring beans within the container,
|
||||
* imported configurations may be injected using {@code @Autowired} or {@code @Inject}:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* public class DatabaseConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public DataSource dataSource() {
|
||||
* // instantiate, configure and return DataSource
|
||||
@@ -190,7 +172,6 @@ import org.springframework.stereotype.Component;
|
||||
* @Configuration
|
||||
* @Import(DatabaseConfig.class)
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Inject DatabaseConfig dataConfig;
|
||||
*
|
||||
* @Bean
|
||||
@@ -207,15 +188,13 @@ import org.springframework.stereotype.Component;
|
||||
* new AnnotationConfigApplicationContext(AppConfig.class);</pre>
|
||||
*
|
||||
* <h3>With the {@code @Profile} annotation</h3>
|
||||
*
|
||||
* {@code @Configuration} classes may be marked with the {@link Profile @Profile} annotation to
|
||||
* indicate they should be processed only if a given profile or profiles are <em>active</em>:
|
||||
*
|
||||
* indicate they should be processed only if a given profile or profiles are
|
||||
* <em>active</em>:
|
||||
* <pre class="code">
|
||||
* @Profile("embedded")
|
||||
* @Configuration
|
||||
* public class EmbeddedDatabaseConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public DataSource dataSource() {
|
||||
* // instantiate, configure and return embedded DataSource
|
||||
@@ -225,29 +204,25 @@ import org.springframework.stereotype.Component;
|
||||
* @Profile("production")
|
||||
* @Configuration
|
||||
* public class ProductionDatabaseConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public DataSource dataSource() {
|
||||
* // instantiate, configure and return production DataSource
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* See the {@link Profile @Profile} and {@link org.springframework.core.env.Environment}
|
||||
* javadocs for further details.
|
||||
* See {@link Profile @Profile} and {@link org.springframework.core.env.Environment Environment}
|
||||
* Javadoc for further details.
|
||||
*
|
||||
* <h3>With Spring XML using the {@code @ImportResource} annotation</h3>
|
||||
*
|
||||
* As mentioned above, {@code @Configuration} classes may be declared as regular Spring
|
||||
* {@code <bean>} definitions within Spring XML files. It is also possible to
|
||||
* import Spring XML configuration files into {@code @Configuration} classes using
|
||||
* the {@link ImportResource @ImportResource} annotation. Bean definitions imported from XML can be
|
||||
* injected using {@code @Autowired} or {@code @Inject}:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @ImportResource("classpath:/com/acme/database-config.xml")
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Inject DataSource dataSource; // from XML
|
||||
*
|
||||
* @Bean
|
||||
@@ -258,13 +233,10 @@ import org.springframework.stereotype.Component;
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>With nested {@code @Configuration} classes</h3>
|
||||
*
|
||||
* {@code @Configuration} classes may be nested within one another as follows:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Inject DataSource dataSource;
|
||||
*
|
||||
* @Bean
|
||||
@@ -292,7 +264,6 @@ import org.springframework.stereotype.Component;
|
||||
* enclosing {@code @Configuration} class.
|
||||
*
|
||||
* <h2>Configuring lazy initialization</h2>
|
||||
*
|
||||
* <p>By default, {@code @Bean} methods will be <em>eagerly instantiated</em> at container
|
||||
* bootstrap time. To avoid this, {@code @Configuration} may be used in conjunction with
|
||||
* the {@link Lazy @Lazy} annotation to indicate that all {@code @Bean} methods declared within
|
||||
@@ -300,11 +271,9 @@ import org.springframework.stereotype.Component;
|
||||
* individual {@code @Bean} methods as well.
|
||||
*
|
||||
* <h2>Testing support for {@code @Configuration} classes</h2>
|
||||
*
|
||||
* The Spring <em>TestContext framework</em> available in the {@code spring-test} module
|
||||
* provides the {@code @ContextConfiguration} annotation, which as of Spring 3.1 can
|
||||
* accept an array of {@code @Configuration} {@code Class} objects:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @RunWith(SpringJUnit4ClassRunner.class)
|
||||
* @ContextConfiguration(classes={AppConfig.class, DatabaseConfig.class})
|
||||
@@ -323,7 +292,6 @@ import org.springframework.stereotype.Component;
|
||||
* See TestContext framework reference documentation for details.
|
||||
*
|
||||
* <h2>Enabling built-in Spring features using {@code @Enable} annotations</h2>
|
||||
*
|
||||
* Spring features such as asynchronous method execution, scheduled task execution,
|
||||
* annotation driven transaction management, and even Spring MVC can be enabled and
|
||||
* configured from {@code @Configuration}
|
||||
@@ -336,7 +304,6 @@ import org.springframework.stereotype.Component;
|
||||
* for details.
|
||||
*
|
||||
* <h2>Constraints when authoring {@code @Configuration} classes</h2>
|
||||
*
|
||||
* <ul>
|
||||
* <li>@Configuration classes must be non-final
|
||||
* <li>@Configuration classes must be non-local (may not be declared within a method)
|
||||
|
||||
+2
-3
@@ -159,7 +159,7 @@ class ConfigurationClassEnhancer {
|
||||
* Conditional {@link Callback}.
|
||||
* @see ConditionalCallbackFilter
|
||||
*/
|
||||
private interface ConditionalCallback extends Callback {
|
||||
private static interface ConditionalCallback extends Callback {
|
||||
|
||||
boolean isMatch(Method candidateMethod);
|
||||
}
|
||||
@@ -343,8 +343,7 @@ class ConfigurationClassEnhancer {
|
||||
// The factory is calling the bean method in order to instantiate and register the bean
|
||||
// (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
|
||||
// create the bean instance.
|
||||
if (logger.isWarnEnabled() &&
|
||||
BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
|
||||
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
|
||||
logger.warn(String.format("@Bean method %s.%s is non-static and returns an object " +
|
||||
"assignable to Spring's BeanFactoryPostProcessor interface. This will " +
|
||||
"result in a failure to process annotations such as @Autowired, " +
|
||||
|
||||
+1
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -382,12 +382,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||
throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
|
||||
beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
|
||||
}
|
||||
else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
|
||||
logger.warn("Cannot enhance @Configuration bean definition '" + beanName +
|
||||
"' since its singleton instance has been created too early. The typical cause " +
|
||||
"is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
|
||||
"return type: Consider declaring such methods as 'static'.");
|
||||
}
|
||||
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,6 @@ import java.lang.annotation.Target;
|
||||
* @Configuration
|
||||
* @EnableAspectJAutoProxy
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public FooService fooService() {
|
||||
* return new FooService();
|
||||
@@ -48,14 +47,12 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* <pre class="code">
|
||||
* public class FooService {
|
||||
*
|
||||
* // various methods
|
||||
* }</pre>
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Aspect
|
||||
* public class MyAspect {
|
||||
*
|
||||
* @Before("execution(* FooService+.*(..))")
|
||||
* public void advice() {
|
||||
* // advise FooService methods as appropriate
|
||||
@@ -69,7 +66,6 @@ import java.lang.annotation.Target;
|
||||
* <p>Users can control the type of proxy that gets created for {@code FooService} using
|
||||
* the {@link #proxyTargetClass()} attribute. The following enables CGLIB-style 'subclass'
|
||||
* proxies as opposed to the default interface-based JDK proxy approach.
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableAspectJAutoProxy(proxyTargetClass=true)
|
||||
@@ -79,7 +75,6 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* <p>Note that {@code @Aspect} beans may be component-scanned like any other. Simply
|
||||
* mark the aspect with both {@code @Aspect} and {@code @Component}:
|
||||
*
|
||||
* <pre class="code">
|
||||
* package com.foo;
|
||||
*
|
||||
@@ -91,13 +86,11 @@ import java.lang.annotation.Target;
|
||||
* public class MyAspect { ... }</pre>
|
||||
*
|
||||
* Then use the @{@link ComponentScan} annotation to pick both up:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @ComponentScan("com.foo")
|
||||
* @EnableAspectJAutoProxy
|
||||
* public class AppConfig {
|
||||
*
|
||||
* // no explicit @Bean definitions required
|
||||
* }</pre>
|
||||
*
|
||||
|
||||
+4
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,28 +29,22 @@ import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
* Activates a Spring {@link LoadTimeWeaver} for this application context, available as
|
||||
* a bean with the name "loadTimeWeaver", similar to the {@code <context:load-time-weaver>}
|
||||
* element in Spring XML.
|
||||
*
|
||||
* <p>To be used on @{@link org.springframework.context.annotation.Configuration Configuration} classes;
|
||||
* To be used
|
||||
* on @{@link org.springframework.context.annotation.Configuration Configuration} classes;
|
||||
* the simplest possible example of which follows:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableLoadTimeWeaving
|
||||
* public class AppConfig {
|
||||
*
|
||||
* // application-specific @Bean definitions ...
|
||||
* }</pre>
|
||||
*
|
||||
* The example above is equivalent to the following Spring XML configuration:
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
* <beans>
|
||||
*
|
||||
* <context:load-time-weaver/>
|
||||
*
|
||||
* <!-- application-specific <bean> definitions -->
|
||||
*
|
||||
* </beans>
|
||||
* }</pre>
|
||||
*
|
||||
@@ -67,12 +61,10 @@ import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
* {@code @EnableLoadTimeWeaving} may also implement the {@link LoadTimeWeavingConfigurer}
|
||||
* interface and return a custom {@code LoadTimeWeaver} instance through the
|
||||
* {@code #getLoadTimeWeaver} method:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableLoadTimeWeaving
|
||||
* public class AppConfig implements LoadTimeWeavingConfigurer {
|
||||
*
|
||||
* @Override
|
||||
* public LoadTimeWeaver getLoadTimeWeaver() {
|
||||
* MyLoadTimeWeaver ltw = new MyLoadTimeWeaver();
|
||||
@@ -83,13 +75,10 @@ import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
* }</pre>
|
||||
*
|
||||
* <p>The example above can be compared to the following Spring XML configuration:
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
* <beans>
|
||||
*
|
||||
* <context:load-time-weaver weaverClass="com.acme.MyLoadTimeWeaver"/>
|
||||
*
|
||||
* </beans>
|
||||
* }</pre>
|
||||
*
|
||||
@@ -105,7 +94,6 @@ import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
* be registered through {@link LoadTimeWeaver#addTransformer}. AspectJ weaving will be
|
||||
* activated by default if a "META-INF/aop.xml" resource is present on the classpath.
|
||||
* Example:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableLoadTimeWeaving(aspectjWeaving=ENABLED)
|
||||
@@ -113,13 +101,10 @@ import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
* }</pre>
|
||||
*
|
||||
* <p>The example above can be compared to the following Spring XML configuration:
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
* <beans>
|
||||
*
|
||||
* <context:load-time-weaver aspectj-weaving="on"/>
|
||||
*
|
||||
* </beans>
|
||||
* }</pre>
|
||||
*
|
||||
@@ -146,8 +131,7 @@ public @interface EnableLoadTimeWeaving {
|
||||
*/
|
||||
AspectJWeaving aspectjWeaving() default AspectJWeaving.AUTODETECT;
|
||||
|
||||
|
||||
enum AspectJWeaving {
|
||||
public enum AspectJWeaving {
|
||||
|
||||
/**
|
||||
* Switches on Spring-based AspectJ load-time weaving.
|
||||
@@ -167,5 +151,4 @@ public @interface EnableLoadTimeWeaving {
|
||||
*/
|
||||
AUTODETECT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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,12 +75,12 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade
|
||||
LoadTimeWeaver loadTimeWeaver = null;
|
||||
|
||||
if (this.ltwConfigurer != null) {
|
||||
// The user has provided a custom LoadTimeWeaver instance
|
||||
loadTimeWeaver = this.ltwConfigurer.getLoadTimeWeaver();
|
||||
// the user has provided a custom LTW instance
|
||||
loadTimeWeaver = ltwConfigurer.getLoadTimeWeaver();
|
||||
}
|
||||
|
||||
if (loadTimeWeaver == null) {
|
||||
// No custom LoadTimeWeaver provided -> fall back to the default
|
||||
// no custom LTW provided -> fall back to the default
|
||||
loadTimeWeaver = new DefaultContextLoadTimeWeaver(this.beanClassLoader);
|
||||
}
|
||||
|
||||
|
||||
+1
-6
@@ -32,7 +32,6 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* conjunction with @{@link Configuration} classes.
|
||||
*
|
||||
* <h3>Example usage</h3>
|
||||
*
|
||||
* <p>Given a file {@code app.properties} containing the key/value pair
|
||||
* {@code testbean.name=myTestBean}, the following {@code @Configuration} class
|
||||
* uses {@code @PropertySource} to contribute {@code app.properties} to the
|
||||
@@ -59,7 +58,6 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* the configuration above, a call to {@code testBean.getName()} will return "myTestBean".
|
||||
*
|
||||
* <h3>Resolving ${...} placeholders in {@code <bean>} and {@code @Value} annotations</h3>
|
||||
*
|
||||
* In order to resolve ${...} placeholders in {@code <bean>} definitions or {@code @Value}
|
||||
* annotations using properties from a {@code PropertySource}, one must register
|
||||
* a {@code PropertySourcesPlaceholderConfigurer}. This happens automatically when using
|
||||
@@ -70,11 +68,9 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* for details and examples.
|
||||
*
|
||||
* <h3>Resolving ${...} placeholders within {@code @PropertySource} resource locations</h3>
|
||||
*
|
||||
* Any ${...} placeholders present in a {@code @PropertySource} {@linkplain #value()
|
||||
* resource location} will be resolved against the set of property sources already
|
||||
* registered against the environment. For example:
|
||||
*
|
||||
* registered against the environment. For example:
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
|
||||
@@ -98,7 +94,6 @@ import org.springframework.core.io.support.PropertySourceFactory;
|
||||
* IllegalArgumentException} will be thrown.
|
||||
*
|
||||
* <h3>A note on property overriding with @PropertySource</h3>
|
||||
*
|
||||
* In cases where a given property key exists in more than one {@code .properties}
|
||||
* file, the last {@code @PropertySource} annotation processed will 'win' and override.
|
||||
*
|
||||
|
||||
+8
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,8 @@ import org.springframework.context.expression.AnnotatedElementKey;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.context.expression.CachedExpressionEvaluator;
|
||||
import org.springframework.context.expression.MethodBasedEvaluationContext;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
|
||||
@@ -40,11 +42,13 @@ import org.springframework.expression.Expression;
|
||||
*/
|
||||
class EventExpressionEvaluator extends CachedExpressionEvaluator {
|
||||
|
||||
// shared param discoverer since it caches data internally
|
||||
private final ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
private final Map<ExpressionKey, Expression> conditionCache = new ConcurrentHashMap<ExpressionKey, Expression>(64);
|
||||
|
||||
private final Map<AnnotatedElementKey, Method> targetMethodCache = new ConcurrentHashMap<AnnotatedElementKey, Method>(64);
|
||||
|
||||
|
||||
/**
|
||||
* Create the suitable {@link EvaluationContext} for the specified event handling
|
||||
* on the specified method.
|
||||
@@ -54,8 +58,8 @@ class EventExpressionEvaluator extends CachedExpressionEvaluator {
|
||||
|
||||
Method targetMethod = getTargetMethod(targetClass, method);
|
||||
EventExpressionRootObject root = new EventExpressionRootObject(event, args);
|
||||
MethodBasedEvaluationContext evaluationContext = new MethodBasedEvaluationContext(
|
||||
root, targetMethod, args, getParameterNameDiscoverer());
|
||||
MethodBasedEvaluationContext evaluationContext =
|
||||
new MethodBasedEvaluationContext(root, targetMethod, args, this.paramNameDiscoverer);
|
||||
if (beanFactory != null) {
|
||||
evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
|
||||
}
|
||||
|
||||
+1
-13
@@ -18,8 +18,6 @@ package org.springframework.context.expression;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -37,14 +35,12 @@ public abstract class CachedExpressionEvaluator {
|
||||
|
||||
private final SpelExpressionParser parser;
|
||||
|
||||
private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance with the specified {@link SpelExpressionParser}.
|
||||
*/
|
||||
protected CachedExpressionEvaluator(SpelExpressionParser parser) {
|
||||
Assert.notNull(parser, "SpelExpressionParser must not be null");
|
||||
Assert.notNull(parser, "Parser must not be null");
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@@ -63,14 +59,6 @@ public abstract class CachedExpressionEvaluator {
|
||||
return this.parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a shared parameter name discoverer which caches data internally.
|
||||
* @since 4.3
|
||||
*/
|
||||
protected ParameterNameDiscoverer getParameterNameDiscoverer() {
|
||||
return this.parameterNameDiscoverer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the {@link Expression} for the specified SpEL value
|
||||
|
||||
-20
@@ -78,7 +78,6 @@ import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* Abstract implementation of the {@link org.springframework.context.ApplicationContext}
|
||||
@@ -679,13 +678,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
*/
|
||||
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
|
||||
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
|
||||
|
||||
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
|
||||
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
|
||||
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
|
||||
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
|
||||
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -833,18 +825,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
|
||||
}
|
||||
|
||||
// Register a default embedded value resolver if no bean post-processor
|
||||
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
|
||||
// at this point, primarily for resolution in annotation attribute values.
|
||||
if (!beanFactory.hasEmbeddedValueResolver()) {
|
||||
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
|
||||
@Override
|
||||
public String resolveStringValue(String strVal) {
|
||||
return getEnvironment().resolvePlaceholders(strVal);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
|
||||
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
|
||||
for (String weaverAwareName : weaverAwareNames) {
|
||||
|
||||
+1
-1
@@ -292,7 +292,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
||||
* <p>The default implementation checks for the {@link Phased} interface.
|
||||
* Can be overridden to apply other/further policies.
|
||||
* @param bean the bean to introspect
|
||||
* @return the phase an integer value. The suggested default is 0.
|
||||
* @return the phase an an integer value. The suggested default is 0.
|
||||
* @see Phased
|
||||
* @see SmartLifecycle
|
||||
*/
|
||||
|
||||
+7
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -344,23 +344,17 @@ class PostProcessorRegistrationDelegate {
|
||||
|
||||
|
||||
/**
|
||||
* {@code BeanPostProcessor} that detects beans which implement the {@code ApplicationListener}
|
||||
* interface. This catches beans that can't reliably be detected by {@code getBeanNamesForType}
|
||||
* and related operations which only work against top-level beans.
|
||||
*
|
||||
* <p>With standard Java serialization, this post-processor won't get serialized as part of
|
||||
* {@code DisposableBeanAdapter} to begin with. However, with alternative serialization
|
||||
* mechanisms, {@code DisposableBeanAdapter.writeReplace} might not get used at all, so we
|
||||
* defensively mark this post-processor's field state as {@code transient}.
|
||||
* BeanPostProcessor that detects beans which implement the ApplicationListener interface.
|
||||
* This catches beans that can't reliably be detected by getBeanNamesForType.
|
||||
*/
|
||||
private static class ApplicationListenerDetector
|
||||
implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);
|
||||
|
||||
private transient final AbstractApplicationContext applicationContext;
|
||||
private final AbstractApplicationContext applicationContext;
|
||||
|
||||
private transient final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>(256);
|
||||
private final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>(256);
|
||||
|
||||
public ApplicationListenerDetector(AbstractApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
@@ -368,7 +362,7 @@ class PostProcessorRegistrationDelegate {
|
||||
|
||||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
if (this.applicationContext != null && beanDefinition.isSingleton()) {
|
||||
if (beanDefinition.isSingleton()) {
|
||||
this.singletonNames.put(beanName, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
@@ -380,7 +374,7 @@ class PostProcessorRegistrationDelegate {
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
if (this.applicationContext != null && bean instanceof ApplicationListener) {
|
||||
if (bean instanceof ApplicationListener) {
|
||||
// potentially not detected as a listener by getBeanNamesForType retrieval
|
||||
Boolean flag = this.singletonNames.get(beanName);
|
||||
if (Boolean.TRUE.equals(flag)) {
|
||||
|
||||
+3
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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,7 +18,6 @@ package org.springframework.format.datetime.standard;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.format.Formatter;
|
||||
@@ -27,29 +26,18 @@ import org.springframework.lang.UsesJava8;
|
||||
/**
|
||||
* {@link Formatter} implementation for a JSR-310 {@link java.time.Instant},
|
||||
* following JSR-310's parsing rules for an Instant (that is, not using a
|
||||
* configurable {@link java.time.format.DateTimeFormatter}): accepting the
|
||||
* default {@code ISO_INSTANT} format as well as {@code RFC_1123_DATE_TIME}
|
||||
* (which is commonly used for HTTP date header values), as of Spring 4.3.
|
||||
* configurable {@link java.time.format.DateTimeFormatter}).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0
|
||||
* @see java.time.Instant#parse
|
||||
* @see java.time.format.DateTimeFormatter#ISO_INSTANT
|
||||
* @see java.time.format.DateTimeFormatter#RFC_1123_DATE_TIME
|
||||
*/
|
||||
@UsesJava8
|
||||
public class InstantFormatter implements Formatter<Instant> {
|
||||
|
||||
@Override
|
||||
public Instant parse(String text, Locale locale) throws ParseException {
|
||||
if (text.length() > 0 && Character.isDigit(text.charAt(0))) {
|
||||
// assuming UTC instant a la "2007-12-03T10:15:30.00Z"
|
||||
return Instant.parse(text);
|
||||
}
|
||||
else {
|
||||
// assuming RFC-1123 value a la "Tue, 3 Jun 2008 11:05:30 GMT"
|
||||
return Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(text));
|
||||
}
|
||||
return Instant.parse(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,8 +22,6 @@ import java.lang.reflect.Method;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.DecoratingClassLoader;
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -99,14 +97,15 @@ public class ReflectiveLoadTimeWeaver implements LoadTimeWeaver {
|
||||
Assert.notNull(classLoader, "ClassLoader must not be null");
|
||||
this.classLoader = classLoader;
|
||||
this.addTransformerMethod = ClassUtils.getMethodIfAvailable(
|
||||
this.classLoader.getClass(), ADD_TRANSFORMER_METHOD_NAME, ClassFileTransformer.class);
|
||||
this.classLoader.getClass(), ADD_TRANSFORMER_METHOD_NAME,
|
||||
new Class<?>[] {ClassFileTransformer.class});
|
||||
if (this.addTransformerMethod == null) {
|
||||
throw new IllegalStateException(
|
||||
"ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide an " +
|
||||
"'addTransformer(ClassFileTransformer)' method.");
|
||||
}
|
||||
this.getThrowawayClassLoaderMethod = ClassUtils.getMethodIfAvailable(
|
||||
this.classLoader.getClass(), GET_THROWAWAY_CLASS_LOADER_METHOD_NAME);
|
||||
this.classLoader.getClass(), GET_THROWAWAY_CLASS_LOADER_METHOD_NAME, new Class<?>[0]);
|
||||
// getThrowawayClassLoader method is optional
|
||||
if (this.getThrowawayClassLoaderMethod == null) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
@@ -131,10 +130,7 @@ public class ReflectiveLoadTimeWeaver implements LoadTimeWeaver {
|
||||
@Override
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
if (this.getThrowawayClassLoaderMethod != null) {
|
||||
ClassLoader target = (ClassLoader)
|
||||
ReflectionUtils.invokeMethod(this.getThrowawayClassLoaderMethod, this.classLoader);
|
||||
return (target instanceof DecoratingClassLoader ? target :
|
||||
new OverridingClassLoader(this.classLoader, target));
|
||||
return (ClassLoader) ReflectionUtils.invokeMethod(this.getThrowawayClassLoaderMethod, this.classLoader);
|
||||
}
|
||||
else {
|
||||
return new SimpleThrowawayClassLoader(this.classLoader);
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2013 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.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -110,7 +109,7 @@ public class GlassFishLoadTimeWeaver implements LoadTimeWeaver {
|
||||
@Override
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
return new OverridingClassLoader(this.classLoader, (ClassLoader) this.copyMethod.invoke(this.classLoader));
|
||||
return (ClassLoader) this.copyMethod.invoke(this.classLoader);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("GlassFish copy method threw exception", ex.getCause());
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2013 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.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -104,7 +103,7 @@ public class TomcatLoadTimeWeaver implements LoadTimeWeaver {
|
||||
@Override
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
return new OverridingClassLoader(this.classLoader, (ClassLoader) this.copyMethod.invoke(this.classLoader));
|
||||
return (ClassLoader) this.copyMethod.invoke(this.classLoader);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("Tomcat copy method threw exception", ex.getCause());
|
||||
|
||||
+2
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2012 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,7 +18,6 @@ package org.springframework.instrument.classloading.weblogic;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -71,8 +70,6 @@ public class WebLogicLoadTimeWeaver implements LoadTimeWeaver {
|
||||
|
||||
@Override
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
return new OverridingClassLoader(this.classLoader.getClassLoader(),
|
||||
this.classLoader.getThrowawayClassLoader());
|
||||
return this.classLoader.getThrowawayClassLoader();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+18
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,57 +29,47 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Reflective wrapper around a WebSphere 7+ class loader. Used to
|
||||
* Reflective wrapper around a WebSphere 7 class loader. Used to
|
||||
* encapsulate the classloader-specific methods (discovered and
|
||||
* called through reflection) from the load-time weaver.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
*/
|
||||
class WebSphereClassLoaderAdapter {
|
||||
|
||||
private static final String COMPOUND_CLASS_LOADER_NAME = "com.ibm.ws.classloader.CompoundClassLoader";
|
||||
|
||||
private static final String CLASS_PRE_PROCESSOR_NAME = "com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin";
|
||||
|
||||
private static final String PLUGINS_FIELD = "preDefinePlugins";
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private Class<?> wsPreProcessorClass;
|
||||
|
||||
private Method addPreDefinePlugin;
|
||||
|
||||
private Constructor<? extends ClassLoader> cloneConstructor;
|
||||
|
||||
private Field transformerList;
|
||||
|
||||
|
||||
public WebSphereClassLoaderAdapter(ClassLoader classLoader) {
|
||||
Class<?> wsCompoundClassLoaderClass;
|
||||
Class<?> wsCompoundClassLoaderClass = null;
|
||||
try {
|
||||
wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME);
|
||||
this.cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass);
|
||||
this.cloneConstructor.setAccessible(true);
|
||||
cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass);
|
||||
cloneConstructor.setAccessible(true);
|
||||
|
||||
this.wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME);
|
||||
this.addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", this.wsPreProcessorClass);
|
||||
this.transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD);
|
||||
this.transformerList.setAccessible(true);
|
||||
wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME);
|
||||
addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", wsPreProcessorClass);
|
||||
transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD);
|
||||
transformerList.setAccessible(true);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize WebSphere LoadTimeWeaver because WebSphere API classes are not available", ex);
|
||||
}
|
||||
|
||||
if (!wsCompoundClassLoaderClass.isInstance(classLoader)) {
|
||||
throw new IllegalArgumentException("ClassLoader must be instance of [" + COMPOUND_CLASS_LOADER_NAME + "]");
|
||||
"Could not initialize WebSphere LoadTimeWeaver because WebSphere 7 API classes are not available",
|
||||
ex);
|
||||
}
|
||||
Assert.isInstanceOf(wsCompoundClassLoaderClass, classLoader,
|
||||
"ClassLoader must be instance of [" + COMPOUND_CLASS_LOADER_NAME + "]");
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
@@ -89,8 +79,9 @@ class WebSphereClassLoaderAdapter {
|
||||
try {
|
||||
InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer);
|
||||
Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(),
|
||||
new Class<?>[] {this.wsPreProcessorClass}, adapter);
|
||||
new Class<?>[] { this.wsPreProcessorClass }, adapter);
|
||||
this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance);
|
||||
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause());
|
||||
@@ -102,9 +93,9 @@ class WebSphereClassLoaderAdapter {
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
ClassLoader loader = this.cloneConstructor.newInstance(getClassLoader());
|
||||
// Clear out the transformers (copied as well)
|
||||
List<?> list = (List<?>) this.transformerList.get(loader);
|
||||
ClassLoader loader = cloneConstructor.newInstance(getClassLoader());
|
||||
// clear out the transformers (copied as well)
|
||||
List<?> list = (List<?>) transformerList.get(loader);
|
||||
list.clear();
|
||||
return loader;
|
||||
}
|
||||
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2012 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,7 +18,6 @@ package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -68,8 +67,7 @@ public class WebSphereLoadTimeWeaver implements LoadTimeWeaver {
|
||||
|
||||
@Override
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
return new OverridingClassLoader(this.classLoader.getClassLoader(),
|
||||
this.classLoader.getThrowawayClassLoader());
|
||||
return this.classLoader.getThrowawayClassLoader();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -570,7 +570,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
* should be exposed to the {@code MBeanServer}. Specifically, if the
|
||||
* supplied {@code mapValue} is the name of a bean that is configured
|
||||
* for lazy initialization, then a proxy to the resource is registered with
|
||||
* the {@code MBeanServer} so that the lazy load behavior is
|
||||
* the {@code MBeanServer} so that the the lazy load behavior is
|
||||
* honored. If the bean is already an MBean then it will be registered
|
||||
* directly with the {@code MBeanServer} without any intervention. For
|
||||
* all other beans or bean names, the resource itself is registered with
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* An implementation of the {@code ObjectNamingStrategy} interface that
|
||||
* creates a name based on the identity of a given instance.
|
||||
* creates a name based on the the identity of a given instance.
|
||||
*
|
||||
* <p>The resulting {@code ObjectName} will be in the form
|
||||
* <i>package</i>:class=<i>class name</i>,hashCode=<i>identity hash (in hex)</i>
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ public class KeyNamingStrategy implements ObjectNamingStrategy, InitializingBean
|
||||
|
||||
/**
|
||||
* Stores the result of merging the {@code mappings} {@code Properties}
|
||||
* with the properties stored in the resources defined by {@code mappingLocations}.
|
||||
* with the the properties stored in the resources defined by {@code mappingLocations}.
|
||||
*/
|
||||
private Properties mergedMappings;
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ public class JndiObjectFactoryBean extends JndiObjectLocator
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup variant that returns the specified "defaultObject"
|
||||
* Lookup variant that that returns the specified "defaultObject"
|
||||
* (if any) in case of lookup failure.
|
||||
* @return the located object, or the "defaultObject" as fallback
|
||||
* @throws NamingException in case of lookup failure without fallback
|
||||
|
||||
+4
-9
@@ -64,7 +64,8 @@ import org.springframework.core.Ordered;
|
||||
* {@code void} return type cannot transmit any exception back to the caller. By default,
|
||||
* such uncaught exceptions are only logged.
|
||||
*
|
||||
* <p>To customize all this, implement {@link AsyncConfigurer} and provide:
|
||||
* <p>To customize all this, implement {@link AsyncConfigurer} and
|
||||
* provide:
|
||||
* <ul>
|
||||
* <li>your own {@link java.util.concurrent.Executor Executor} through the
|
||||
* {@link AsyncConfigurer#getAsyncExecutor getAsyncExecutor()} method, and</li>
|
||||
@@ -113,19 +114,13 @@ import org.springframework.core.Ordered;
|
||||
*
|
||||
* <p>For reference, the example above can be compared to the following Spring XML
|
||||
* configuration:
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
* <beans>
|
||||
*
|
||||
* <task:annotation-driven executor="myExecutor" exception-handler="exceptionHandler"/>
|
||||
*
|
||||
* <task:executor id="myExecutor" pool-size="7-42" queue-capacity="11"/>
|
||||
*
|
||||
* <bean id="asyncBean" class="com.foo.MyAsyncBean"/>
|
||||
*
|
||||
* <bean id="exceptionHandler" class="com.foo.MyAsyncUncaughtExceptionHandler"/>
|
||||
*
|
||||
* </beans>
|
||||
* }</pre>
|
||||
*
|
||||
@@ -153,8 +148,8 @@ public @interface EnableAsync {
|
||||
/**
|
||||
* Indicate the 'async' annotation type to be detected at either class
|
||||
* or method level.
|
||||
* <p>By default, both Spring's @{@link Async} annotation and the EJB 3.1
|
||||
* {@code @javax.ejb.Asynchronous} annotation will be detected.
|
||||
* <p>By default, both Spring's @{@link Async} annotation and the EJB
|
||||
* 3.1 {@code @javax.ejb.Asynchronous} annotation will be detected.
|
||||
* <p>This attribute exists so that developers can provide their own
|
||||
* custom annotation type to indicate that a method (or all methods of
|
||||
* a given class) should be invoked asynchronously.
|
||||
|
||||
+2
-11
@@ -163,25 +163,16 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
*
|
||||
* <p>For reference, the example above can be compared to the following Spring XML
|
||||
* configuration:
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@code
|
||||
* <beans>
|
||||
*
|
||||
* <task:annotation-driven scheduler="taskScheduler"/>
|
||||
*
|
||||
* <task:scheduler id="taskScheduler" pool-size="42"/>
|
||||
*
|
||||
* <task:scheduled-tasks scheduler="taskScheduler">
|
||||
* <task:scheduled ref="myTask" method="work" fixed-rate="1000"/>
|
||||
* </task:scheduled-tasks>
|
||||
*
|
||||
* <task:scheduled ref="myTask" method="work" fixed-rate="1000"/>
|
||||
* <bean id="myTask" class="com.foo.MyTask"/>
|
||||
*
|
||||
* </beans>
|
||||
* }</pre>
|
||||
*
|
||||
* The examples are equivalent save that in XML a <em>fixed-rate</em> period is used
|
||||
* the examples are equivalent save that in XML a <em>fixed-rate</em> period is used
|
||||
* instead of a custom <em>{@code Trigger}</em> implementation; this is because the
|
||||
* {@code task:} namespace {@code scheduled} cannot easily expose such support. This is
|
||||
* but one demonstration how the code-based approach allows for maximum configurability
|
||||
|
||||
+4
-5
@@ -24,13 +24,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* An annotation that marks a method to be scheduled. Exactly one of
|
||||
* the {@link #cron()}, {@link #fixedDelay()}, or {@link #fixedRate()}
|
||||
* Annotation that marks a method to be scheduled. Exactly one of the
|
||||
* {@link #cron()}, {@link #fixedDelay()}, or {@link #fixedRate()}
|
||||
* attributes must be specified.
|
||||
*
|
||||
* <p>The annotated method must expect no arguments. It will typically have
|
||||
* a {@code void} return type; if not, the returned value will be ignored
|
||||
* when called through the scheduler.
|
||||
* <p>The annotated method must expect no arguments and have a
|
||||
* {@code void} return type.
|
||||
*
|
||||
* <p>Processing of {@code @Scheduled} annotations is performed by
|
||||
* registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be
|
||||
|
||||
+10
-40
@@ -17,9 +17,7 @@
|
||||
package org.springframework.scheduling.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
@@ -37,7 +35,7 @@ import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@@ -50,7 +48,6 @@ import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.config.CronTask;
|
||||
import org.springframework.scheduling.config.IntervalTask;
|
||||
import org.springframework.scheduling.config.ScheduledTask;
|
||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
import org.springframework.scheduling.support.CronTrigger;
|
||||
import org.springframework.scheduling.support.ScheduledMethodRunnable;
|
||||
@@ -84,8 +81,8 @@ import org.springframework.util.StringValueResolver;
|
||||
* @see org.springframework.scheduling.config.ScheduledTaskRegistrar
|
||||
* @see AsyncAnnotationBeanPostProcessor
|
||||
*/
|
||||
public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBeanPostProcessor,
|
||||
Ordered, EmbeddedValueResolverAware, BeanFactoryAware, ApplicationContextAware,
|
||||
public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered,
|
||||
EmbeddedValueResolverAware, BeanFactoryAware, ApplicationContextAware,
|
||||
SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean {
|
||||
|
||||
/**
|
||||
@@ -112,9 +109,6 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
private final Set<Class<?>> nonAnnotatedClasses =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<Class<?>, Boolean>(64));
|
||||
|
||||
private final Map<Object, Set<ScheduledTask>> scheduledTasks =
|
||||
new ConcurrentHashMap<Object, Set<ScheduledTask>>(16);
|
||||
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
@@ -293,6 +287,8 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
|
||||
protected void processScheduled(Scheduled scheduled, Method method, Object bean) {
|
||||
try {
|
||||
Assert.isTrue(void.class == method.getReturnType(),
|
||||
"Only void-returning methods may be annotated with @Scheduled");
|
||||
Assert.isTrue(method.getParameterTypes().length == 0,
|
||||
"Only no-arg methods may be annotated with @Scheduled");
|
||||
|
||||
@@ -302,9 +298,6 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
String errorMessage =
|
||||
"Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required";
|
||||
|
||||
Set<ScheduledTask> tasks =
|
||||
new LinkedHashSet<ScheduledTask>(4);
|
||||
|
||||
// Determine initial delay
|
||||
long initialDelay = scheduled.initialDelay();
|
||||
String initialDelayString = scheduled.initialDelayString();
|
||||
@@ -339,7 +332,7 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
else {
|
||||
timeZone = TimeZone.getDefault();
|
||||
}
|
||||
tasks.add(this.registrar.scheduleCronTask(new CronTask(runnable, new CronTrigger(cron, timeZone))));
|
||||
this.registrar.addCronTask(new CronTask(runnable, new CronTrigger(cron, timeZone)));
|
||||
}
|
||||
|
||||
// At this point we don't need to differentiate between initial delay set or not anymore
|
||||
@@ -352,7 +345,7 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
if (fixedDelay >= 0) {
|
||||
Assert.isTrue(!processedSchedule, errorMessage);
|
||||
processedSchedule = true;
|
||||
tasks.add(this.registrar.scheduleFixedDelayTask(new IntervalTask(runnable, fixedDelay, initialDelay)));
|
||||
this.registrar.addFixedDelayTask(new IntervalTask(runnable, fixedDelay, initialDelay));
|
||||
}
|
||||
String fixedDelayString = scheduled.fixedDelayString();
|
||||
if (StringUtils.hasText(fixedDelayString)) {
|
||||
@@ -368,7 +361,7 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid fixedDelayString value \"" + fixedDelayString + "\" - cannot parse into integer");
|
||||
}
|
||||
tasks.add(this.registrar.scheduleFixedDelayTask(new IntervalTask(runnable, fixedDelay, initialDelay)));
|
||||
this.registrar.addFixedDelayTask(new IntervalTask(runnable, fixedDelay, initialDelay));
|
||||
}
|
||||
|
||||
// Check fixed rate
|
||||
@@ -376,7 +369,7 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
if (fixedRate >= 0) {
|
||||
Assert.isTrue(!processedSchedule, errorMessage);
|
||||
processedSchedule = true;
|
||||
tasks.add(this.registrar.scheduleFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay)));
|
||||
this.registrar.addFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay));
|
||||
}
|
||||
String fixedRateString = scheduled.fixedRateString();
|
||||
if (StringUtils.hasText(fixedRateString)) {
|
||||
@@ -392,12 +385,11 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid fixedRateString value \"" + fixedRateString + "\" - cannot parse into integer");
|
||||
}
|
||||
tasks.add(this.registrar.scheduleFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay)));
|
||||
this.registrar.addFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay));
|
||||
}
|
||||
|
||||
// Check whether we had any attribute set
|
||||
Assert.isTrue(processedSchedule, errorMessage);
|
||||
this.scheduledTasks.put(bean, tasks);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new IllegalStateException(
|
||||
@@ -406,30 +398,8 @@ public class ScheduledAnnotationBeanPostProcessor implements DestructionAwareBea
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postProcessBeforeDestruction(Object bean, String beanName) {
|
||||
Set<ScheduledTask> tasks = this.scheduledTasks.remove(bean);
|
||||
if (tasks != null) {
|
||||
for (ScheduledTask task : tasks) {
|
||||
task.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresDestruction(Object bean) {
|
||||
return this.scheduledTasks.containsKey(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
Collection<Set<ScheduledTask>> allTasks = this.scheduledTasks.values();
|
||||
for (Set<ScheduledTask> tasks : allTasks) {
|
||||
for (ScheduledTask task : tasks) {
|
||||
task.cancel();
|
||||
}
|
||||
}
|
||||
this.scheduledTasks.clear();
|
||||
this.registrar.destroy();
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -61,6 +61,9 @@ public class ExecutorBeanDefinitionParser extends AbstractSingleBeanDefinitionPa
|
||||
return;
|
||||
}
|
||||
String prefix = "java.util.concurrent.ThreadPoolExecutor.";
|
||||
if (builder.getRawBeanDefinition().getBeanClassName().contains("backport")) {
|
||||
prefix = "edu.emory.mathcs.backport." + prefix;
|
||||
}
|
||||
String policyClassName;
|
||||
if (rejectionPolicy.equals("ABORT")) {
|
||||
policyClassName = prefix + "AbortPolicy";
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.config;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
/**
|
||||
* A representation of a scheduled task,
|
||||
* used as a return value for scheduling methods.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.3
|
||||
* @see ScheduledTaskRegistrar#scheduleTriggerTask
|
||||
* @see ScheduledTaskRegistrar#scheduleFixedRateTask
|
||||
*/
|
||||
public final class ScheduledTask {
|
||||
|
||||
volatile ScheduledFuture<?> future;
|
||||
|
||||
|
||||
ScheduledTask() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trigger cancellation of this scheduled task.
|
||||
*/
|
||||
public void cancel() {
|
||||
ScheduledFuture<?> future = this.future;
|
||||
if (future != null) {
|
||||
future.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+29
-132
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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,13 +19,13 @@ package org.springframework.scheduling.config;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
@@ -67,9 +67,7 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean
|
||||
|
||||
private List<IntervalTask> fixedDelayTasks;
|
||||
|
||||
private final Map<Task, ScheduledTask> unresolvedTasks = new HashMap<Task, ScheduledTask>(16);
|
||||
|
||||
private final Set<ScheduledTask> scheduledTasks = new LinkedHashSet<ScheduledTask>(16);
|
||||
private final Set<ScheduledFuture<?>> scheduledFutures = new LinkedHashSet<ScheduledFuture<?>>();
|
||||
|
||||
|
||||
/**
|
||||
@@ -230,7 +228,6 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean
|
||||
Collections.<IntervalTask>emptyList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a Runnable task to be triggered per the given {@link Trigger}.
|
||||
* @see TaskScheduler#scheduleAtFixedRate(Runnable, long)
|
||||
@@ -309,7 +306,6 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean
|
||||
this.fixedDelayTasks.add(task);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return whether this {@code ScheduledTaskRegistrar} has any tasks registered.
|
||||
* @since 3.2
|
||||
@@ -335,155 +331,56 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean
|
||||
* #setTaskScheduler(TaskScheduler) task scheduler}.
|
||||
*/
|
||||
protected void scheduleTasks() {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
if (this.taskScheduler == null) {
|
||||
this.localExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
|
||||
}
|
||||
if (this.triggerTasks != null) {
|
||||
for (TriggerTask task : this.triggerTasks) {
|
||||
addScheduledTask(scheduleTriggerTask(task));
|
||||
this.scheduledFutures.add(this.taskScheduler.schedule(
|
||||
task.getRunnable(), task.getTrigger()));
|
||||
}
|
||||
}
|
||||
if (this.cronTasks != null) {
|
||||
for (CronTask task : this.cronTasks) {
|
||||
addScheduledTask(scheduleCronTask(task));
|
||||
this.scheduledFutures.add(this.taskScheduler.schedule(
|
||||
task.getRunnable(), task.getTrigger()));
|
||||
}
|
||||
}
|
||||
if (this.fixedRateTasks != null) {
|
||||
for (IntervalTask task : this.fixedRateTasks) {
|
||||
addScheduledTask(scheduleFixedRateTask(task));
|
||||
if (task.getInitialDelay() > 0) {
|
||||
Date startTime = new Date(now + task.getInitialDelay());
|
||||
this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(
|
||||
task.getRunnable(), startTime, task.getInterval()));
|
||||
}
|
||||
else {
|
||||
this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(
|
||||
task.getRunnable(), task.getInterval()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.fixedDelayTasks != null) {
|
||||
for (IntervalTask task : this.fixedDelayTasks) {
|
||||
addScheduledTask(scheduleFixedDelayTask(task));
|
||||
if (task.getInitialDelay() > 0) {
|
||||
Date startTime = new Date(now + task.getInitialDelay());
|
||||
this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(
|
||||
task.getRunnable(), startTime, task.getInterval()));
|
||||
}
|
||||
else {
|
||||
this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(
|
||||
task.getRunnable(), task.getInterval()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addScheduledTask(ScheduledTask task) {
|
||||
if (task != null) {
|
||||
this.scheduledTasks.add(task);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Schedule the specified trigger task, either right away if possible
|
||||
* or on initialization of the scheduler.
|
||||
* @return a handle to the scheduled task, allowing to cancel it
|
||||
* @since 4.3
|
||||
*/
|
||||
public ScheduledTask scheduleTriggerTask(TriggerTask task) {
|
||||
ScheduledTask scheduledTask = this.unresolvedTasks.remove(task);
|
||||
boolean newTask = false;
|
||||
if (scheduledTask == null) {
|
||||
scheduledTask = new ScheduledTask();
|
||||
newTask = true;
|
||||
}
|
||||
if (this.taskScheduler != null) {
|
||||
scheduledTask.future = this.taskScheduler.schedule(task.getRunnable(), task.getTrigger());
|
||||
}
|
||||
else {
|
||||
addTriggerTask(task);
|
||||
this.unresolvedTasks.put(task, scheduledTask);
|
||||
}
|
||||
return (newTask ? scheduledTask : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the specified cron task, either right away if possible
|
||||
* or on initialization of the scheduler.
|
||||
* @return a handle to the scheduled task, allowing to cancel it
|
||||
* (or {@code null} if processing a previously registered task)
|
||||
* @since 4.3
|
||||
*/
|
||||
public ScheduledTask scheduleCronTask(CronTask task) {
|
||||
ScheduledTask scheduledTask = this.unresolvedTasks.remove(task);
|
||||
boolean newTask = false;
|
||||
if (scheduledTask == null) {
|
||||
scheduledTask = new ScheduledTask();
|
||||
newTask = true;
|
||||
}
|
||||
if (this.taskScheduler != null) {
|
||||
scheduledTask.future = this.taskScheduler.schedule(task.getRunnable(), task.getTrigger());
|
||||
}
|
||||
else {
|
||||
addCronTask(task);
|
||||
this.unresolvedTasks.put(task, scheduledTask);
|
||||
}
|
||||
return (newTask ? scheduledTask : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the specified fixed-rate task, either right away if possible
|
||||
* or on initialization of the scheduler.
|
||||
* @return a handle to the scheduled task, allowing to cancel it
|
||||
* (or {@code null} if processing a previously registered task)
|
||||
* @since 4.3
|
||||
*/
|
||||
public ScheduledTask scheduleFixedRateTask(IntervalTask task) {
|
||||
ScheduledTask scheduledTask = this.unresolvedTasks.remove(task);
|
||||
boolean newTask = false;
|
||||
if (scheduledTask == null) {
|
||||
scheduledTask = new ScheduledTask();
|
||||
newTask = true;
|
||||
}
|
||||
if (this.taskScheduler != null) {
|
||||
if (task.getInitialDelay() > 0) {
|
||||
Date startTime = new Date(System.currentTimeMillis() + task.getInitialDelay());
|
||||
scheduledTask.future =
|
||||
this.taskScheduler.scheduleAtFixedRate(task.getRunnable(), startTime, task.getInterval());
|
||||
}
|
||||
else {
|
||||
scheduledTask.future =
|
||||
this.taskScheduler.scheduleAtFixedRate(task.getRunnable(), task.getInterval());
|
||||
}
|
||||
}
|
||||
else {
|
||||
addFixedRateTask(task);
|
||||
this.unresolvedTasks.put(task, scheduledTask);
|
||||
}
|
||||
return (newTask ? scheduledTask : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the specified fixed-delay task, either right away if possible
|
||||
* or on initialization of the scheduler.
|
||||
* @return a handle to the scheduled task, allowing to cancel it
|
||||
* (or {@code null} if processing a previously registered task)
|
||||
* @since 4.3
|
||||
*/
|
||||
public ScheduledTask scheduleFixedDelayTask(IntervalTask task) {
|
||||
ScheduledTask scheduledTask = this.unresolvedTasks.remove(task);
|
||||
boolean newTask = false;
|
||||
if (scheduledTask == null) {
|
||||
scheduledTask = new ScheduledTask();
|
||||
newTask = true;
|
||||
}
|
||||
if (this.taskScheduler != null) {
|
||||
if (task.getInitialDelay() > 0) {
|
||||
Date startTime = new Date(System.currentTimeMillis() + task.getInitialDelay());
|
||||
scheduledTask.future =
|
||||
this.taskScheduler.scheduleWithFixedDelay(task.getRunnable(), startTime, task.getInterval());
|
||||
}
|
||||
else {
|
||||
scheduledTask.future =
|
||||
this.taskScheduler.scheduleWithFixedDelay(task.getRunnable(), task.getInterval());
|
||||
}
|
||||
}
|
||||
else {
|
||||
addFixedDelayTask(task);
|
||||
this.unresolvedTasks.put(task, scheduledTask);
|
||||
}
|
||||
return (newTask ? scheduledTask : null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
for (ScheduledTask task : this.scheduledTasks) {
|
||||
task.cancel();
|
||||
for (ScheduledFuture<?> future : this.scheduledFutures) {
|
||||
future.cancel(true);
|
||||
}
|
||||
if (this.localExecutor != null) {
|
||||
this.localExecutor.shutdownNow();
|
||||
|
||||
+31
-26
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2013 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,8 +16,8 @@
|
||||
|
||||
package org.springframework.scheduling.config;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionHandler;
|
||||
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
@@ -27,8 +27,8 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link FactoryBean} for creating {@link ThreadPoolTaskExecutor} instances,
|
||||
* primarily used behind the XML task namespace.
|
||||
* FactoryBean for creating ThreadPoolTaskExecutor instances, choosing
|
||||
* between the standard concurrent and the backport-concurrent variant.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
@@ -41,13 +41,13 @@ public class TaskExecutorFactoryBean implements
|
||||
|
||||
private Integer queueCapacity;
|
||||
|
||||
private RejectedExecutionHandler rejectedExecutionHandler;
|
||||
private Object rejectedExecutionHandler;
|
||||
|
||||
private Integer keepAliveSeconds;
|
||||
|
||||
private String beanName;
|
||||
|
||||
private ThreadPoolTaskExecutor target;
|
||||
private TaskExecutor target;
|
||||
|
||||
|
||||
public void setPoolSize(String poolSize) {
|
||||
@@ -58,7 +58,7 @@ public class TaskExecutorFactoryBean implements
|
||||
this.queueCapacity = queueCapacity;
|
||||
}
|
||||
|
||||
public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
|
||||
public void setRejectedExecutionHandler(Object rejectedExecutionHandler) {
|
||||
this.rejectedExecutionHandler = rejectedExecutionHandler;
|
||||
}
|
||||
|
||||
@@ -73,25 +73,28 @@ public class TaskExecutorFactoryBean implements
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
this.target = new ThreadPoolTaskExecutor();
|
||||
determinePoolSizeRange();
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
BeanWrapper bw = new BeanWrapperImpl(ThreadPoolTaskExecutor.class);
|
||||
determinePoolSizeRange(bw);
|
||||
if (this.queueCapacity != null) {
|
||||
this.target.setQueueCapacity(this.queueCapacity);
|
||||
bw.setPropertyValue("queueCapacity", this.queueCapacity);
|
||||
}
|
||||
if (this.keepAliveSeconds != null) {
|
||||
this.target.setKeepAliveSeconds(this.keepAliveSeconds);
|
||||
bw.setPropertyValue("keepAliveSeconds", this.keepAliveSeconds);
|
||||
}
|
||||
if (this.rejectedExecutionHandler != null) {
|
||||
this.target.setRejectedExecutionHandler(this.rejectedExecutionHandler);
|
||||
bw.setPropertyValue("rejectedExecutionHandler", this.rejectedExecutionHandler);
|
||||
}
|
||||
if (this.beanName != null) {
|
||||
this.target.setThreadNamePrefix(this.beanName + "-");
|
||||
bw.setPropertyValue("threadNamePrefix", this.beanName + "-");
|
||||
}
|
||||
this.target = (TaskExecutor) bw.getWrappedInstance();
|
||||
if (this.target instanceof InitializingBean) {
|
||||
((InitializingBean) this.target).afterPropertiesSet();
|
||||
}
|
||||
this.target.afterPropertiesSet();
|
||||
}
|
||||
|
||||
private void determinePoolSizeRange() {
|
||||
private void determinePoolSizeRange(BeanWrapper bw) {
|
||||
if (StringUtils.hasText(this.poolSize)) {
|
||||
try {
|
||||
int corePoolSize;
|
||||
@@ -105,15 +108,15 @@ public class TaskExecutorFactoryBean implements
|
||||
"Lower bound of pool-size range must not exceed the upper bound");
|
||||
}
|
||||
if (this.queueCapacity == null) {
|
||||
// No queue-capacity provided, so unbounded
|
||||
// no queue-capacity provided, so unbounded
|
||||
if (corePoolSize == 0) {
|
||||
// Actually set 'corePoolSize' to the upper bound of the range
|
||||
// but allow core threads to timeout...
|
||||
this.target.setAllowCoreThreadTimeOut(true);
|
||||
// actually set 'corePoolSize' to the upper bound of the range
|
||||
// but allow core threads to timeout
|
||||
bw.setPropertyValue("allowCoreThreadTimeOut", true);
|
||||
corePoolSize = maxPoolSize;
|
||||
}
|
||||
else {
|
||||
// Non-zero lower bound implies a core-max size range...
|
||||
// non-zero lower bound implies a core-max size range
|
||||
throw new IllegalArgumentException(
|
||||
"A non-zero lower bound for the size range requires a queue-capacity value");
|
||||
}
|
||||
@@ -124,8 +127,8 @@ public class TaskExecutorFactoryBean implements
|
||||
corePoolSize = value;
|
||||
maxPoolSize = value;
|
||||
}
|
||||
this.target.setCorePoolSize(corePoolSize);
|
||||
this.target.setMaxPoolSize(maxPoolSize);
|
||||
bw.setPropertyValue("corePoolSize", corePoolSize);
|
||||
bw.setPropertyValue("maxPoolSize", maxPoolSize);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new IllegalArgumentException("Invalid pool-size value [" + this.poolSize + "]: only single " +
|
||||
@@ -152,8 +155,10 @@ public class TaskExecutorFactoryBean implements
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
this.target.destroy();
|
||||
public void destroy() throws Exception {
|
||||
if (this.target instanceof DisposableBean) {
|
||||
((DisposableBean) this.target).destroy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2012 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,8 +19,8 @@ package org.springframework.scheduling.config;
|
||||
import org.springframework.scheduling.Trigger;
|
||||
|
||||
/**
|
||||
* {@link Task} implementation defining a {@code Runnable} to be executed
|
||||
* according to a given {@link Trigger}.
|
||||
* {@link Task} implementation defining a {@code Runnable} to be executed according to a
|
||||
* given {@link Trigger}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.2
|
||||
@@ -45,7 +45,6 @@ public class TriggerTask extends Task {
|
||||
|
||||
|
||||
public Trigger getTrigger() {
|
||||
return this.trigger;
|
||||
return trigger;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -95,6 +95,7 @@ public class CronSequenceGenerator {
|
||||
parse(expression);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the cron pattern that this sequence generator has been built for.
|
||||
*/
|
||||
@@ -261,7 +262,7 @@ public class CronSequenceGenerator {
|
||||
*/
|
||||
private void parse(String expression) throws IllegalArgumentException {
|
||||
String[] fields = StringUtils.tokenizeToStringArray(expression, " ");
|
||||
if (!areValidCronFields(fields)) {
|
||||
if (fields.length != 6) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Cron expression must consist of 6 fields (found %d in \"%s\")", fields.length, expression));
|
||||
}
|
||||
@@ -382,23 +383,6 @@ public class CronSequenceGenerator {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the specified expression represents a valid cron pattern.
|
||||
* <p>Specifically, this method verifies that the expression contains six
|
||||
* fields separated by single spaces.
|
||||
* @param expression the expression to evaluate
|
||||
* @return {@code true} if the given expression is a valid cron expression
|
||||
*/
|
||||
public static boolean isValidExpression(String expression) {
|
||||
String[] fields = StringUtils.tokenizeToStringArray(expression, " ");
|
||||
return areValidCronFields(fields);
|
||||
}
|
||||
|
||||
private static boolean areValidCronFields(String[] fields) {
|
||||
return (fields != null && fields.length == 6);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
|
||||
+1
-1
@@ -381,7 +381,7 @@ public class ScriptFactoryPostProcessor extends InstantiationAwareBeanPostProces
|
||||
* If the {@link BeanDefinition} has a
|
||||
* {@link org.springframework.core.AttributeAccessor metadata attribute}
|
||||
* under the key {@link #REFRESH_CHECK_DELAY_ATTRIBUTE} which is a valid {@link Number}
|
||||
* type, then this value is used. Otherwise, the {@link #defaultRefreshCheckDelay}
|
||||
* type, then this value is used. Otherwise, the the {@link #defaultRefreshCheckDelay}
|
||||
* value is used.
|
||||
* @param beanDefinition the BeanDefinition to check
|
||||
* @return the refresh check delay
|
||||
|
||||
+1
-3
@@ -293,9 +293,7 @@
|
||||
<xsd:attribute name="method" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the method to be invoked. The target method must expect no arguments.
|
||||
It will typically have a void return type; if not, the returned value will be
|
||||
ignored when called through the scheduler.
|
||||
The name of the method to be invoked.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
|
||||
@@ -36,7 +36,7 @@ final class _TestTypes { }
|
||||
|
||||
|
||||
/**
|
||||
* Aspect used as part of before advice binding tests and
|
||||
* Aspect used as part of before before advice binding tests and
|
||||
* serves as base class for a number of more specialized test aspects.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
|
||||
+8
-8
@@ -1,17 +1,17 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.config;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -236,18 +236,18 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
|
||||
@Test
|
||||
public void testMultipleProxiesForIntroductionAdvisor() {
|
||||
TestBean target1 = new TestBean();
|
||||
target1.setAge(20);
|
||||
TestBean target = new TestBean();
|
||||
target.setAge(20);
|
||||
TestBean target2 = new TestBean();
|
||||
target2.setAge(21);
|
||||
|
||||
ITestBean proxy1 = getIntroductionAdvisorProxy(target1);
|
||||
ITestBean proxy1 = getIntroductionAdvisorProxy(target);
|
||||
ITestBean proxy2 = getIntroductionAdvisorProxy(target2);
|
||||
assertSame("Incorrect duplicate creation of proxy classes", proxy1.getClass(), proxy2.getClass());
|
||||
}
|
||||
|
||||
private ITestBean getIntroductionAdvisorProxy(TestBean target) {
|
||||
ProxyFactory pf = new ProxyFactory(ITestBean.class);
|
||||
ProxyFactory pf = new ProxyFactory(new Class<?>[] {ITestBean.class});
|
||||
pf.setProxyTargetClass(true);
|
||||
|
||||
pf.addAdvisor(new LockMixinAdvisor());
|
||||
|
||||
+9
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.io.IOException;
|
||||
import org.junit.Test;
|
||||
import test.mixin.Lockable;
|
||||
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.framework.autoproxy.target.AbstractBeanFactoryBasedTargetSourceCreator;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
@@ -49,7 +48,7 @@ import static org.junit.Assert.*;
|
||||
* @author Chris Beams
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class AdvisorAutoProxyCreatorTests {
|
||||
public final class AdvisorAutoProxyCreatorTests {
|
||||
|
||||
private static final Class<?> CLASS = AdvisorAutoProxyCreatorTests.class;
|
||||
private static final String CLASSNAME = CLASS.getSimpleName();
|
||||
@@ -60,7 +59,6 @@ public class AdvisorAutoProxyCreatorTests {
|
||||
private static final String QUICK_TARGETSOURCE_CONTEXT = CLASSNAME + "-quick-targetsource.xml";
|
||||
private static final String OPTIMIZED_CONTEXT = CLASSNAME + "-optimized.xml";
|
||||
|
||||
|
||||
/**
|
||||
* Return a bean factory with attributes and EnterpriseServices configured.
|
||||
*/
|
||||
@@ -68,7 +66,6 @@ public class AdvisorAutoProxyCreatorTests {
|
||||
return new ClassPathXmlApplicationContext(DEFAULT_CONTEXT, CLASS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check that we can provide a common interceptor that will
|
||||
* appear in the chain before "specific" interceptors,
|
||||
@@ -81,8 +78,8 @@ public class AdvisorAutoProxyCreatorTests {
|
||||
assertTrue(AopUtils.isAopProxy(test1));
|
||||
|
||||
Lockable lockable1 = (Lockable) test1;
|
||||
NopInterceptor nop1 = (NopInterceptor) bf.getBean("nopInterceptor");
|
||||
NopInterceptor nop2 = (NopInterceptor) bf.getBean("pointcutAdvisor", Advisor.class).getAdvice();
|
||||
NopInterceptor nop = (NopInterceptor) bf.getBean("nopInterceptor");
|
||||
assertEquals(0, nop.getCount());
|
||||
|
||||
ITestBean test2 = (ITestBean) bf.getBean("test2");
|
||||
Lockable lockable2 = (Lockable) test2;
|
||||
@@ -90,28 +87,14 @@ public class AdvisorAutoProxyCreatorTests {
|
||||
// Locking should be independent; nop is shared
|
||||
assertFalse(lockable1.locked());
|
||||
assertFalse(lockable2.locked());
|
||||
// equals 2 calls on shared nop, because it's first and sees calls
|
||||
// against the Lockable interface introduced by the specific advisor
|
||||
assertEquals(2, nop1.getCount());
|
||||
assertEquals(0, nop2.getCount());
|
||||
// equals 2 calls on shared nop, because it's first
|
||||
// and sees calls against the Lockable interface introduced
|
||||
// by the specific advisor
|
||||
assertEquals(2, nop.getCount());
|
||||
lockable1.lock();
|
||||
assertTrue(lockable1.locked());
|
||||
assertFalse(lockable2.locked());
|
||||
assertEquals(5, nop1.getCount());
|
||||
assertEquals(0, nop2.getCount());
|
||||
|
||||
PackageVisibleMethod packageVisibleMethod = (PackageVisibleMethod) bf.getBean("packageVisibleMethod");
|
||||
assertEquals(5, nop1.getCount());
|
||||
assertEquals(0, nop2.getCount());
|
||||
packageVisibleMethod.doSomething();
|
||||
assertEquals(6, nop1.getCount());
|
||||
assertEquals(1, nop2.getCount());
|
||||
assertTrue(packageVisibleMethod instanceof Lockable);
|
||||
Lockable lockable3 = (Lockable) packageVisibleMethod;
|
||||
lockable3.lock();
|
||||
assertTrue(lockable3.locked());
|
||||
lockable3.unlock();
|
||||
assertFalse(lockable3.locked());
|
||||
assertEquals(5, nop.getCount());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,7 +202,6 @@ public class AdvisorAutoProxyCreatorTests {
|
||||
|
||||
}
|
||||
|
||||
|
||||
class SelectivePrototypeTargetSourceCreator extends AbstractBeanFactoryBasedTargetSourceCreator {
|
||||
|
||||
@Override
|
||||
|
||||
+2
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -56,7 +56,7 @@ import static org.junit.Assert.*;
|
||||
* @since 09.12.2003
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class AutoProxyCreatorTests {
|
||||
public final class AutoProxyCreatorTests {
|
||||
|
||||
@Test
|
||||
public void testBeanNameAutoProxyCreator() {
|
||||
@@ -252,23 +252,6 @@ public class AutoProxyCreatorTests {
|
||||
assertEquals(2, tapc.testInterceptor.nrOfInvocations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoProxyCreatorWithPackageVisibleMethod() {
|
||||
StaticApplicationContext sac = new StaticApplicationContext();
|
||||
sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class);
|
||||
sac.registerSingleton("packageVisibleMethodToBeProxied", PackageVisibleMethod.class);
|
||||
sac.refresh();
|
||||
|
||||
TestAutoProxyCreator tapc = (TestAutoProxyCreator) sac.getBean("testAutoProxyCreator");
|
||||
tapc.testInterceptor.nrOfInvocations = 0;
|
||||
|
||||
PackageVisibleMethod tb = (PackageVisibleMethod) sac.getBean("packageVisibleMethodToBeProxied");
|
||||
assertTrue(AopUtils.isCglibProxy(tb));
|
||||
assertEquals(0, tapc.testInterceptor.nrOfInvocations);
|
||||
tb.doSomething();
|
||||
assertEquals(1, tapc.testInterceptor.nrOfInvocations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoProxyCreatorWithFactoryBean() {
|
||||
StaticApplicationContext sac = new StaticApplicationContext();
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.framework.autoproxy;
|
||||
|
||||
public class PackageVisibleMethod {
|
||||
|
||||
void doSomething() {
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user