Compare commits

..

1 Commits

Author SHA1 Message Date
Spring Buildmaster fe7a8aea2a Release version 4.3.0.RC1 2016-04-06 07:42:49 +00:00
473 changed files with 3671 additions and 7259 deletions
+8
View File
@@ -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
View File
@@ -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
View File
@@ -1 +1 @@
version=4.3.0.RC2
version=4.3.0.RC1
Binary file not shown.
+2 -2
View File
@@ -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
Vendored
+22 -26
View File
@@ -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
View File
@@ -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
+3 -3
View File
@@ -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 -----------------------------------------------------------------------
+2 -2
View File
@@ -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
@@ -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
@@ -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,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,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,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,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()) {
@@ -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,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;
@@ -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");
@@ -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,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) {
@@ -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,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
@@ -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)}
@@ -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,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,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.
@@ -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) {
@@ -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());
}
}
@@ -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 {
@@ -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.
@@ -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;
@@ -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);
@@ -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()}.
@@ -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()}.
@@ -24,6 +24,7 @@ import org.quartz.CronTrigger;
import static org.junit.Assert.*;
/**
*
* @author Stephane Nicoll
*/
public class CronTriggerFactoryBeanTests {
@@ -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();
@@ -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">
* &#064;Configuration
* &#064;EnableCaching
* public class AppConfig {
*
* &#064;Bean
* public MyService myService() {
* // configure and return a class having &#064;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">
* &#064;Configuration
* &#064;EnableCaching
* public class AppConfig extends CachingConfigurerSupport {
*
* &#064;Bean
* public MyService myService() {
* // configure and return a class having &#064;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.
@@ -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));
}
}
@@ -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);
@@ -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);
}
}
}
@@ -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;
}
@@ -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;
}
@@ -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 {
@@ -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;
}
@@ -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;
@@ -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,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;
@@ -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">
* &#064;Configuration
* public class AppConfig {
*
* &#064;Bean
* public FooService fooService() {
* return new FooService(fooRepository());
* }
*
* &#064;Bean
* public FooRepository fooRepository() {
* return new JdbcFooRepository(dataSource());
* }
*
* // ...
* }</pre>
*
@@ -158,8 +152,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* &#064;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.
@@ -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
@@ -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">
* &#064;Configuration
* public class AppConfig {
*
* &#064;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">
* &#064;Configuration
* &#064;ComponentScan("com.acme.app.services")
@@ -96,20 +89,18 @@ import org.springframework.stereotype.Component;
* // various &#064;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">
* &#064;Configuration
* public class AppConfig {
*
* &#064Inject Environment env;
*
* &#064;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">
* &#064;Configuration
* &#064;PropertySource("classpath:/com/acme/app.properties")
* public class AppConfig {
*
* &#064Inject Environment env;
*
* &#064;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">
* &#064;Configuration
* &#064;PropertySource("classpath:/com/acme/app.properties")
* public class AppConfig {
*
* &#064Value("${bean.name}") String beanName;
*
* &#064;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">
* &#064;Configuration
* public class DatabaseConfig {
*
* &#064;Bean
* public DataSource dataSource() {
* // instantiate, configure and return DataSource
@@ -190,7 +172,6 @@ import org.springframework.stereotype.Component;
* &#064;Configuration
* &#064;Import(DatabaseConfig.class)
* public class AppConfig {
*
* &#064Inject DatabaseConfig dataConfig;
*
* &#064;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">
* &#064;Profile("embedded")
* &#064;Configuration
* public class EmbeddedDatabaseConfig {
*
* &#064;Bean
* public DataSource dataSource() {
* // instantiate, configure and return embedded DataSource
@@ -225,29 +204,25 @@ import org.springframework.stereotype.Component;
* &#064;Profile("production")
* &#064;Configuration
* public class ProductionDatabaseConfig {
*
* &#064;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">
* &#064;Configuration
* &#064;ImportResource("classpath:/com/acme/database-config.xml")
* public class AppConfig {
*
* &#064Inject DataSource dataSource; // from XML
*
* &#064;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">
* &#064;Configuration
* public class AppConfig {
*
* &#064;Inject DataSource dataSource;
*
* &#064;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">
* &#064;RunWith(SpringJUnit4ClassRunner.class)
* &#064;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>&#064;Configuration classes must be non-final
* <li>&#064;Configuration classes must be non-local (may not be declared within a method)
@@ -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,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,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;
* &#064;Configuration
* &#064;EnableAspectJAutoProxy
* public class AppConfig {
*
* &#064;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">
* &#064;Aspect
* public class MyAspect {
*
* &#064;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">
* &#064;Configuration
* &#064;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">
* &#064;Configuration
* &#064;ComponentScan("com.foo")
* &#064;EnableAspectJAutoProxy
* public class AppConfig {
*
* // no explicit &#064Bean definitions required
* }</pre>
*
@@ -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">
* &#064;Configuration
* &#064;EnableLoadTimeWeaving
* public class AppConfig {
*
* // application-specific &#064;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">
* &#064;Configuration
* &#064;EnableLoadTimeWeaving
* public class AppConfig implements LoadTimeWeavingConfigurer {
*
* &#064;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">
* &#064;Configuration
* &#064;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;
}
}
@@ -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);
}
@@ -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">
* &#064;Configuration
* &#064;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.
*
@@ -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));
}
@@ -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
@@ -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) {
@@ -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
*/
@@ -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)) {
@@ -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
@@ -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);
@@ -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());
@@ -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());
@@ -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();
}
}
@@ -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;
}
@@ -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
@@ -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>
@@ -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
@@ -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.
@@ -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
@@ -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
@@ -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();
}
@@ -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);
}
}
}
@@ -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();
@@ -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;
}
}
@@ -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) {
@@ -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
@@ -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
@@ -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());
@@ -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
@@ -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();
@@ -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