mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-19 19:29:03 +00:00
Compare commits
161
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51c9d3e9ac | ||
|
|
e57047adf8 | ||
|
|
f85be8ebef | ||
|
|
f22c669f45 | ||
|
|
a7dc48534e | ||
|
|
bd282e632f | ||
|
|
6bdc5bfc08 | ||
|
|
8c26717bdc | ||
|
|
6075c81371 | ||
|
|
f473392a42 | ||
|
|
1e2b8aba76 | ||
|
|
f6024c23ca | ||
|
|
703b3b1524 | ||
|
|
cfd16f9c94 | ||
|
|
70f2736c6c | ||
|
|
a5070d562c | ||
|
|
5fe608d098 | ||
|
|
71fd621a1b | ||
|
|
1295f62319 | ||
|
|
b9a2d0af98 | ||
|
|
52f21bdf54 | ||
|
|
3185f67b43 | ||
|
|
9520a593bd | ||
|
|
6924f00f8c | ||
|
|
e8562bb3af | ||
|
|
a4b5425108 | ||
|
|
74b4dd0a40 | ||
|
|
9ec50a278e | ||
|
|
d3c0e75b95 | ||
|
|
9be54047e9 | ||
|
|
cb64dd1583 | ||
|
|
c38381a54d | ||
|
|
51a557b885 | ||
|
|
fc37824bc0 | ||
|
|
2b9c527d31 | ||
|
|
14ab9800ff | ||
|
|
a1c09877d9 | ||
|
|
0b8822fab4 | ||
|
|
49ae46d7e4 | ||
|
|
7da129539f | ||
|
|
6009e03a7f | ||
|
|
2e90a1ccdc | ||
|
|
25cf96f6df | ||
|
|
d6a4981a92 | ||
|
|
07db535b37 | ||
|
|
5cbe90b2cd | ||
|
|
7de8f4f584 | ||
|
|
cf39078fbb | ||
|
|
3d6b0ca5be | ||
|
|
a8418d3bcd | ||
|
|
dc20a32ded | ||
|
|
ac5b9c7bd6 | ||
|
|
7c998a70bc | ||
|
|
8adff1bd70 | ||
|
|
fe76f4084a | ||
|
|
9e3bb1e26f | ||
|
|
c2eb5e1c1c | ||
|
|
4fe386d572 | ||
|
|
ad103016eb | ||
|
|
512d1263f2 | ||
|
|
d11b9577d5 | ||
|
|
1ea9dd0579 | ||
|
|
9d5b6430c4 | ||
|
|
f93c520ffe | ||
|
|
368773d3bb | ||
|
|
12eb893e5f | ||
|
|
c0e5d00e56 | ||
|
|
73823151bf | ||
|
|
a385153e8c | ||
|
|
f7031dfb10 | ||
|
|
7bc04dcd5d | ||
|
|
8890d3190a | ||
|
|
88be06e152 | ||
|
|
dac8c9e0f6 | ||
|
|
03585f2e4e | ||
|
|
8d7d4cecf8 | ||
|
|
2ea69c37c6 | ||
|
|
d42cc149db | ||
|
|
86ba7476cb | ||
|
|
1489e29d0c | ||
|
|
f2e4da3dac | ||
|
|
6a9329cb76 | ||
|
|
ac5c904335 | ||
|
|
fb4408c779 | ||
|
|
51e8aed41f | ||
|
|
03f547eb98 | ||
|
|
daada71c36 | ||
|
|
ef4c978c25 | ||
|
|
8a8225925e | ||
|
|
6c138d3981 | ||
|
|
bb8a12ff78 | ||
|
|
2b3d1bef10 | ||
|
|
51a0237e0a | ||
|
|
73a2407545 | ||
|
|
b15da37891 | ||
|
|
eb5b147364 | ||
|
|
7491efa2c8 | ||
|
|
d2447ce523 | ||
|
|
30a55d73db | ||
|
|
d875772103 | ||
|
|
0d394a02f3 | ||
|
|
d996a0988b | ||
|
|
5a711c05ec | ||
|
|
1e42464c22 | ||
|
|
896f0d91f9 | ||
|
|
50eef1b979 | ||
|
|
d5de3867ca | ||
|
|
a64dcc2a31 | ||
|
|
e5ccdfb029 | ||
|
|
adb54b2c69 | ||
|
|
eb6368ca3f | ||
|
|
ed9769a11b | ||
|
|
b5a56ca3a9 | ||
|
|
dd73848e15 | ||
|
|
64a039402a | ||
|
|
e748cf17d9 | ||
|
|
3e2491c058 | ||
|
|
e51da28897 | ||
|
|
e7cc19537d | ||
|
|
474862a7c9 | ||
|
|
0920266b33 | ||
|
|
de9c5a8c4d | ||
|
|
d879bad248 | ||
|
|
ff76be2d16 | ||
|
|
e5207e6231 | ||
|
|
1c10861a92 | ||
|
|
1f9bc50c3e | ||
|
|
2d3fe96cd6 | ||
|
|
9b26e4f1ad | ||
|
|
9a7871fb70 | ||
|
|
80128f1992 | ||
|
|
186fef6808 | ||
|
|
3f8d48eb1a | ||
|
|
3ed24bca20 | ||
|
|
f8a8ecd8fe | ||
|
|
16df002de7 | ||
|
|
840ffc5ec4 | ||
|
|
64e79ba692 | ||
|
|
4bcf92f176 | ||
|
|
75a9c45865 | ||
|
|
62a6c3733d | ||
|
|
e353af65d2 | ||
|
|
568e963466 | ||
|
|
c50886ce03 | ||
|
|
2b0ada95ce | ||
|
|
4efe6a8a5c | ||
|
|
ec3967a6c7 | ||
|
|
4c5e17ec3e | ||
|
|
9413204838 | ||
|
|
925c46e445 | ||
|
|
a6a837bc3b | ||
|
|
0e3b26da27 | ||
|
|
98cbae7fdc | ||
|
|
379d2e6da0 | ||
|
|
c75e370eaf | ||
|
|
4b4bc2dae0 | ||
|
|
feb6552d2c | ||
|
|
7f1e5a49a4 | ||
|
|
f6e1856276 | ||
|
|
d02d9cea4e | ||
|
|
cf5077861a |
@@ -30,6 +30,7 @@ spring-*/src/main/java/META-INF/MANIFEST.MF
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea
|
||||
out
|
||||
test-output
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
@@ -19,14 +19,6 @@ in our [JIRA issue tracker][] to see if you can find something similar. If not,
|
||||
please create a new issue before submitting a pull request unless the change is
|
||||
truly trivial, e.g. 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 Contributor License Agreement
|
||||
|
||||
If you have not previously done so, please fill out and submit the
|
||||
|
||||
+26
-26
@@ -1,10 +1,10 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url "http://repo.springsource.org/plugins-release" }
|
||||
maven { url "https://repo.spring.io/plugins-release" }
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
|
||||
classpath("org.springframework.build.gradle:docbook-reference-plugin:0.2.8")
|
||||
classpath("io.spring.gradle:docbook-reference-plugin:0.3.1")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ configure(allprojects) { project ->
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url "http://repo.spring.io/libs-release" }
|
||||
maven { url "https://repo.spring.io/libs-release" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -182,7 +182,7 @@ project("spring-core") {
|
||||
// avoids including two different copies of asm unnecessarily. If however future cglib
|
||||
// versions drift from the version of asm used by Spring internally, this duplication
|
||||
// will become necessary.
|
||||
def asmVersion = "5.0.3"
|
||||
def asmVersion = "5.0.4"
|
||||
def cglibVersion = "3.1"
|
||||
|
||||
configurations {
|
||||
@@ -359,7 +359,7 @@ project("spring-tx") {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
optional(project(":spring-aop"))
|
||||
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
|
||||
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
|
||||
optional("aopalliance:aopalliance:1.0")
|
||||
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
|
||||
optional("javax.resource:connector-api:1.5")
|
||||
@@ -434,7 +434,7 @@ project("spring-jdbc") {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-core"))
|
||||
compile(project(":spring-tx"))
|
||||
optional(project(":spring-context")) // for JndiDataSourceLookup
|
||||
optional(project(":spring-context")) // for JndiDataSourceLookup
|
||||
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
|
||||
optional("c3p0:c3p0:0.9.1.2")
|
||||
optional("hsqldb:hsqldb:${hsqldbVersion}")
|
||||
@@ -452,8 +452,8 @@ project("spring-context-support") {
|
||||
compile(project(":spring-beans"))
|
||||
compile(project(":spring-context"))
|
||||
provided("javax.activation:activation:1.1")
|
||||
optional(project(":spring-jdbc")) // for Quartz support
|
||||
optional(project(":spring-tx")) // for Quartz support
|
||||
optional(project(":spring-jdbc")) // for Quartz support
|
||||
optional(project(":spring-tx")) // for Quartz support
|
||||
optional("javax.mail:mail:1.4.7")
|
||||
optional("javax.cache:cache-api:0.5")
|
||||
optional("net.sf.ehcache:ehcache-core:2.0.1")
|
||||
@@ -464,8 +464,8 @@ project("spring-context-support") {
|
||||
optional("com.lowagie:itext:2.1.7")
|
||||
optional("net.sf.jasperreports:jasperreports:3.7.6")
|
||||
testCompile("org.apache.poi:poi:3.6")
|
||||
testCompile("commons-beanutils:commons-beanutils:1.8.0") // for Velocity/JasperReports
|
||||
testCompile("commons-digester:commons-digester:1.8.1") // for Velocity/JasperReports
|
||||
testCompile("commons-beanutils:commons-beanutils:1.8.0") // for Velocity/JasperReports
|
||||
testCompile("commons-digester:commons-digester:1.8.1") // for Velocity/JasperReports
|
||||
testCompile("hsqldb:hsqldb:${hsqldbVersion}")
|
||||
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
|
||||
}
|
||||
@@ -478,13 +478,13 @@ project("spring-web") {
|
||||
description = "Spring Web"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
|
||||
compile(project(":spring-beans")) // for MultiPartFilter
|
||||
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
|
||||
compile(project(":spring-beans")) // for MultipartFilter
|
||||
compile(project(":spring-context"))
|
||||
compile(project(":spring-core"))
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
provided("javax.activation:activation:1.1")
|
||||
optional(project(":spring-oxm")) // for MarshallingHttpMessageConverter
|
||||
optional(project(":spring-oxm")) // for MarshallingHttpMessageConverter
|
||||
optional("javax.servlet.jsp:jsp-api:2.1")
|
||||
optional("javax.portlet:portlet-api:2.0")
|
||||
optional("javax.el:el-api:1.0")
|
||||
@@ -562,8 +562,8 @@ project("spring-orm-hibernate4") {
|
||||
provided(project(":spring-jdbc"))
|
||||
provided(project(":spring-tx"))
|
||||
optional(project(":spring-web"))
|
||||
optional("org.hibernate:hibernate-core:4.2.15.Final")
|
||||
optional("org.hibernate:hibernate-entitymanager:4.2.15.Final")
|
||||
optional("org.hibernate:hibernate-core:4.2.21.Final")
|
||||
optional("org.hibernate:hibernate-entitymanager:4.2.21.Final")
|
||||
optional("javax.servlet:servlet-api:2.5")
|
||||
}
|
||||
}
|
||||
@@ -578,8 +578,8 @@ project("spring-webmvc") {
|
||||
compile(project(":spring-expression"))
|
||||
compile(project(":spring-web"))
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional(project(":spring-context-support")) // for Velocity support
|
||||
optional(project(":spring-oxm")) // for MarshallingView
|
||||
optional(project(":spring-context-support")) // for Velocity support
|
||||
optional(project(":spring-oxm")) // for MarshallingView
|
||||
optional("javax.servlet.jsp:jsp-api:2.1")
|
||||
optional("javax.servlet:jstl:1.2")
|
||||
optional("net.sourceforge.jexcelapi:jxl:2.6.12")
|
||||
@@ -786,13 +786,13 @@ project("spring-aspects") {
|
||||
rt("org.aspectj:aspectjrt:${aspectjVersion}")
|
||||
compile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
provided("javax.persistence:persistence-api:1.0")
|
||||
optional(project(":spring-aop")) // for @Async support
|
||||
optional(project(":spring-beans")) // for @Configurable support
|
||||
optional(project(":spring-context")) // for @Enable* support
|
||||
optional(project(":spring-context-support")) // for JavaMail support
|
||||
optional(project(":spring-orm")) // for JPA exception translation support
|
||||
optional(project(":spring-tx")) // for JPA, @Transactional support
|
||||
testCompile(project(":spring-core")) // for CodeStyleAspect
|
||||
optional(project(":spring-aop")) // for @Async support
|
||||
optional(project(":spring-beans")) // for @Configurable support
|
||||
optional(project(":spring-context")) // for @Enable* support
|
||||
optional(project(":spring-context-support")) // for JavaMail support
|
||||
optional(project(":spring-orm")) // for JPA exception translation support
|
||||
optional(project(":spring-tx")) // for JPA, @Transactional support
|
||||
testCompile(project(":spring-core")) // for CodeStyleAspect
|
||||
testCompile(project(":spring-test"))
|
||||
testCompile("javax.mail:mail:1.4.7")
|
||||
}
|
||||
@@ -879,7 +879,7 @@ configure(rootProject) {
|
||||
testCompile("javax.inject:javax.inject:1")
|
||||
testCompile("javax.resource:connector-api:1.5")
|
||||
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
testCompile("org.hibernate:hibernate-core:4.2.15.Final")
|
||||
testCompile("org.hibernate:hibernate-core:4.2.21.Final")
|
||||
testCompile("hsqldb:hsqldb:${hsqldbVersion}")
|
||||
}
|
||||
|
||||
@@ -1050,7 +1050,7 @@ configure(rootProject) {
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
description = "Generates gradlew[.bat] scripts"
|
||||
gradleVersion = "1.12"
|
||||
gradleVersion = "2.5"
|
||||
|
||||
doLast() {
|
||||
def gradleOpts = "-XX:MaxPermSize=1024m -Xmx1024m"
|
||||
|
||||
@@ -68,8 +68,8 @@ class MergePlugin implements Plugin<Project> {
|
||||
Configuration runtimeMerge = project.configurations.create("runtimeMerge")
|
||||
|
||||
// Ensure the IDE can reference merged projects
|
||||
project.eclipse.classpath.plusConfigurations += [runtimeMerge]
|
||||
project.idea.module.scopes.PROVIDED.plus += runtimeMerge
|
||||
project.eclipse.classpath.plusConfigurations += [ runtimeMerge ]
|
||||
project.idea.module.scopes.PROVIDED.plus += [ runtimeMerge ]
|
||||
|
||||
// Hook to perform the actual merge logic
|
||||
project.afterEvaluate{
|
||||
@@ -132,8 +132,9 @@ class MergePlugin implements Plugin<Project> {
|
||||
intoConfiguration.dependencies.add(it)
|
||||
}
|
||||
}
|
||||
def index = project.parent.childProjects.findIndexOf {p -> p.getValue() == project}
|
||||
project.merge.into.install.repositories.mavenInstaller.pom.scopeMappings.addMapping(
|
||||
mapping.priority + 100, intoConfiguration, mapping.scope)
|
||||
mapping.priority + 100 + index, intoConfiguration, mapping.scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=3.2.12.RELEASE
|
||||
version=3.2.18.RELEASE
|
||||
|
||||
@@ -41,6 +41,17 @@ eclipse.classpath.file.whenMerged { classpath ->
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure project dependencies come after 3rd-party libs (SPR-11836)
|
||||
// https://jira.spring.io/browse/SPR-11836
|
||||
eclipse.classpath.file.whenMerged { classpath ->
|
||||
classpath.entries.findAll { it instanceof ProjectDependency }.each {
|
||||
// delete from original position
|
||||
classpath.entries.remove(it)
|
||||
// append to end of classpath
|
||||
classpath.entries.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
// Allow projects to be used as WPT modules
|
||||
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
|
||||
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-bin.zip
|
||||
|
||||
+36
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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,6 +19,7 @@ package org.springframework.aop.aspectj;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -200,8 +201,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
pointcutParameters[i] = parser.createPointcutParameter(
|
||||
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
|
||||
}
|
||||
return parser.parsePointcutExpression(
|
||||
replaceBooleanOperators(getExpression()),
|
||||
return parser.parsePointcutExpression(replaceBooleanOperators(getExpression()),
|
||||
this.pointcutDeclarationScope, pointcutParameters);
|
||||
}
|
||||
|
||||
@@ -319,29 +319,41 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
catch (IllegalStateException ex) {
|
||||
// No current invocation...
|
||||
// TODO: Should we really proceed here?
|
||||
logger.debug("Couldn't access current invocation - matching with limited context: " + ex);
|
||||
}
|
||||
|
||||
JoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args);
|
||||
|
||||
/*
|
||||
* Do a final check to see if any this(TYPE) kind of residue match. For
|
||||
* this purpose, we use the original method's (proxy method's) shadow to
|
||||
* ensure that 'this' is correctly checked against. Without this check,
|
||||
* we get incorrect match on this(TYPE) where TYPE matches the target
|
||||
* type but not 'this' (as would be the case of JDK dynamic proxies).
|
||||
* <p>See SPR-2979 for the original bug.
|
||||
*/
|
||||
if (pmi != null) { // there is a current invocation
|
||||
RuntimeTestWalker originalMethodResidueTest = getRuntimeTestWalker(originalShadowMatch);
|
||||
if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) {
|
||||
return false;
|
||||
}
|
||||
if (joinPointMatch.matches()) {
|
||||
bindParameters(pmi, joinPointMatch);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not access current invocation - matching with limited context: " + ex);
|
||||
}
|
||||
}
|
||||
return joinPointMatch.matches();
|
||||
|
||||
try {
|
||||
JoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args);
|
||||
|
||||
/*
|
||||
* Do a final check to see if any this(TYPE) kind of residue match. For
|
||||
* this purpose, we use the original method's (proxy method's) shadow to
|
||||
* ensure that 'this' is correctly checked against. Without this check,
|
||||
* we get incorrect match on this(TYPE) where TYPE matches the target
|
||||
* type but not 'this' (as would be the case of JDK dynamic proxies).
|
||||
* <p>See SPR-2979 for the original bug.
|
||||
*/
|
||||
if (pmi != null) { // there is a current invocation
|
||||
RuntimeTestWalker originalMethodResidueTest = getRuntimeTestWalker(originalShadowMatch);
|
||||
if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) {
|
||||
return false;
|
||||
}
|
||||
if (joinPointMatch.matches()) {
|
||||
bindParameters(pmi, joinPointMatch);
|
||||
}
|
||||
}
|
||||
|
||||
return joinPointMatch.matches();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to evaluate join point for arguments " + Arrays.asList(args) +
|
||||
" - falling back to non-match", ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getCurrentProxiedBeanName() {
|
||||
|
||||
+25
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -18,9 +18,11 @@ package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.support.AbstractBeanFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -66,7 +68,9 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
* @param name the name of the bean
|
||||
* @param type the type that should be introspected by AspectJ
|
||||
*/
|
||||
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class type) {
|
||||
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);
|
||||
@@ -78,18 +82,31 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
}
|
||||
|
||||
public ClassLoader getAspectClassLoader() {
|
||||
if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
|
||||
}
|
||||
else {
|
||||
return ClassUtils.getDefaultClassLoader();
|
||||
}
|
||||
return (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
|
||||
ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
public AspectMetadata getAspectMetadata() {
|
||||
return this.aspectMetadata;
|
||||
}
|
||||
|
||||
public Object getAspectCreationMutex() {
|
||||
if (this.beanFactory != null) {
|
||||
if (this.beanFactory.isSingleton(this.name)) {
|
||||
// Rely on singleton semantics provided by the factory -> no local lock.
|
||||
return null;
|
||||
}
|
||||
else if (this.beanFactory instanceof AbstractBeanFactory) {
|
||||
// No singleton guarantees from the factory -> let's lock locally but
|
||||
// reuse the factory's singleton lock, just in case a lazy dependency
|
||||
// of our advice bean happens to trigger the singleton lock implicitly...
|
||||
return ((AbstractBeanFactory) this.beanFactory).getSingletonMutex();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the order for this factory's target aspect, either
|
||||
* an instance-specific order expressed through implementing the
|
||||
|
||||
+14
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* 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.
|
||||
@@ -42,11 +42,20 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
}
|
||||
|
||||
|
||||
public synchronized Object getAspectInstance() {
|
||||
public Object getAspectInstance() {
|
||||
if (this.materialized == null) {
|
||||
synchronized (this) {
|
||||
if (this.materialized == null) {
|
||||
this.materialized = this.maaif.getAspectInstance();
|
||||
Object mutex = this;
|
||||
if (this.maaif instanceof BeanFactoryAspectInstanceFactory) {
|
||||
mutex = ((BeanFactoryAspectInstanceFactory) this.maaif).getAspectCreationMutex();
|
||||
}
|
||||
if (mutex == null) {
|
||||
this.materialized = this.maaif.getAspectInstance();
|
||||
}
|
||||
else {
|
||||
synchronized (mutex) {
|
||||
if (this.materialized == null) {
|
||||
this.materialized = this.maaif.getAspectInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -93,7 +93,7 @@ final class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
|
||||
/** Logger available to subclasses; static to optimize serialization */
|
||||
protected final static Log logger = LogFactory.getLog(CglibAopProxy.class);
|
||||
protected static final Log logger = LogFactory.getLog(CglibAopProxy.class);
|
||||
|
||||
/** Keeps track of the Classes that we have validated for final methods */
|
||||
private static final Map<Class<?>, Boolean> validatedClasses = new WeakHashMap<Class<?>, Boolean>();
|
||||
@@ -294,13 +294,13 @@ final class CglibAopProxy implements AopProxy, Serializable {
|
||||
Callback targetDispatcher = isStatic ?
|
||||
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
|
||||
|
||||
Callback[] mainCallbacks = new Callback[]{
|
||||
aopInterceptor, // for normal advice
|
||||
targetInterceptor, // invoke target without considering advice, if optimized
|
||||
new SerializableNoOp(), // no override for methods mapped to this
|
||||
targetDispatcher, this.advisedDispatcher,
|
||||
new EqualsInterceptor(this.advised),
|
||||
new HashCodeInterceptor(this.advised)
|
||||
Callback[] mainCallbacks = new Callback[] {
|
||||
aopInterceptor, // for normal advice
|
||||
targetInterceptor, // invoke target without considering advice, if optimized
|
||||
new SerializableNoOp(), // no override for methods mapped to this
|
||||
targetDispatcher, this.advisedDispatcher,
|
||||
new EqualsInterceptor(this.advised),
|
||||
new HashCodeInterceptor(this.advised)
|
||||
};
|
||||
|
||||
Callback[] callbacks;
|
||||
@@ -678,10 +678,11 @@ final class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
private final MethodProxy methodProxy;
|
||||
|
||||
private boolean protectedMethod;
|
||||
private final boolean protectedMethod;
|
||||
|
||||
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
|
||||
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
|
||||
|
||||
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
||||
this.methodProxy = methodProxy;
|
||||
this.protectedMethod = Modifier.isProtected(method.getModifiers());
|
||||
@@ -800,8 +801,7 @@ final class CglibAopProxy implements AopProxy, Serializable {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Method has advice and optimisations are enabled: " + method);
|
||||
}
|
||||
// We know that we are optimising so we can use the
|
||||
// FixedStaticChainInterceptors.
|
||||
// We know that we are optimising so we can use the FixedStaticChainInterceptors.
|
||||
int index = this.fixedInterceptorMap.get(key);
|
||||
return (index + this.fixedInterceptorOffset);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for asynchronous method execution aspects, such as
|
||||
* {@link org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor}
|
||||
* {@code org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor}
|
||||
* or {@code org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect}.
|
||||
*
|
||||
* <p>Provides support for <i>executor qualification</i> on a method-by-method basis.
|
||||
|
||||
+49
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -23,6 +23,7 @@ import org.aopalliance.aop.Advice;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.support.AbstractBeanFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -45,7 +46,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private transient Advice advice;
|
||||
private transient volatile Advice advice;
|
||||
|
||||
private transient volatile Object adviceMonitor = new Object();
|
||||
|
||||
@@ -71,8 +72,23 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
resetAdviceMonitor();
|
||||
}
|
||||
|
||||
private void resetAdviceMonitor() {
|
||||
if (this.beanFactory instanceof AbstractBeanFactory) {
|
||||
this.adviceMonitor = ((AbstractBeanFactory) this.beanFactory).getSingletonMutex();
|
||||
}
|
||||
else {
|
||||
this.adviceMonitor = new Object();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a particular instance of the target advice directly,
|
||||
* avoiding lazy resolution in {@link #getAdvice()}.
|
||||
* @since 3.1
|
||||
*/
|
||||
public void setAdvice(Advice advice) {
|
||||
synchronized (this.adviceMonitor) {
|
||||
this.advice = advice;
|
||||
@@ -80,18 +96,42 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
}
|
||||
|
||||
public Advice getAdvice() {
|
||||
synchronized (this.adviceMonitor) {
|
||||
if (this.advice == null && this.adviceBeanName != null) {
|
||||
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
|
||||
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||
Advice advice = this.advice;
|
||||
if (advice != null || this.adviceBeanName == null) {
|
||||
return advice;
|
||||
}
|
||||
|
||||
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
|
||||
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
|
||||
// Rely on singleton semantics provided by the factory.
|
||||
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||
this.advice = advice;
|
||||
return advice;
|
||||
}
|
||||
else {
|
||||
// No singleton guarantees from the factory -> let's lock locally but
|
||||
// reuse the factory's singleton lock, just in case a lazy dependency
|
||||
// of our advice bean happens to trigger the singleton lock implicitly...
|
||||
synchronized (this.adviceMonitor) {
|
||||
if (this.advice == null) {
|
||||
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||
}
|
||||
return this.advice;
|
||||
}
|
||||
return this.advice;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + ": advice bean '" + getAdviceBeanName() + "'";
|
||||
StringBuilder sb = new StringBuilder(getClass().getName());
|
||||
sb.append(": advice ");
|
||||
if (this.adviceBeanName != null) {
|
||||
sb.append("bean '").append(this.adviceBeanName).append("'");
|
||||
}
|
||||
else {
|
||||
sb.append(this.advice);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +144,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
ois.defaultReadObject();
|
||||
|
||||
// Initialize transient fields.
|
||||
this.adviceMonitor = new Object();
|
||||
resetAdviceMonitor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-8
@@ -1,6 +1,5 @@
|
||||
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -29,23 +28,23 @@ public class NopInterceptor implements MethodInterceptor {
|
||||
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* @see org.aopalliance.intercept.MethodInterceptor#invoke(MethodInvocation)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
increment();
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
protected void increment() {
|
||||
this.count++;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
protected void increment() {
|
||||
++count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof NopInterceptor)) {
|
||||
return false;
|
||||
@@ -56,4 +55,9 @@ public class NopInterceptor implements MethodInterceptor {
|
||||
return this.count == ((NopInterceptor) other).count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return NopInterceptor.class.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -29,17 +29,9 @@ import org.springframework.util.ObjectUtils;
|
||||
public class SerializablePerson implements Person, Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
@Override
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
@@ -51,6 +43,16 @@ public class SerializablePerson implements Person, Serializable {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object echo(Object o) throws Throwable {
|
||||
if (o instanceof Throwable) {
|
||||
@@ -59,6 +61,8 @@ public class SerializablePerson implements Person, Serializable {
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof SerializablePerson)) {
|
||||
return false;
|
||||
@@ -67,4 +71,9 @@ public class SerializablePerson implements Person, Serializable {
|
||||
return p.age == age && ObjectUtils.nullSafeEquals(name, p.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return SerializablePerson.class.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -28,9 +28,9 @@ import org.springframework.context.annotation.Role;
|
||||
* annotated with @{@link org.springframework.beans.factory.annotation.Configurable
|
||||
* Configurable}.
|
||||
*
|
||||
* <p>This configuration class is automatically imported when using the @{@link
|
||||
* EnableSpringConfigured} annotation. See {@code @EnableSpringConfigured} Javadoc for
|
||||
* complete usage details.
|
||||
* <p>This configuration class is automatically imported when using the
|
||||
* @{@link EnableSpringConfigured} annotation. See {@code @EnableSpringConfigured}'s
|
||||
* javadoc for complete usage details.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
@@ -42,9 +42,10 @@ public class SpringConfiguredConfiguration {
|
||||
public static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME =
|
||||
"org.springframework.context.config.internalBeanConfigurerAspect";
|
||||
|
||||
@Bean(name=BEAN_CONFIGURER_ASPECT_BEAN_NAME)
|
||||
@Bean(name = BEAN_CONFIGURER_ASPECT_BEAN_NAME)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public AnnotationBeanConfigurerAspect beanConfigurerAspect() {
|
||||
return AnnotationBeanConfigurerAspect.aspectOf();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -105,7 +105,7 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
|
||||
|
||||
// Redefined with public visibility.
|
||||
@Override
|
||||
public Class getPropertyType(String propertyPath) {
|
||||
public Class<?> getPropertyType(String propertyPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
|
||||
* @throws InvalidPropertyException if there is no such property or
|
||||
* if the property isn't writable
|
||||
* @throws PropertyAccessException if the property was valid but the
|
||||
* accessor method failed or a type mismatch occured
|
||||
* accessor method failed or a type mismatch occurred
|
||||
*/
|
||||
public abstract void setPropertyValue(String propertyName, Object value) throws BeansException;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -379,13 +379,28 @@ public abstract class BeanUtils {
|
||||
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
|
||||
* with the method either being the read method or the write method for
|
||||
* that bean property.
|
||||
* @param method the method to find a corresponding PropertyDescriptor for
|
||||
* @param method the method to find a corresponding PropertyDescriptor for,
|
||||
* introspecting its declaring class
|
||||
* @return the corresponding PropertyDescriptor, or {@code null} if none
|
||||
* @throws BeansException if PropertyDescriptor lookup fails
|
||||
*/
|
||||
public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException {
|
||||
return findPropertyForMethod(method, method.getDeclaringClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
|
||||
* with the method either being the read method or the write method for
|
||||
* that bean property.
|
||||
* @param method the method to find a corresponding PropertyDescriptor for
|
||||
* @param clazz the (most specific) class to introspect for descriptors
|
||||
* @return the corresponding PropertyDescriptor, or {@code null} if none
|
||||
* @throws BeansException if PropertyDescriptor lookup fails
|
||||
* @since 3.2.13
|
||||
*/
|
||||
public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException {
|
||||
Assert.notNull(method, "Method must not be null");
|
||||
PropertyDescriptor[] pds = getPropertyDescriptors(method.getDeclaringClass());
|
||||
PropertyDescriptor[] pds = getPropertyDescriptors(clazz);
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
if (method.equals(pd.getReadMethod()) || method.equals(pd.getWriteMethod())) {
|
||||
return pd;
|
||||
@@ -591,11 +606,11 @@ public abstract class BeanUtils {
|
||||
actualEditable = editable;
|
||||
}
|
||||
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
|
||||
List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
|
||||
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
|
||||
|
||||
for (PropertyDescriptor targetPd : targetPds) {
|
||||
Method writeMethod = targetPd.getWriteMethod();
|
||||
if (writeMethod != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
|
||||
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
|
||||
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
|
||||
if (sourcePd != null) {
|
||||
Method readMethod = sourcePd.getReadMethod();
|
||||
|
||||
@@ -1025,7 +1025,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
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 [" + pv.getValue() + "]");
|
||||
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,6 +35,9 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import static org.springframework.beans.PropertyDescriptorUtils.*;
|
||||
|
||||
/**
|
||||
@@ -73,6 +76,8 @@ import static org.springframework.beans.PropertyDescriptorUtils.*;
|
||||
*/
|
||||
class ExtendedBeanInfo implements BeanInfo {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ExtendedBeanInfo.class);
|
||||
|
||||
private final BeanInfo delegate;
|
||||
|
||||
private final Set<PropertyDescriptor> propertyDescriptors =
|
||||
@@ -94,14 +99,30 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException {
|
||||
this.delegate = delegate;
|
||||
for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) {
|
||||
this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
|
||||
new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
|
||||
new SimplePropertyDescriptor(pd));
|
||||
try {
|
||||
this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
|
||||
new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
|
||||
new SimplePropertyDescriptor(pd));
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
// Probably simply a method that wasn't meant to follow the JavaBeans pattern...
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring invalid bean property '" + pd.getName() + "': " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodDescriptor[] methodDescriptors = delegate.getMethodDescriptors();
|
||||
if (methodDescriptors != null) {
|
||||
for (Method method : findCandidateWriteMethods(methodDescriptors)) {
|
||||
handleCandidateWriteMethod(method);
|
||||
try {
|
||||
handleCandidateWriteMethod(method);
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
// We're only trying to find candidates, can easily ignore extra ones here...
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring candidate write method [" + method + "]: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,15 +151,15 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
String methodName = method.getName();
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
int nParams = parameterTypes.length;
|
||||
return methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
|
||||
return (methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
|
||||
(!void.class.isAssignableFrom(method.getReturnType()) || Modifier.isStatic(method.getModifiers())) &&
|
||||
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class)));
|
||||
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class))));
|
||||
}
|
||||
|
||||
private void handleCandidateWriteMethod(Method method) throws IntrospectionException {
|
||||
int nParams = method.getParameterTypes().length;
|
||||
String propertyName = propertyNameFor(method);
|
||||
Class<?> propertyType = method.getParameterTypes()[nParams-1];
|
||||
Class<?> propertyType = method.getParameterTypes()[nParams - 1];
|
||||
PropertyDescriptor existingPd = findExistingPropertyDescriptor(propertyName, propertyType);
|
||||
if (nParams == 1) {
|
||||
if (existingPd == null) {
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -88,7 +88,8 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
Set<Method> ambiguousCandidates = new HashSet<Method>();
|
||||
for (Method method : beanClass.getMethods()) {
|
||||
if (method.getName().equals(writeMethodToUse.getName()) &&
|
||||
!method.equals(writeMethodToUse) && !method.isBridge()) {
|
||||
!method.equals(writeMethodToUse) && !method.isBridge() &&
|
||||
method.getParameterTypes().length == writeMethodToUse.getParameterTypes().length) {
|
||||
ambiguousCandidates.add(method);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -86,7 +86,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
// There is no replacement of existing property values.
|
||||
if (original != null) {
|
||||
this.propertyValueList = new ArrayList<PropertyValue>(original.size());
|
||||
for (Map.Entry entry : original.entrySet()) {
|
||||
for (Map.Entry<?, ?> entry : original.entrySet()) {
|
||||
this.propertyValueList.add(new PropertyValue(entry.getKey().toString(), entry.getValue()));
|
||||
}
|
||||
}
|
||||
@@ -303,6 +303,16 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
this.processedProperties.add(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the "processed" registration of the given property, if any.
|
||||
* @since 3.2.13
|
||||
*/
|
||||
public void clearProcessedProperty(String propertyName) {
|
||||
if (this.processedProperties != null) {
|
||||
this.processedProperties.remove(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this holder as containing converted values only
|
||||
* (i.e. no runtime resolution needed anymore).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -86,7 +86,7 @@ public interface PropertyAccessor {
|
||||
* @throws PropertyAccessException if the property was valid but the
|
||||
* accessor method failed
|
||||
*/
|
||||
Class getPropertyType(String propertyName) throws BeansException;
|
||||
Class<?> getPropertyType(String propertyName) throws BeansException;
|
||||
|
||||
/**
|
||||
* Return a type descriptor for the specified property:
|
||||
@@ -120,7 +120,7 @@ public interface PropertyAccessor {
|
||||
* @throws InvalidPropertyException if there is no such property or
|
||||
* if the property isn't writable
|
||||
* @throws PropertyAccessException if the property was valid but the
|
||||
* accessor method failed or a type mismatch occured
|
||||
* accessor method failed or a type mismatch occurred
|
||||
*/
|
||||
void setPropertyValue(String propertyName, Object value) throws BeansException;
|
||||
|
||||
@@ -130,7 +130,7 @@ public interface PropertyAccessor {
|
||||
* @throws InvalidPropertyException if there is no such property or
|
||||
* if the property isn't writable
|
||||
* @throws PropertyAccessException if the property was valid but the
|
||||
* accessor method failed or a type mismatch occured
|
||||
* accessor method failed or a type mismatch occurred
|
||||
*/
|
||||
void setPropertyValue(PropertyValue pv) throws BeansException;
|
||||
|
||||
@@ -144,7 +144,7 @@ public interface PropertyAccessor {
|
||||
* @throws InvalidPropertyException if there is no such property or
|
||||
* if the property isn't writable
|
||||
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions
|
||||
* occured for specific properties during the batch update. This exception bundles
|
||||
* occurred for specific properties during the batch update. This exception bundles
|
||||
* all individual PropertyAccessExceptions. All other properties will have been
|
||||
* successfully updated.
|
||||
*/
|
||||
@@ -164,7 +164,7 @@ public interface PropertyAccessor {
|
||||
* @throws InvalidPropertyException if there is no such property or
|
||||
* if the property isn't writable
|
||||
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions
|
||||
* occured for specific properties during the batch update. This exception bundles
|
||||
* occurred for specific properties during the batch update. This exception bundles
|
||||
* all individual PropertyAccessExceptions. All other properties will have been
|
||||
* successfully updated.
|
||||
* @see #setPropertyValues(PropertyValues, boolean, boolean)
|
||||
@@ -185,7 +185,7 @@ public interface PropertyAccessor {
|
||||
* @throws InvalidPropertyException if there is no such property or
|
||||
* if the property isn't writable
|
||||
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions
|
||||
* occured for specific properties during the batch update. This exception bundles
|
||||
* occurred for specific properties during the batch update. This exception bundles
|
||||
* all individual PropertyAccessExceptions. All other properties will have been
|
||||
* successfully updated.
|
||||
* @see #setPropertyValues(PropertyValues, boolean, boolean)
|
||||
@@ -208,7 +208,7 @@ public interface PropertyAccessor {
|
||||
* @throws InvalidPropertyException if there is no such property or
|
||||
* if the property isn't writable
|
||||
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions
|
||||
* occured for specific properties during the batch update. This exception bundles
|
||||
* occurred for specific properties during the batch update. This exception bundles
|
||||
* all individual PropertyAccessExceptions. All other properties will have been
|
||||
* successfully updated.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ public class PropertyBatchUpdateException extends BeansException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Class exType) {
|
||||
public boolean contains(Class<?> exType) {
|
||||
if (exType == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -46,8 +46,6 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
|
||||
|
||||
private final Object value;
|
||||
|
||||
private Object source;
|
||||
|
||||
private boolean optional = false;
|
||||
|
||||
private boolean converted = false;
|
||||
@@ -82,13 +80,13 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
|
||||
Assert.notNull(original, "Original must not be null");
|
||||
this.name = original.getName();
|
||||
this.value = original.getValue();
|
||||
this.source = original.getSource();
|
||||
this.optional = original.isOptional();
|
||||
this.converted = original.converted;
|
||||
this.convertedValue = original.convertedValue;
|
||||
this.conversionNecessary = original.conversionNecessary;
|
||||
this.resolvedTokens = original.resolvedTokens;
|
||||
this.resolvedDescriptor = original.resolvedDescriptor;
|
||||
setSource(original.getSource());
|
||||
copyAttributesFrom(original);
|
||||
}
|
||||
|
||||
@@ -102,11 +100,11 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
|
||||
Assert.notNull(original, "Original must not be null");
|
||||
this.name = original.getName();
|
||||
this.value = newValue;
|
||||
this.source = original;
|
||||
this.optional = original.isOptional();
|
||||
this.conversionNecessary = original.conversionNecessary;
|
||||
this.resolvedTokens = original.resolvedTokens;
|
||||
this.resolvedDescriptor = original.resolvedDescriptor;
|
||||
setSource(original);
|
||||
copyAttributesFrom(original);
|
||||
}
|
||||
|
||||
@@ -135,16 +133,28 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
|
||||
*/
|
||||
public PropertyValue getOriginalPropertyValue() {
|
||||
PropertyValue original = this;
|
||||
while (original.source instanceof PropertyValue && original.source != original) {
|
||||
original = (PropertyValue) original.source;
|
||||
Object source = getSource();
|
||||
while (source instanceof PropertyValue && source != original) {
|
||||
original = (PropertyValue) source;
|
||||
source = original.getSource();
|
||||
}
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this is an optional value, that is, to be ignored
|
||||
* when no corresponding property exists on the target class.
|
||||
* @since 3.0
|
||||
*/
|
||||
public void setOptional(boolean optional) {
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this is an optional value, that is, to be ignored
|
||||
* when no corresponding property exists on the target class.
|
||||
* @since 3.0
|
||||
*/
|
||||
public boolean isOptional() {
|
||||
return this.optional;
|
||||
}
|
||||
@@ -186,7 +196,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
|
||||
PropertyValue otherPv = (PropertyValue) other;
|
||||
return (this.name.equals(otherPv.name) &&
|
||||
ObjectUtils.nullSafeEquals(this.value, otherPv.value) &&
|
||||
ObjectUtils.nullSafeEquals(this.source, otherPv.source));
|
||||
ObjectUtils.nullSafeEquals(getSource(), otherPv.getSource()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -123,7 +123,7 @@ public class BeanCreationException extends FatalBeanException {
|
||||
|
||||
/**
|
||||
* Add a related cause to this bean creation exception,
|
||||
* not being a direct cause of the failure but having occured
|
||||
* not being a direct cause of the failure but having occurred
|
||||
* earlier in the creation of the same bean instance.
|
||||
* @param ex the related cause to add
|
||||
*/
|
||||
@@ -185,7 +185,7 @@ public class BeanCreationException extends FatalBeanException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Class exClass) {
|
||||
public boolean contains(Class<?> exClass) {
|
||||
if (super.contains(exClass)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -66,24 +66,27 @@ import org.springframework.beans.BeansException;
|
||||
* 1. BeanNameAware's {@code setBeanName}<br>
|
||||
* 2. BeanClassLoaderAware's {@code setBeanClassLoader}<br>
|
||||
* 3. BeanFactoryAware's {@code setBeanFactory}<br>
|
||||
* 4. ResourceLoaderAware's {@code setResourceLoader}
|
||||
* 4. EnvironmentAware's {@code setEnvironment}
|
||||
* 5. EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
|
||||
* 6. ResourceLoaderAware's {@code setResourceLoader}
|
||||
* (only applicable when running in an application context)<br>
|
||||
* 5. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
|
||||
* 7. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
|
||||
* (only applicable when running in an application context)<br>
|
||||
* 6. MessageSourceAware's {@code setMessageSource}
|
||||
* 8. MessageSourceAware's {@code setMessageSource}
|
||||
* (only applicable when running in an application context)<br>
|
||||
* 7. ApplicationContextAware's {@code setApplicationContext}
|
||||
* 9. ApplicationContextAware's {@code setApplicationContext}
|
||||
* (only applicable when running in an application context)<br>
|
||||
* 8. ServletContextAware's {@code setServletContext}
|
||||
* 10. ServletContextAware's {@code setServletContext}
|
||||
* (only applicable when running in a web application context)<br>
|
||||
* 9. {@code postProcessBeforeInitialization} methods of BeanPostProcessors<br>
|
||||
* 10. InitializingBean's {@code afterPropertiesSet}<br>
|
||||
* 11. a custom init-method definition<br>
|
||||
* 12. {@code postProcessAfterInitialization} methods of BeanPostProcessors
|
||||
* 11. {@code postProcessBeforeInitialization} methods of BeanPostProcessors<br>
|
||||
* 12. InitializingBean's {@code afterPropertiesSet}<br>
|
||||
* 13. a custom init-method definition<br>
|
||||
* 14. {@code postProcessAfterInitialization} methods of BeanPostProcessors
|
||||
*
|
||||
* <p>On shutdown of a bean factory, the following lifecycle methods apply:<br>
|
||||
* 1. DisposableBean's {@code destroy}<br>
|
||||
* 2. a custom destroy-method definition
|
||||
* 1. {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
|
||||
* 2. DisposableBean's {@code destroy}<br>
|
||||
* 3. a custom destroy-method definition
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
@@ -114,6 +117,7 @@ public interface BeanFactory {
|
||||
*/
|
||||
String FACTORY_BEAN_PREFIX = "&";
|
||||
|
||||
|
||||
/**
|
||||
* Return an instance, which may be shared or independent, of the specified bean.
|
||||
* <p>This method allows a Spring BeanFactory to be used as a replacement for the
|
||||
@@ -151,15 +155,16 @@ public interface BeanFactory {
|
||||
|
||||
/**
|
||||
* Return the bean instance that uniquely matches the given object type, if any.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass.
|
||||
* {@code null} is disallowed.
|
||||
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
|
||||
* but may also be translated into a conventional by-name lookup based on the name
|
||||
* of the given type. For more extensive retrieval operations across sets of beans,
|
||||
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass.
|
||||
* {@code null} is disallowed.
|
||||
* @return an instance of the single bean matching the required type
|
||||
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
* @throws BeansException if the bean could not be created
|
||||
* @since 3.0
|
||||
* @see ListableBeanFactory
|
||||
*/
|
||||
@@ -170,7 +175,7 @@ public interface BeanFactory {
|
||||
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
|
||||
* overriding the specified default arguments (if any) in the bean definition.
|
||||
* @param name the name of the bean to retrieve
|
||||
* @param args arguments to use if creating a prototype using explicit arguments
|
||||
* @param args arguments to use when creating a prototype using explicit arguments
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||
* @throws BeanDefinitionStoreException if arguments have been given but
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* 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.
|
||||
@@ -17,10 +17,10 @@
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
/**
|
||||
* Counterpart of BeanNameAware. Returns the bean name of an object.
|
||||
* Counterpart of {@link BeanNameAware}. Returns the bean name of an object.
|
||||
*
|
||||
* <p>This interface can be introduced to avoid a brittle dependence
|
||||
* on bean name in objects used with Spring IoC and Spring AOP.
|
||||
* <p>This interface can be introduced to avoid a brittle dependence on
|
||||
* bean name in objects used with Spring IoC and Spring AOP.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
@@ -29,7 +29,7 @@ package org.springframework.beans.factory;
|
||||
public interface NamedBean {
|
||||
|
||||
/**
|
||||
* Return the name of this bean in a Spring bean factory.
|
||||
* Return the name of this bean in a Spring bean factory, if known.
|
||||
*/
|
||||
String getBeanName();
|
||||
|
||||
|
||||
+30
-25
@@ -215,7 +215,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
if (beanType != null) {
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType);
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
|
||||
metadata.checkConfigMembers(beanDefinition);
|
||||
}
|
||||
}
|
||||
@@ -233,8 +233,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
Constructor<?> requiredConstructor = null;
|
||||
Constructor<?> defaultConstructor = null;
|
||||
for (Constructor<?> candidate : rawCandidates) {
|
||||
Annotation annotation = findAutowiredAnnotation(candidate);
|
||||
if (annotation != null) {
|
||||
Annotation ann = findAutowiredAnnotation(candidate);
|
||||
if (ann != null) {
|
||||
if (requiredConstructor != null) {
|
||||
throw new BeanCreationException(beanName,
|
||||
"Invalid autowire-marked constructor: " + candidate +
|
||||
@@ -245,7 +245,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
throw new IllegalStateException(
|
||||
"Autowired annotation requires at least one argument: " + candidate);
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
boolean required = determineRequiredStatus(ann);
|
||||
if (required) {
|
||||
if (!candidates.isEmpty()) {
|
||||
throw new BeanCreationException(beanName,
|
||||
@@ -290,7 +290,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());
|
||||
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
|
||||
try {
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
@@ -308,7 +308,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
*/
|
||||
public void processInjection(Object bean) throws BeansException {
|
||||
Class<?> clazz = bean.getClass();
|
||||
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz);
|
||||
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
|
||||
try {
|
||||
metadata.inject(bean, null, null);
|
||||
}
|
||||
@@ -318,15 +318,18 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
}
|
||||
|
||||
|
||||
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz) {
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
|
||||
// Fall back to class name as cache key, for backwards compatibility with custom callers.
|
||||
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
|
||||
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
|
||||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(cacheKey);
|
||||
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
|
||||
if (metadata != null) {
|
||||
metadata.clear(pvs);
|
||||
}
|
||||
metadata = buildAutowiringMetadata(clazz);
|
||||
this.injectionMetadataCache.put(cacheKey, metadata);
|
||||
}
|
||||
@@ -342,23 +345,25 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
do {
|
||||
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
for (Field field : targetClass.getDeclaredFields()) {
|
||||
Annotation annotation = findAutowiredAnnotation(field);
|
||||
if (annotation != null) {
|
||||
Annotation ann = findAutowiredAnnotation(field);
|
||||
if (ann != null) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation is not supported on static fields: " + field);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
boolean required = determineRequiredStatus(ann);
|
||||
currElements.add(new AutowiredFieldElement(field, required));
|
||||
}
|
||||
}
|
||||
for (Method method : targetClass.getDeclaredMethods()) {
|
||||
Annotation ann = null;
|
||||
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
|
||||
Annotation annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
|
||||
findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method);
|
||||
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
|
||||
ann = findAutowiredAnnotation(bridgedMethod);
|
||||
}
|
||||
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation is not supported on static methods: " + method);
|
||||
@@ -370,8 +375,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
|
||||
}
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
boolean required = determineRequiredStatus(ann);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
|
||||
currElements.add(new AutowiredMethodElement(method, required, pd));
|
||||
}
|
||||
}
|
||||
@@ -385,9 +390,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
|
||||
private Annotation findAutowiredAnnotation(AccessibleObject ao) {
|
||||
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
|
||||
Annotation annotation = AnnotationUtils.getAnnotation(ao, type);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
Annotation ann = AnnotationUtils.getAnnotation(ao, type);
|
||||
if (ann != null) {
|
||||
return ann;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -412,21 +417,21 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
* <p>A 'required' dependency means that autowiring should fail when no beans
|
||||
* are found. Otherwise, the autowiring process will simply bypass the field
|
||||
* or method when no beans are found.
|
||||
* @param annotation the Autowired annotation
|
||||
* @param ann the Autowired annotation
|
||||
* @return whether the annotation indicates that a dependency is required
|
||||
*/
|
||||
protected boolean determineRequiredStatus(Annotation annotation) {
|
||||
protected boolean determineRequiredStatus(Annotation ann) {
|
||||
try {
|
||||
Method method = ReflectionUtils.findMethod(annotation.annotationType(), this.requiredParameterName);
|
||||
Method method = ReflectionUtils.findMethod(ann.annotationType(), this.requiredParameterName);
|
||||
if (method == null) {
|
||||
// annotations like @Inject and @Value don't have a method (attribute) named "required"
|
||||
// Annotations like @Inject and @Value don't have a method (attribute) named "required"
|
||||
// -> default to required status
|
||||
return true;
|
||||
}
|
||||
return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, annotation));
|
||||
return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, ann));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// an exception was thrown during reflective invocation of the required attribute
|
||||
// An exception was thrown during reflective invocation of the required attribute
|
||||
// -> default to required status
|
||||
return true;
|
||||
}
|
||||
|
||||
+6
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.beans.factory.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
@@ -77,19 +76,19 @@ public class BeanFactoryAnnotationUtils {
|
||||
* @throws NoSuchBeanDefinitionException if no matching bean of type {@code T} found
|
||||
*/
|
||||
private static <T> T qualifiedBeanOfType(ConfigurableListableBeanFactory bf, Class<T> beanType, String qualifier) {
|
||||
Map<String, T> candidateBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, beanType);
|
||||
T matchingBean = null;
|
||||
for (String beanName : candidateBeans.keySet()) {
|
||||
String[] candidateBeans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(bf, beanType);
|
||||
String matchingBean = null;
|
||||
for (String beanName : candidateBeans) {
|
||||
if (isQualifierMatch(qualifier, beanName, bf)) {
|
||||
if (matchingBean != null) {
|
||||
throw new NoSuchBeanDefinitionException(qualifier, "No unique " + beanType.getSimpleName() +
|
||||
" bean found for qualifier '" + qualifier + "'");
|
||||
}
|
||||
matchingBean = candidateBeans.get(beanName);
|
||||
matchingBean = beanName;
|
||||
}
|
||||
}
|
||||
if (matchingBean != null) {
|
||||
return matchingBean;
|
||||
return bf.getBean(matchingBean, beanType);
|
||||
}
|
||||
else if (bf.containsBean(qualifier)) {
|
||||
// Fallback: target bean at least found by bean name - probably a manually registered singleton.
|
||||
|
||||
+32
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
*/
|
||||
public class InjectionMetadata {
|
||||
|
||||
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||
|
||||
private final Class<?> targetClass;
|
||||
|
||||
@@ -60,6 +60,7 @@ public class InjectionMetadata {
|
||||
this.injectedElements = elements;
|
||||
}
|
||||
|
||||
|
||||
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
||||
Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
|
||||
for (InjectedElement element : this.injectedElements) {
|
||||
@@ -82,13 +83,26 @@ public class InjectionMetadata {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (InjectedElement element : elementsToIterate) {
|
||||
if (debug) {
|
||||
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
|
||||
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
|
||||
}
|
||||
element.inject(target, beanName, pvs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.13
|
||||
*/
|
||||
public void clear(PropertyValues pvs) {
|
||||
Collection<InjectedElement> elementsToIterate =
|
||||
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
|
||||
if (!elementsToIterate.isEmpty()) {
|
||||
for (InjectedElement element : elementsToIterate) {
|
||||
element.clearPropertySkipping(pvs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean needsRefresh(InjectionMetadata metadata, Class<?> clazz) {
|
||||
return (metadata == null || !metadata.targetClass.equals(clazz));
|
||||
@@ -170,7 +184,7 @@ public class InjectionMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this injector's property needs to be skipped due to
|
||||
* Check whether this injector's property needs to be skipped due to
|
||||
* an explicit property value having been specified. Also marks the
|
||||
* affected property as processed for other processors to ignore it.
|
||||
*/
|
||||
@@ -201,6 +215,20 @@ public class InjectionMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.13
|
||||
*/
|
||||
protected void clearPropertySkipping(PropertyValues pvs) {
|
||||
if (pvs == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (pvs) {
|
||||
if (Boolean.FALSE.equals(this.skip) && this.pd != null && pvs instanceof MutablePropertyValues) {
|
||||
((MutablePropertyValues) pvs).clearProcessedProperty(this.pd.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Either this or {@link #inject} needs to be overridden.
|
||||
*/
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -153,7 +153,7 @@ public abstract class AbstractFactoryBean<T>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private T getEarlySingletonInstance() throws Exception {
|
||||
Class[] ifcs = getEarlySingletonInterfaces();
|
||||
Class<?>[] ifcs = getEarlySingletonInterfaces();
|
||||
if (ifcs == null) {
|
||||
throw new FactoryBeanNotInitializedException(
|
||||
getClass().getName() + " does not support circular references");
|
||||
@@ -201,7 +201,7 @@ public abstract class AbstractFactoryBean<T>
|
||||
* <p>Invoked on initialization of this FactoryBean in case of
|
||||
* a singleton; else, on each {@link #getObject()} call.
|
||||
* @return the object returned by this factory
|
||||
* @throws Exception if an exception occured during object creation
|
||||
* @throws Exception if an exception occurred during object creation
|
||||
* @see #getObject()
|
||||
*/
|
||||
protected abstract T createInstance() throws Exception;
|
||||
@@ -218,9 +218,9 @@ public abstract class AbstractFactoryBean<T>
|
||||
* or {@code null} to indicate a FactoryBeanNotInitializedException
|
||||
* @see org.springframework.beans.factory.FactoryBeanNotInitializedException
|
||||
*/
|
||||
protected Class[] getEarlySingletonInterfaces() {
|
||||
Class type = getObjectType();
|
||||
return (type != null && type.isInterface() ? new Class[] {type} : null);
|
||||
protected Class<?>[] getEarlySingletonInterfaces() {
|
||||
Class<?> type = getObjectType();
|
||||
return (type != null && type.isInterface() ? new Class<?>[] {type} : null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -114,9 +114,9 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
* <p>Performs full initialization of the bean, including all applicable
|
||||
* {@link BeanPostProcessor BeanPostProcessors}.
|
||||
* <p>Note: This is intended for creating a fresh instance, populating annotated
|
||||
* fields and methods as well as applying all standard bean initialiation callbacks.
|
||||
* fields and methods as well as applying all standard bean initialization callbacks.
|
||||
* It does <i>not</> imply traditional by-name or by-type autowiring of properties;
|
||||
* use {@link #createBean(Class, int, boolean)} for that purposes.
|
||||
* use {@link #createBean(Class, int, boolean)} for those purposes.
|
||||
* @param beanClass the class of the bean to create
|
||||
* @return the new bean instance
|
||||
* @throws BeansException if instantiation or wiring failed
|
||||
@@ -129,7 +129,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||
* <p>Note: This is essentially intended for (re-)populating annotated fields and
|
||||
* methods, either for new instances or for deserialized instances. It does
|
||||
* <i>not</i> imply traditional by-name or by-type autowiring of properties;
|
||||
* use {@link #autowireBeanProperties} for that purposes.
|
||||
* use {@link #autowireBeanProperties} for those purposes.
|
||||
* @param existingBean the existing bean instance
|
||||
* @throws BeansException if wiring failed
|
||||
*/
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -91,7 +91,7 @@ public class PropertiesFactoryBean extends PropertiesLoaderSupport
|
||||
* <p>Invoked on initialization of this FactoryBean in case of a
|
||||
* shared singleton; else, on each {@link #getObject()} call.
|
||||
* @return the object returned by this factory
|
||||
* @throws IOException if an exception occured during properties loading
|
||||
* @throws IOException if an exception occurred during properties loading
|
||||
* @see #mergeProperties()
|
||||
*/
|
||||
protected Properties createProperties() throws IOException {
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -219,8 +219,7 @@ public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport
|
||||
throws BeansException {
|
||||
|
||||
StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props);
|
||||
|
||||
this.doProcessProperties(beanFactoryToProcess, valueResolver);
|
||||
doProcessProperties(beanFactoryToProcess, valueResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+13
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -425,9 +425,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @see #doCreateBean
|
||||
*/
|
||||
@Override
|
||||
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
|
||||
throws BeanCreationException {
|
||||
|
||||
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating instance of bean '" + beanName + "'");
|
||||
}
|
||||
@@ -596,7 +594,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the bean type for the given bean definition which is based on
|
||||
* Determine the target type for the given bean definition which is based on
|
||||
* a factory method. Only called if there is no singleton instance registered
|
||||
* for the target bean already.
|
||||
* <p>This implementation determines the type matching {@link #createBean}'s
|
||||
@@ -606,7 +604,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param mbd the merged bean definition for the bean
|
||||
* @param typesToMatch the types to match in case of internal type matching purposes
|
||||
* (also signals that the returned {@code Class} will never be exposed to application code)
|
||||
* @return the type for the bean if determinable, or {@code null} else
|
||||
* @return the type for the bean if determinable, or {@code null} otherwise
|
||||
* @see #createBean
|
||||
*/
|
||||
protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
|
||||
@@ -745,10 +743,14 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (objectType.value != null) {
|
||||
return objectType.value;
|
||||
}
|
||||
else {
|
||||
// No type found for shortcut FactoryBean instance:
|
||||
// fall back to full creation of the FactoryBean instance.
|
||||
return super.getTypeForFactoryBean(beanName, mbd);
|
||||
}
|
||||
}
|
||||
|
||||
// No type found - fall back to full creation of the FactoryBean instance.
|
||||
return super.getTypeForFactoryBean(beanName, mbd);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -767,7 +769,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
|
||||
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
|
||||
if (exposedObject == null) {
|
||||
return exposedObject;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -782,8 +784,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
/**
|
||||
* Obtain a "shortcut" singleton FactoryBean instance to use for a
|
||||
* {@code getObjectType()} call, without full initialization
|
||||
* of the FactoryBean.
|
||||
* {@code getObjectType()} call, without full initialization of the FactoryBean.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @return the FactoryBean instance, or {@code null} to indicate
|
||||
@@ -824,8 +825,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
/**
|
||||
* Obtain a "shortcut" non-singleton FactoryBean instance to use for a
|
||||
* {@code getObjectType()} call, without full initialization
|
||||
* of the FactoryBean.
|
||||
* {@code getObjectType()} call, without full initialization of the FactoryBean.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @return the FactoryBean instance, or {@code null} to indicate
|
||||
|
||||
+11
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -156,7 +156,7 @@ class ConstructorResolver {
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
|
||||
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
|
||||
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
|
||||
}
|
||||
}
|
||||
AutowireUtils.sortConstructors(candidates);
|
||||
@@ -613,8 +613,8 @@ class ConstructorResolver {
|
||||
String beanName, RootBeanDefinition mbd, BeanWrapper bw,
|
||||
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
|
||||
|
||||
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
|
||||
this.beanFactory.getCustomTypeConverter() : bw);
|
||||
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
|
||||
TypeConverter converter = (customConverter != null ? customConverter : bw);
|
||||
BeanDefinitionValueResolver valueResolver =
|
||||
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
|
||||
|
||||
@@ -670,8 +670,8 @@ class ConstructorResolver {
|
||||
boolean autowiring) throws UnsatisfiedDependencyException {
|
||||
|
||||
String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
|
||||
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
|
||||
this.beanFactory.getCustomTypeConverter() : bw);
|
||||
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
|
||||
TypeConverter converter = (customConverter != null ? customConverter : bw);
|
||||
|
||||
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
|
||||
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
|
||||
@@ -772,12 +772,13 @@ class ConstructorResolver {
|
||||
private Object[] resolvePreparedArguments(
|
||||
String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) {
|
||||
|
||||
Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
|
||||
((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
|
||||
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
|
||||
this.beanFactory.getCustomTypeConverter() : bw);
|
||||
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
|
||||
TypeConverter converter = (customConverter != null ? customConverter : bw);
|
||||
BeanDefinitionValueResolver valueResolver =
|
||||
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
|
||||
Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
|
||||
((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
|
||||
|
||||
Object[] resolvedArgs = new Object[argsToResolve.length];
|
||||
for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
|
||||
Object argValue = argsToResolve[argIndex];
|
||||
|
||||
+5
-3
@@ -509,10 +509,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
public void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) {
|
||||
Assert.notNull(dependencyType, "Type must not be null");
|
||||
Assert.notNull(dependencyType, "Dependency type must not be null");
|
||||
if (autowiredValue != null) {
|
||||
Assert.isTrue((autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue)),
|
||||
"Value [" + autowiredValue + "] does not implement specified type [" + dependencyType.getName() + "]");
|
||||
if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
|
||||
throw new IllegalArgumentException("Value [" + autowiredValue +
|
||||
"] does not implement specified dependency type [" + dependencyType.getName() + "]");
|
||||
}
|
||||
this.resolvableDependencies.put(dependencyType, autowiredValue);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -317,7 +317,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
|
||||
/**
|
||||
* Callback before singleton creation.
|
||||
* <p>Default implementation register the singleton as currently in creation.
|
||||
* <p>The default implementation register the singleton as currently in creation.
|
||||
* @param beanName the name of the singleton about to be created
|
||||
* @see #isSingletonCurrentlyInCreation
|
||||
*/
|
||||
@@ -539,13 +539,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the singleton mutex to subclasses.
|
||||
* Exposes the singleton mutex to subclasses and external collaborators.
|
||||
* <p>Subclasses should synchronize on the given Object if they perform
|
||||
* any sort of extended singleton creation phase. In particular, subclasses
|
||||
* should <i>not</i> have their own mutexes involved in singleton creation,
|
||||
* to avoid the potential for deadlocks in lazy-init situations.
|
||||
*/
|
||||
protected final Object getSingletonMutex() {
|
||||
public final Object getSingletonMutex() {
|
||||
return this.singletonObjects;
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -97,6 +97,7 @@ public class CustomBooleanEditor extends PropertyEditorSupport {
|
||||
this.allowEmpty = allowEmpty;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
String input = (text != null ? text.trim() : null);
|
||||
@@ -104,20 +105,20 @@ public class CustomBooleanEditor extends PropertyEditorSupport {
|
||||
// Treat empty String as null value.
|
||||
setValue(null);
|
||||
}
|
||||
else if (this.trueString != null && input.equalsIgnoreCase(this.trueString)) {
|
||||
else if (this.trueString != null && this.trueString.equalsIgnoreCase(input)) {
|
||||
setValue(Boolean.TRUE);
|
||||
}
|
||||
else if (this.falseString != null && input.equalsIgnoreCase(this.falseString)) {
|
||||
else if (this.falseString != null && this.falseString.equalsIgnoreCase(input)) {
|
||||
setValue(Boolean.FALSE);
|
||||
}
|
||||
else if (this.trueString == null &&
|
||||
(input.equalsIgnoreCase(VALUE_TRUE) || input.equalsIgnoreCase(VALUE_ON) ||
|
||||
input.equalsIgnoreCase(VALUE_YES) || input.equals(VALUE_1))) {
|
||||
(VALUE_TRUE.equalsIgnoreCase(input) || VALUE_ON.equalsIgnoreCase(input) ||
|
||||
VALUE_YES.equalsIgnoreCase(input) || VALUE_1.equals(input))) {
|
||||
setValue(Boolean.TRUE);
|
||||
}
|
||||
else if (this.falseString == null &&
|
||||
(input.equalsIgnoreCase(VALUE_FALSE) || input.equalsIgnoreCase(VALUE_OFF) ||
|
||||
input.equalsIgnoreCase(VALUE_NO) || input.equals(VALUE_0))) {
|
||||
(VALUE_FALSE.equalsIgnoreCase(input) || VALUE_OFF.equalsIgnoreCase(input) ||
|
||||
VALUE_NO.equalsIgnoreCase(input) || VALUE_0.equals(input))) {
|
||||
setValue(Boolean.FALSE);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -917,6 +917,15 @@ public class ExtendedBeanInfoTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // SPR-12434
|
||||
public void shouldDetectValidPropertiesAndIgnoreInvalidProperties() throws IntrospectionException {
|
||||
BeanInfo bi = new ExtendedBeanInfo(Introspector.getBeanInfo(java.awt.Window.class));
|
||||
assertThat(hasReadMethodForProperty(bi, "locationByPlatform"), is(true));
|
||||
assertThat(hasWriteMethodForProperty(bi, "locationByPlatform"), is(true));
|
||||
assertThat(hasIndexedReadMethodForProperty(bi, "locationByPlatform"), is(false));
|
||||
assertThat(hasIndexedWriteMethodForProperty(bi, "locationByPlatform"), is(false));
|
||||
}
|
||||
|
||||
|
||||
interface Spr9453<T> {
|
||||
|
||||
|
||||
+32
-38
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -16,18 +16,13 @@
|
||||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.tests.TestResourceUtils.qualifiedResource;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.StaticListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
@@ -39,6 +34,8 @@ import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.factory.DummyFactory;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.tests.TestResourceUtils.*;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
@@ -54,16 +51,16 @@ public final class BeanFactoryUtilsTests {
|
||||
private static final Resource LEAF_CONTEXT = qualifiedResource(CLASS, "leaf.xml");
|
||||
private static final Resource DEPENDENT_BEANS_CONTEXT = qualifiedResource(CLASS, "dependentBeans.xml");
|
||||
|
||||
private ConfigurableListableBeanFactory listableBeanFactory;
|
||||
private DefaultListableBeanFactory listableBeanFactory;
|
||||
|
||||
private DefaultListableBeanFactory dependentBeansFactory;
|
||||
|
||||
private ConfigurableListableBeanFactory dependentBeansBF;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Interesting hierarchical factory to test counts.
|
||||
// Slow to read so we cache it.
|
||||
|
||||
|
||||
DefaultListableBeanFactory grandParent = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(grandParent).loadBeanDefinitions(ROOT_CONTEXT);
|
||||
DefaultListableBeanFactory parent = new DefaultListableBeanFactory(grandParent);
|
||||
@@ -71,12 +68,13 @@ public final class BeanFactoryUtilsTests {
|
||||
DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
|
||||
new XmlBeanDefinitionReader(child).loadBeanDefinitions(LEAF_CONTEXT);
|
||||
|
||||
this.dependentBeansBF = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader((BeanDefinitionRegistry) this.dependentBeansBF).loadBeanDefinitions(DEPENDENT_BEANS_CONTEXT);
|
||||
dependentBeansBF.preInstantiateSingletons();
|
||||
this.dependentBeansFactory = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(this.dependentBeansFactory).loadBeanDefinitions(DEPENDENT_BEANS_CONTEXT);
|
||||
dependentBeansFactory.preInstantiateSingletons();
|
||||
this.listableBeanFactory = child;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHierarchicalCountBeansWithNonHierarchicalFactory() {
|
||||
StaticListableBeanFactory lbf = new StaticListableBeanFactory();
|
||||
@@ -93,22 +91,21 @@ public final class BeanFactoryUtilsTests {
|
||||
// Leaf count
|
||||
assertTrue(this.listableBeanFactory.getBeanDefinitionCount() == 1);
|
||||
// Count minus duplicate
|
||||
assertTrue("Should count 7 beans, not "
|
||||
+ BeanFactoryUtils.countBeansIncludingAncestors(this.listableBeanFactory),
|
||||
BeanFactoryUtils.countBeansIncludingAncestors(this.listableBeanFactory) == 7);
|
||||
assertTrue("Should count 7 beans, not " + BeanFactoryUtils.countBeansIncludingAncestors(this.listableBeanFactory),
|
||||
BeanFactoryUtils.countBeansIncludingAncestors(this.listableBeanFactory) == 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalNamesWithNoMatch() throws Exception {
|
||||
List<String> names = Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory,
|
||||
NoOp.class));
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, NoOp.class));
|
||||
assertEquals(0, names.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchicalNamesWithMatchOnlyInRoot() throws Exception {
|
||||
List<String> names = Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory,
|
||||
IndexedTestBean.class));
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, IndexedTestBean.class));
|
||||
assertEquals(1, names.size());
|
||||
assertTrue(names.contains("indexedBean"));
|
||||
// Distinguish from default ListableBeanFactory behavior
|
||||
@@ -117,8 +114,8 @@ public final class BeanFactoryUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testGetBeanNamesForTypeWithOverride() throws Exception {
|
||||
List<String> names = Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory,
|
||||
ITestBean.class));
|
||||
List<String> names = Arrays.asList(
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class));
|
||||
// includes 2 TestBeans from FactoryBeans (DummyFactory definitions)
|
||||
assertEquals(4, names.size());
|
||||
assertTrue(names.contains("test"));
|
||||
@@ -131,7 +128,7 @@ public final class BeanFactoryUtilsTests {
|
||||
public void testNoBeansOfType() {
|
||||
StaticListableBeanFactory lbf = new StaticListableBeanFactory();
|
||||
lbf.addBean("foo", new Object());
|
||||
Map<?, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, false);
|
||||
Map<String, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, false);
|
||||
assertTrue(beans.isEmpty());
|
||||
}
|
||||
|
||||
@@ -148,7 +145,7 @@ public final class BeanFactoryUtilsTests {
|
||||
lbf.addBean("t3", t3);
|
||||
lbf.addBean("t4", t4);
|
||||
|
||||
Map<?, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, false);
|
||||
Map<String, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, false);
|
||||
assertEquals(2, beans.size());
|
||||
assertEquals(t1, beans.get("t1"));
|
||||
assertEquals(t2, beans.get("t2"));
|
||||
@@ -192,8 +189,8 @@ public final class BeanFactoryUtilsTests {
|
||||
this.listableBeanFactory.registerSingleton("t3", t3);
|
||||
this.listableBeanFactory.registerSingleton("t4", t4);
|
||||
|
||||
Map<?, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true,
|
||||
false);
|
||||
Map<String, ?> beans =
|
||||
BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true, false);
|
||||
assertEquals(6, beans.size());
|
||||
assertEquals(test3, beans.get("test3"));
|
||||
assertEquals(test, beans.get("test"));
|
||||
@@ -201,12 +198,9 @@ public final class BeanFactoryUtilsTests {
|
||||
assertEquals(t2, beans.get("t2"));
|
||||
assertEquals(t3.getObject(), beans.get("t3"));
|
||||
assertTrue(beans.get("t4") instanceof TestBean);
|
||||
// t3 and t4 are found here as of Spring 2.0, since they are
|
||||
// pre-registered
|
||||
// singleton instances, while testFactory1 and testFactory are *not*
|
||||
// found
|
||||
// because they are FactoryBean definitions that haven't been
|
||||
// initialized yet.
|
||||
// t3 and t4 are found here as of Spring 2.0, since they are pre-registered
|
||||
// singleton instances, while testFactory1 and testFactory are *not* found
|
||||
// because they are FactoryBean definitions that haven't been initialized yet.
|
||||
|
||||
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, false, true);
|
||||
Object testFactory1 = this.listableBeanFactory.getBean("testFactory1");
|
||||
@@ -248,8 +242,8 @@ public final class BeanFactoryUtilsTests {
|
||||
Object test3 = this.listableBeanFactory.getBean("test3");
|
||||
Object test = this.listableBeanFactory.getBean("test");
|
||||
|
||||
Map<?, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true,
|
||||
false);
|
||||
Map<String, ?> beans =
|
||||
BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true, false);
|
||||
assertEquals(2, beans.size());
|
||||
assertEquals(test3, beans.get("test3"));
|
||||
assertEquals(test, beans.get("test"));
|
||||
@@ -284,25 +278,25 @@ public final class BeanFactoryUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testADependencies() {
|
||||
String[] deps = this.dependentBeansBF.getDependentBeans("a");
|
||||
String[] deps = this.dependentBeansFactory.getDependentBeans("a");
|
||||
assertTrue(ObjectUtils.isEmpty(deps));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBDependencies() {
|
||||
String[] deps = this.dependentBeansBF.getDependentBeans("b");
|
||||
String[] deps = this.dependentBeansFactory.getDependentBeans("b");
|
||||
assertTrue(Arrays.equals(new String[] { "c" }, deps));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDependencies() {
|
||||
String[] deps = this.dependentBeansBF.getDependentBeans("c");
|
||||
String[] deps = this.dependentBeansFactory.getDependentBeans("c");
|
||||
assertTrue(Arrays.equals(new String[] { "int", "long" }, deps));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntDependencies() {
|
||||
String[] deps = this.dependentBeansBF.getDependentBeans("int");
|
||||
String[] deps = this.dependentBeansFactory.getDependentBeans("int");
|
||||
assertTrue(Arrays.equals(new String[] { "buffer" }, deps));
|
||||
}
|
||||
|
||||
|
||||
+20
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -32,7 +32,6 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -41,6 +40,7 @@ import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.NotWritablePropertyException;
|
||||
@@ -104,9 +104,11 @@ public class DefaultListableBeanFactoryTests {
|
||||
|
||||
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
|
||||
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void testUnreferencedSingletonWasInstantiated() {
|
||||
KnowsIfInstantiated.clearInstantiationRecord();
|
||||
@@ -188,7 +190,7 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrototypeSingletonFactoryBeanIgnoredByNonEagerTypeMatching() {
|
||||
public void testSingletonFactoryBeanIgnoredByNonEagerTypeMatching() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
Properties p = new Properties();
|
||||
p.setProperty("x1.(class)", DummyFactory.class.getName());
|
||||
@@ -1210,8 +1212,8 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
catch (UnsatisfiedDependencyException ex) {
|
||||
// expected
|
||||
assertTrue(ex.getMessage().indexOf("rod") != -1);
|
||||
assertTrue(ex.getMessage().indexOf("rod2") != -1);
|
||||
assertTrue(ex.getMessage().contains("rod"));
|
||||
assertTrue(ex.getMessage().contains("rod2"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1281,13 +1283,13 @@ public class DefaultListableBeanFactoryTests {
|
||||
assertNull(bean.getSpouse());
|
||||
}
|
||||
|
||||
@Test(expected=NoSuchBeanDefinitionException.class)
|
||||
@Test(expected = NoSuchBeanDefinitionException.class)
|
||||
public void testGetBeanByTypeWithNoneFound() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.getBean(TestBean.class);
|
||||
}
|
||||
|
||||
@Test(expected=NoUniqueBeanDefinitionException.class)
|
||||
@Test(expected = NoUniqueBeanDefinitionException.class)
|
||||
public void testGetBeanByTypeWithAmbiguity() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
|
||||
@@ -1391,7 +1393,7 @@ public class DefaultListableBeanFactoryTests {
|
||||
* Java method names. In other words, you can't name a method
|
||||
* {@code set&FactoryBean(...)}.
|
||||
*/
|
||||
@Test(expected=TypeMismatchException.class)
|
||||
@Test(expected = TypeMismatchException.class)
|
||||
public void testAutowireBeanWithFactoryBeanByName() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
|
||||
@@ -1414,8 +1416,8 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
catch (UnsatisfiedDependencyException ex) {
|
||||
// expected
|
||||
assertTrue(ex.getMessage().indexOf("test") != -1);
|
||||
assertTrue(ex.getMessage().indexOf("spouse") != -1);
|
||||
assertTrue(ex.getMessage().contains("test"));
|
||||
assertTrue(ex.getMessage().contains("spouse"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1432,8 +1434,8 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
catch (UnsatisfiedDependencyException ex) {
|
||||
// expected
|
||||
assertTrue(ex.getMessage().indexOf("test") != -1);
|
||||
assertTrue(ex.getMessage().indexOf("spouse") != -1);
|
||||
assertTrue(ex.getMessage().contains("test"));
|
||||
assertTrue(ex.getMessage().contains("spouse"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1681,7 +1683,7 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
assertEquals("test", ex.getBeanName());
|
||||
assertTrue(ex.getMessage().toLowerCase().indexOf("interface") != -1);
|
||||
assertTrue(ex.getMessage().toLowerCase().contains("interface"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1695,7 +1697,7 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
assertEquals("test", ex.getBeanName());
|
||||
assertTrue(ex.getMessage().toLowerCase().indexOf("abstract") != -1);
|
||||
assertTrue(ex.getMessage().toLowerCase().contains("abstract"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2142,13 +2144,13 @@ public class DefaultListableBeanFactoryTests {
|
||||
assertEquals(expectedNameFromArgs, tb2.getName());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testScopingBeanToUnregisteredScopeResultsInAnException() throws Exception {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
|
||||
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
|
||||
beanDefinition.setScope("he put himself so low could hardly look me in the face");
|
||||
|
||||
final DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
factory.registerBeanDefinition("testBean", beanDefinition);
|
||||
factory.getBean("testBean");
|
||||
}
|
||||
@@ -2160,8 +2162,7 @@ public class DefaultListableBeanFactoryTests {
|
||||
RootBeanDefinition parent = new RootBeanDefinition();
|
||||
parent.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
|
||||
AbstractBeanDefinition child = BeanDefinitionBuilder
|
||||
.childBeanDefinition("parent").getBeanDefinition();
|
||||
AbstractBeanDefinition child = BeanDefinitionBuilder.childBeanDefinition("parent").getBeanDefinition();
|
||||
child.setBeanClass(TestBean.class);
|
||||
child.setScope(theChildScope);
|
||||
|
||||
@@ -2676,6 +2677,7 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class KnowsIfInstantiated {
|
||||
|
||||
|
||||
+92
-136
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -16,15 +16,6 @@
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
|
||||
import static org.springframework.tests.TestResourceUtils.qualifiedResource;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -36,8 +27,8 @@ import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
import java.util.prefs.PreferencesFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
@@ -52,19 +43,22 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.tests.sample.beans.IndexedTestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
import static org.springframework.tests.TestResourceUtils.*;
|
||||
|
||||
/**
|
||||
* Unit tests for various {@link PropertyResourceConfigurer} implementations including:
|
||||
* {@link PropertyPlaceholderConfigurer}, {@link PropertyOverrideConfigurer} and
|
||||
* {@link PreferencesPlaceholderConfigurer}.
|
||||
*
|
||||
* @see PropertyPlaceholderConfigurerTests
|
||||
* @since 02.10.2003
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Phillip Webb
|
||||
* @since 02.10.2003
|
||||
* @see PropertyPlaceholderConfigurerTests
|
||||
*/
|
||||
public final class PropertyResourceConfigurerTests {
|
||||
public class PropertyResourceConfigurerTests {
|
||||
|
||||
static {
|
||||
System.setProperty("java.util.prefs.PreferencesFactory", MockPreferencesFactory.class.getName());
|
||||
@@ -75,23 +69,15 @@ public final class PropertyResourceConfigurerTests {
|
||||
private static final Resource XTEST_PROPS = qualifiedResource(CLASS, "xtest.properties"); // does not exist
|
||||
private static final Resource TEST_PROPS_XML = qualifiedResource(CLASS, "test.properties.xml");
|
||||
|
||||
private DefaultListableBeanFactory factory;
|
||||
private final DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
factory = new DefaultListableBeanFactory();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurer() {
|
||||
BeanDefinition def1 = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(TestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def1 = BeanDefinitionBuilder.genericBeanDefinition(TestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb1", def1);
|
||||
|
||||
BeanDefinition def2 = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(TestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def2 = BeanDefinitionBuilder.genericBeanDefinition(TestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb2", def2);
|
||||
|
||||
PropertyOverrideConfigurer poc1;
|
||||
@@ -128,9 +114,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurerWithNestedProperty() {
|
||||
BeanDefinition def = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IndexedTestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb", def);
|
||||
|
||||
PropertyOverrideConfigurer poc;
|
||||
@@ -148,9 +132,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurerWithNestedPropertyAndDotInBeanName() {
|
||||
BeanDefinition def = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IndexedTestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("my.tb", def);
|
||||
|
||||
PropertyOverrideConfigurer poc;
|
||||
@@ -169,9 +151,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurerWithNestedMapPropertyAndDotInMapKey() {
|
||||
BeanDefinition def = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IndexedTestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb", def);
|
||||
|
||||
PropertyOverrideConfigurer poc;
|
||||
@@ -189,9 +169,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurerWithHeldProperties() {
|
||||
BeanDefinition def = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(PropertiesHolder.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(PropertiesHolder.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb", def);
|
||||
|
||||
PropertyOverrideConfigurer poc;
|
||||
@@ -205,23 +183,9 @@ public final class PropertyResourceConfigurerTests {
|
||||
assertEquals("true", tb.getHeldProperties().getProperty("mail.smtp.auth"));
|
||||
}
|
||||
|
||||
static class PropertiesHolder {
|
||||
private Properties props = new Properties();
|
||||
|
||||
public Properties getHeldProperties() {
|
||||
return props;
|
||||
}
|
||||
|
||||
public void setHeldProperties(Properties props) {
|
||||
this.props = props;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurerWithPropertiesFile() {
|
||||
BeanDefinition def = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IndexedTestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb", def);
|
||||
|
||||
PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer();
|
||||
@@ -235,13 +199,11 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurerWithInvalidPropertiesFile() {
|
||||
BeanDefinition def = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IndexedTestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb", def);
|
||||
|
||||
PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer();
|
||||
poc.setLocations(new Resource[] { TEST_PROPS, XTEST_PROPS });
|
||||
poc.setLocations(TEST_PROPS, XTEST_PROPS);
|
||||
poc.setIgnoreResourceNotFound(true);
|
||||
poc.postProcessBeanFactory(factory);
|
||||
|
||||
@@ -252,9 +214,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurerWithPropertiesXmlFile() {
|
||||
BeanDefinition def = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IndexedTestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb", def);
|
||||
|
||||
PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer();
|
||||
@@ -268,9 +228,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyOverrideConfigurerWithConvertProperties() {
|
||||
BeanDefinition def = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IndexedTestBean.class)
|
||||
.getBeanDefinition();
|
||||
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
|
||||
factory.registerBeanDefinition("tb", def);
|
||||
|
||||
ConvertingOverrideConfigurer bfpp = new ConvertingOverrideConfigurer();
|
||||
@@ -394,7 +352,6 @@ public final class PropertyResourceConfigurerTests {
|
||||
cas.addGenericArgumentValue("${var}name${age}");
|
||||
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
|
||||
pvs.add("stringArray", new String[] {"${os.name}", "${age}"});
|
||||
|
||||
List<Object> friends = new ManagedList<Object>();
|
||||
@@ -414,7 +371,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
someMap.put("key1", new RuntimeBeanReference("${ref}"));
|
||||
someMap.put("key2", "${age}name");
|
||||
MutablePropertyValues innerPvs = new MutablePropertyValues();
|
||||
innerPvs.add("touchy", "${os.name}");
|
||||
innerPvs.add("country", "${os.name}");
|
||||
RootBeanDefinition innerBd = new RootBeanDefinition(TestBean.class);
|
||||
innerBd.setPropertyValues(innerPvs);
|
||||
someMap.put("key3", innerBd);
|
||||
@@ -464,30 +421,28 @@ public final class PropertyResourceConfigurerTests {
|
||||
TestBean inner2 = (TestBean) tb2.getSomeMap().get("mykey4");
|
||||
assertEquals(0, inner1.getAge());
|
||||
assertEquals(null, inner1.getName());
|
||||
assertEquals(System.getProperty("os.name"), inner1.getTouchy());
|
||||
assertEquals(System.getProperty("os.name"), inner1.getCountry());
|
||||
assertEquals(98, inner2.getAge());
|
||||
assertEquals("namemyvarmyvar${", inner2.getName());
|
||||
assertEquals(System.getProperty("os.name"), inner2.getTouchy());
|
||||
assertEquals(System.getProperty("os.name"), inner2.getCountry());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithSystemPropertyFallback() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${os.name}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("country", "${os.name}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
ppc.postProcessBeanFactory(factory);
|
||||
|
||||
TestBean tb = (TestBean) factory.getBean("tb");
|
||||
assertEquals(System.getProperty("os.name"), tb.getTouchy());
|
||||
assertEquals(System.getProperty("os.name"), tb.getCountry());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithSystemPropertyNotUsed() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${os.name}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("country", "${os.name}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
@@ -496,14 +451,13 @@ public final class PropertyResourceConfigurerTests {
|
||||
ppc.postProcessBeanFactory(factory);
|
||||
|
||||
TestBean tb = (TestBean) factory.getBean("tb");
|
||||
assertEquals("myos", tb.getTouchy());
|
||||
assertEquals("myos", tb.getCountry());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithOverridingSystemProperty() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${os.name}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("country", "${os.name}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
@@ -513,14 +467,13 @@ public final class PropertyResourceConfigurerTests {
|
||||
ppc.postProcessBeanFactory(factory);
|
||||
|
||||
TestBean tb = (TestBean) factory.getBean("tb");
|
||||
assertEquals(System.getProperty("os.name"), tb.getTouchy());
|
||||
assertEquals(System.getProperty("os.name"), tb.getCountry());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithUnresolvableSystemProperty() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${user.dir}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${user.dir}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_NEVER);
|
||||
@@ -537,9 +490,8 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithUnresolvablePlaceholder() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${ref}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${ref}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
|
||||
@@ -555,9 +507,8 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithIgnoreUnresolvablePlaceholder() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${ref}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${ref}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
ppc.setIgnoreUnresolvablePlaceholders(true);
|
||||
@@ -569,9 +520,8 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithEmptyStringAsNull() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
ppc.setNullValue("");
|
||||
@@ -583,9 +533,8 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithEmptyStringInPlaceholderAsNull() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${ref}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${ref}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
ppc.setNullValue("");
|
||||
@@ -600,9 +549,8 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithNestedPlaceholderInKey() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${my${key}key}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${my${key}key}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
@@ -617,8 +565,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithPlaceholderInAlias() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class).getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class).getBeanDefinition());
|
||||
factory.registerAlias("tb", "${alias}");
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
@@ -634,8 +581,7 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithSelfReferencingPlaceholderInAlias() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class).getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class).getBeanDefinition());
|
||||
factory.registerAlias("tb", "${alias}");
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
@@ -651,11 +597,10 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithCircularReference() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("age", "${age}")
|
||||
.addPropertyValue("name", "name${var}")
|
||||
.getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("age", "${age}")
|
||||
.addPropertyValue("name", "name${var}")
|
||||
.getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
@@ -675,9 +620,8 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithDefaultProperties() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${test}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${test}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
@@ -691,9 +635,8 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithInlineDefault() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${test:mytest}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${test:mytest}").getBeanDefinition());
|
||||
|
||||
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
|
||||
ppc.postProcessBeanFactory(factory);
|
||||
@@ -704,9 +647,8 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPropertyPlaceholderConfigurerWithAliases() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${test}").getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("touchy", "${test}").getBeanDefinition());
|
||||
|
||||
factory.registerAlias("tb", "${myAlias}");
|
||||
factory.registerAlias("${myTarget}", "alias2");
|
||||
@@ -729,12 +671,11 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPreferencesPlaceholderConfigurer() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${myName}")
|
||||
.addPropertyValue("age", "${myAge}")
|
||||
.addPropertyValue("touchy", "${myTouchy}")
|
||||
.getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${myName}")
|
||||
.addPropertyValue("age", "${myAge}")
|
||||
.addPropertyValue("touchy", "${myTouchy}")
|
||||
.getBeanDefinition());
|
||||
|
||||
PreferencesPlaceholderConfigurer ppc = new PreferencesPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
@@ -757,12 +698,11 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPreferencesPlaceholderConfigurerWithCustomTreePaths() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${myName}")
|
||||
.addPropertyValue("age", "${myAge}")
|
||||
.addPropertyValue("touchy", "${myTouchy}")
|
||||
.getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${myName}")
|
||||
.addPropertyValue("age", "${myAge}")
|
||||
.addPropertyValue("touchy", "${myTouchy}")
|
||||
.getBeanDefinition());
|
||||
|
||||
PreferencesPlaceholderConfigurer ppc = new PreferencesPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
@@ -787,12 +727,11 @@ public final class PropertyResourceConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void testPreferencesPlaceholderConfigurerWithPathInPlaceholder() {
|
||||
factory.registerBeanDefinition("tb",
|
||||
genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${mypath/myName}")
|
||||
.addPropertyValue("age", "${myAge}")
|
||||
.addPropertyValue("touchy", "${myotherpath/myTouchy}")
|
||||
.getBeanDefinition());
|
||||
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
|
||||
.addPropertyValue("name", "${mypath/myName}")
|
||||
.addPropertyValue("age", "${myAge}")
|
||||
.addPropertyValue("touchy", "${myotherpath/myTouchy}")
|
||||
.getBeanDefinition());
|
||||
|
||||
PreferencesPlaceholderConfigurer ppc = new PreferencesPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
@@ -816,6 +755,20 @@ public final class PropertyResourceConfigurerTests {
|
||||
}
|
||||
|
||||
|
||||
static class PropertiesHolder {
|
||||
|
||||
private Properties props = new Properties();
|
||||
|
||||
public Properties getHeldProperties() {
|
||||
return props;
|
||||
}
|
||||
|
||||
public void setHeldProperties(Properties props) {
|
||||
this.props = props;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class ConvertingOverrideConfigurer extends PropertyOverrideConfigurer {
|
||||
|
||||
@Override
|
||||
@@ -824,26 +777,28 @@ public final class PropertyResourceConfigurerTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link PreferencesFactory} to create {@link MockPreferences}.
|
||||
*/
|
||||
public static class MockPreferencesFactory implements PreferencesFactory {
|
||||
|
||||
private Preferences systemRoot = new MockPreferences();
|
||||
private final Preferences userRoot = new MockPreferences();
|
||||
|
||||
private Preferences userRoot = new MockPreferences();
|
||||
private final Preferences systemRoot = new MockPreferences();
|
||||
|
||||
@Override
|
||||
public Preferences systemRoot() {
|
||||
return systemRoot;
|
||||
return this.systemRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Preferences userRoot() {
|
||||
return userRoot;
|
||||
return this.userRoot;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mock implementation of {@link Preferences} that behaves the same regardless of the
|
||||
* underlying operating system and will never throw security exceptions.
|
||||
@@ -909,4 +864,5 @@ public final class PropertyResourceConfigurerTests {
|
||||
protected void flushSpi() throws BackingStoreException {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+30
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -59,7 +59,6 @@ import org.springframework.tests.sample.beans.TestBean;
|
||||
* @author Rob Harrop
|
||||
* @author Arjen Poutsma
|
||||
* @author Chris Beams
|
||||
*
|
||||
* @since 10.06.2003
|
||||
*/
|
||||
public class CustomEditorTests {
|
||||
@@ -302,8 +301,8 @@ public class CustomEditorTests {
|
||||
|
||||
@Test
|
||||
public void testCustomBooleanEditorWithSpecialTrueAndFalseStrings() throws Exception {
|
||||
final String trueString = "pechorin";
|
||||
final String falseString = "nash";
|
||||
String trueString = "pechorin";
|
||||
String falseString = "nash";
|
||||
|
||||
CustomBooleanEditor editor = new CustomBooleanEditor(trueString, falseString, false);
|
||||
|
||||
@@ -320,6 +319,14 @@ public class CustomEditorTests {
|
||||
editor.setAsText(falseString.toUpperCase());
|
||||
assertFalse(((Boolean) editor.getValue()).booleanValue());
|
||||
assertEquals(falseString, editor.getAsText());
|
||||
|
||||
try {
|
||||
editor.setAsText(null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -423,7 +430,7 @@ public class CustomEditorTests {
|
||||
assertTrue("Correct bigDecimal value", new BigDecimal("4.5").equals(tb.getBigDecimal()));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCustomNumberEditorCtorWithNullNumberType() throws Exception {
|
||||
new CustomNumberEditor(null, true);
|
||||
}
|
||||
@@ -543,7 +550,7 @@ public class CustomEditorTests {
|
||||
assertNull(cb.getMyCharacter());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCharacterEditorSetAsTextWithStringLongerThanOneCharacter() throws Exception {
|
||||
PropertyEditor charEditor = new CharacterEditor(false);
|
||||
charEditor.setAsText("ColdWaterCanyon");
|
||||
@@ -562,7 +569,7 @@ public class CustomEditorTests {
|
||||
assertEquals(" ", charEditor.getAsText());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCharacterEditorSetAsTextWithNullNotAllowingEmptyAsNull() throws Exception {
|
||||
PropertyEditor charEditor = new CharacterEditor(false);
|
||||
charEditor.setAsText(null);
|
||||
@@ -583,7 +590,7 @@ public class CustomEditorTests {
|
||||
assertEquals("", classEditor.getAsText());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testClassEditorWithNonExistentClass() throws Exception {
|
||||
PropertyEditor classEditor = new ClassEditor();
|
||||
classEditor.setAsText("hairdresser.on.Fire");
|
||||
@@ -685,26 +692,40 @@ public class CustomEditorTests {
|
||||
@Test
|
||||
public void testCustomBooleanEditor() {
|
||||
CustomBooleanEditor editor = new CustomBooleanEditor(false);
|
||||
|
||||
editor.setAsText("true");
|
||||
assertEquals(Boolean.TRUE, editor.getValue());
|
||||
assertEquals("true", editor.getAsText());
|
||||
|
||||
editor.setAsText("false");
|
||||
assertEquals(Boolean.FALSE, editor.getValue());
|
||||
assertEquals("false", editor.getAsText());
|
||||
|
||||
editor.setValue(null);
|
||||
assertEquals(null, editor.getValue());
|
||||
assertEquals("", editor.getAsText());
|
||||
|
||||
try {
|
||||
editor.setAsText(null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomBooleanEditorWithEmptyAsNull() {
|
||||
CustomBooleanEditor editor = new CustomBooleanEditor(true);
|
||||
|
||||
editor.setAsText("true");
|
||||
assertEquals(Boolean.TRUE, editor.getValue());
|
||||
assertEquals("true", editor.getAsText());
|
||||
|
||||
editor.setAsText("false");
|
||||
assertEquals(Boolean.FALSE, editor.getValue());
|
||||
assertEquals("false", editor.getAsText());
|
||||
|
||||
editor.setValue(null);
|
||||
assertEquals(null, editor.getValue());
|
||||
assertEquals("", editor.getAsText());
|
||||
@@ -750,7 +771,7 @@ public class CustomEditorTests {
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
assertTrue(ex.getMessage().indexOf("10") != -1);
|
||||
assertTrue(ex.getMessage().contains("10"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -36,13 +36,15 @@ import org.springframework.beans.factory.parsing.ReaderEventListener;
|
||||
*/
|
||||
public class CollectingReaderEventListener implements ReaderEventListener {
|
||||
|
||||
private final List defaults = new LinkedList();
|
||||
private final List<DefaultsDefinition> defaults = new LinkedList<DefaultsDefinition>();
|
||||
|
||||
private final Map componentDefinitions = new LinkedHashMap<>(8);
|
||||
private final Map<String, ComponentDefinition> componentDefinitions =
|
||||
new LinkedHashMap<String, ComponentDefinition>(8);
|
||||
|
||||
private final Map aliasMap = new LinkedHashMap<>(8);
|
||||
private final Map<String, List<AliasDefinition>> aliasMap =
|
||||
new LinkedHashMap<String, List<AliasDefinition>>(8);
|
||||
|
||||
private final List imports = new LinkedList();
|
||||
private final List<ImportDefinition> imports = new LinkedList<ImportDefinition>();
|
||||
|
||||
|
||||
@Override
|
||||
@@ -50,7 +52,7 @@ public class CollectingReaderEventListener implements ReaderEventListener {
|
||||
this.defaults.add(defaultsDefinition);
|
||||
}
|
||||
|
||||
public List getDefaults() {
|
||||
public List<DefaultsDefinition> getDefaults() {
|
||||
return Collections.unmodifiableList(this.defaults);
|
||||
}
|
||||
|
||||
@@ -60,27 +62,27 @@ public class CollectingReaderEventListener implements ReaderEventListener {
|
||||
}
|
||||
|
||||
public ComponentDefinition getComponentDefinition(String name) {
|
||||
return (ComponentDefinition) this.componentDefinitions.get(name);
|
||||
return this.componentDefinitions.get(name);
|
||||
}
|
||||
|
||||
public ComponentDefinition[] getComponentDefinitions() {
|
||||
Collection collection = this.componentDefinitions.values();
|
||||
return (ComponentDefinition[]) collection.toArray(new ComponentDefinition[collection.size()]);
|
||||
Collection<ComponentDefinition> collection = this.componentDefinitions.values();
|
||||
return collection.toArray(new ComponentDefinition[collection.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void aliasRegistered(AliasDefinition aliasDefinition) {
|
||||
List aliases = (List) this.aliasMap.get(aliasDefinition.getBeanName());
|
||||
if(aliases == null) {
|
||||
aliases = new ArrayList();
|
||||
List<AliasDefinition> aliases = this.aliasMap.get(aliasDefinition.getBeanName());
|
||||
if (aliases == null) {
|
||||
aliases = new ArrayList<AliasDefinition>();
|
||||
this.aliasMap.put(aliasDefinition.getBeanName(), aliases);
|
||||
}
|
||||
aliases.add(aliasDefinition);
|
||||
}
|
||||
|
||||
public List getAliases(String beanName) {
|
||||
List aliases = (List) this.aliasMap.get(beanName);
|
||||
return aliases == null ? null : Collections.unmodifiableList(aliases);
|
||||
public List<AliasDefinition> getAliases(String beanName) {
|
||||
List<AliasDefinition> aliases = this.aliasMap.get(beanName);
|
||||
return (aliases != null ? Collections.unmodifiableList(aliases) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,7 +90,7 @@ public class CollectingReaderEventListener implements ReaderEventListener {
|
||||
this.imports.add(importDefinition);
|
||||
}
|
||||
|
||||
public List getImports() {
|
||||
public List<ImportDefinition> getImports() {
|
||||
return Collections.unmodifiableList(this.imports);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -76,13 +76,13 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
||||
|
||||
private Float myFloat = new Float(0.0);
|
||||
|
||||
private Collection<? super Object> friends = new LinkedList<>();
|
||||
private Collection<? super Object> friends = new LinkedList<Object>();
|
||||
|
||||
private Set<?> someSet = new HashSet<>();
|
||||
private Set<?> someSet = new HashSet<Object>();
|
||||
|
||||
private Map<?, ?> someMap = new HashMap<>();
|
||||
private Map<?, ?> someMap = new HashMap<Object, Object>();
|
||||
|
||||
private List<?> someList = new ArrayList<>();
|
||||
private List<?> someList = new ArrayList<Object>();
|
||||
|
||||
private Properties someProperties = new Properties();
|
||||
|
||||
@@ -255,10 +255,12 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
||||
this.stringArray = stringArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer[] getSomeIntegerArray() {
|
||||
return someIntegerArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSomeIntegerArray(Integer[] someIntegerArray) {
|
||||
this.someIntegerArray = someIntegerArray;
|
||||
}
|
||||
@@ -461,6 +463,7 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
@@ -472,6 +475,7 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
||||
return (ObjectUtils.nullSafeEquals(this.name, tb2.name) && this.age == tb2.age);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.age;
|
||||
}
|
||||
@@ -486,6 +490,7 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
<util:property-path id="name" path="
|
||||
configuredBean.
|
||||
name
|
||||
"/>
|
||||
"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.tests.sample.beans.TestBean" scope="prototype">
|
||||
<property name="name">
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -126,6 +126,10 @@ public class JCacheCache implements Cache {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class NullHolder implements Serializable {
|
||||
|
||||
private Object readResolve() {
|
||||
return NULL_HOLDER;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -126,7 +126,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
|
||||
}
|
||||
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS);
|
||||
return unit.convert(this.timer.getScheduledExecutionTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public int compareTo(Delayed other) {
|
||||
|
||||
+12
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -245,7 +245,9 @@ public class CronTriggerFactoryBean implements FactoryBean<CronTrigger>, BeanNam
|
||||
CronTriggerImpl cti = new CronTriggerImpl();
|
||||
cti.setName(this.name);
|
||||
cti.setGroup(this.group);
|
||||
cti.setJobKey(this.jobDetail.getKey());
|
||||
if (this.jobDetail != null) {
|
||||
cti.setJobKey(this.jobDetail.getKey());
|
||||
}
|
||||
cti.setJobDataMap(this.jobDataMap);
|
||||
cti.setStartTime(this.startTime);
|
||||
cti.setCronExpression(this.cronExpression);
|
||||
@@ -274,12 +276,14 @@ public class CronTriggerFactoryBean implements FactoryBean<CronTrigger>, BeanNam
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.add("name", this.name);
|
||||
pvs.add("group", this.group);
|
||||
if (jobKeyMethod != null) {
|
||||
pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, this.jobDetail));
|
||||
}
|
||||
else {
|
||||
pvs.add("jobName", this.jobDetail.getName());
|
||||
pvs.add("jobGroup", this.jobDetail.getGroup());
|
||||
if (this.jobDetail != null) {
|
||||
if (jobKeyMethod != null) {
|
||||
pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, this.jobDetail));
|
||||
}
|
||||
else {
|
||||
pvs.add("jobName", this.jobDetail.getName());
|
||||
pvs.add("jobGroup", this.jobDetail.getGroup());
|
||||
}
|
||||
}
|
||||
pvs.add("jobDataMap", this.jobDataMap);
|
||||
pvs.add("startTime", this.startTime);
|
||||
|
||||
+26
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.scheduling.quartz;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
@@ -82,32 +81,41 @@ public class ResourceLoaderClassLoadHelper implements ClassLoadHelper {
|
||||
|
||||
public URL getResource(String name) {
|
||||
Resource resource = this.resourceLoader.getResource(name);
|
||||
try {
|
||||
return resource.getURL();
|
||||
if (resource.exists()) {
|
||||
try {
|
||||
return resource.getURL();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Could not load " + resource);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException ex) {
|
||||
return null;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.warn("Could not load " + resource);
|
||||
return null;
|
||||
else {
|
||||
return getClassLoader().getResource(name);
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getResourceAsStream(String name) {
|
||||
Resource resource = this.resourceLoader.getResource(name);
|
||||
try {
|
||||
return resource.getInputStream();
|
||||
if (resource.exists()) {
|
||||
try {
|
||||
return resource.getInputStream();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Could not load " + resource);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException ex) {
|
||||
return null;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.warn("Could not load " + resource);
|
||||
return null;
|
||||
else {
|
||||
return getClassLoader().getResourceAsStream(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.resourceLoader.getClassLoader();
|
||||
}
|
||||
|
||||
+12
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -237,7 +237,9 @@ public class SimpleTriggerFactoryBean implements FactoryBean<SimpleTrigger>, Bea
|
||||
SimpleTriggerImpl sti = new SimpleTriggerImpl();
|
||||
sti.setName(this.name);
|
||||
sti.setGroup(this.group);
|
||||
sti.setJobKey(this.jobDetail.getKey());
|
||||
if (this.jobDetail != null) {
|
||||
sti.setJobKey(this.jobDetail.getKey());
|
||||
}
|
||||
sti.setJobDataMap(this.jobDataMap);
|
||||
sti.setStartTime(this.startTime);
|
||||
sti.setRepeatInterval(this.repeatInterval);
|
||||
@@ -265,12 +267,14 @@ public class SimpleTriggerFactoryBean implements FactoryBean<SimpleTrigger>, Bea
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.add("name", this.name);
|
||||
pvs.add("group", this.group);
|
||||
if (jobKeyMethod != null) {
|
||||
pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, this.jobDetail));
|
||||
}
|
||||
else {
|
||||
pvs.add("jobName", this.jobDetail.getName());
|
||||
pvs.add("jobGroup", this.jobDetail.getGroup());
|
||||
if (this.jobDetail != null) {
|
||||
if (jobKeyMethod != null) {
|
||||
pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, this.jobDetail));
|
||||
}
|
||||
else {
|
||||
pvs.add("jobName", this.jobDetail.getName());
|
||||
pvs.add("jobGroup", this.jobDetail.getGroup());
|
||||
}
|
||||
}
|
||||
pvs.add("jobDataMap", this.jobDataMap);
|
||||
pvs.add("startTime", this.startTime);
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,6 +45,7 @@ public abstract class FreeMarkerTemplateUtils {
|
||||
*/
|
||||
public static String processTemplateIntoString(Template template, Object model)
|
||||
throws IOException, TemplateException {
|
||||
|
||||
StringWriter result = new StringWriter();
|
||||
template.process(model, result);
|
||||
return result.toString();
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,9 +28,9 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
||||
/**
|
||||
* FreeMarker TemplateLoader adapter that loads via a Spring ResourceLoader.
|
||||
* Used by FreeMarkerConfigurationFactory for any resource loader path that
|
||||
* cannot be resolved to a java.io.File.
|
||||
* FreeMarker {@link TemplateLoader} adapter that loads via a Spring {@link ResourceLoader}.
|
||||
* Used by {@link FreeMarkerConfigurationFactory} for any resource loader path that cannot
|
||||
* be resolved to a {@link java.io.File}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 14.03.2004
|
||||
@@ -63,6 +63,7 @@ public class SpringTemplateLoader implements TemplateLoader {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Object findTemplateSource(String name) throws IOException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Looking for FreeMarker template with name [" + name + "]");
|
||||
@@ -84,7 +85,6 @@ public class SpringTemplateLoader implements TemplateLoader {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public long getLastModified(Object templateSource) {
|
||||
Resource resource = (Resource) templateSource;
|
||||
try {
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.quartz;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.quartz.CronTrigger;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CronTriggerFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void createWithoutJobDetail() throws ParseException {
|
||||
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
|
||||
factory.setName("myTrigger");
|
||||
factory.setCronExpression("0 15 10 ? * *");
|
||||
factory.afterPropertiesSet();
|
||||
CronTrigger trigger = factory.getObject();
|
||||
assertEquals("0 15 10 ? * *", trigger.getCronExpression());
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.quartz;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.quartz.SimpleTrigger;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class SimpleTriggerFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void createWithoutJobDetail() throws ParseException {
|
||||
SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
|
||||
factory.setName("myTrigger");
|
||||
factory.setRepeatCount(5);
|
||||
factory.setRepeatInterval(1000L);
|
||||
factory.afterPropertiesSet();
|
||||
SimpleTrigger trigger = factory.getObject();
|
||||
assertEquals(5, trigger.getRepeatCount());
|
||||
assertEquals(1000L, trigger.getRepeatInterval());
|
||||
}
|
||||
|
||||
}
|
||||
-249
@@ -1,249 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.ui.jasperreports;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import net.sf.jasperreports.engine.JRDataSource;
|
||||
import net.sf.jasperreports.engine.JRExporterParameter;
|
||||
import net.sf.jasperreports.engine.JRParameter;
|
||||
import net.sf.jasperreports.engine.JasperFillManager;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.JasperReport;
|
||||
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
|
||||
import net.sf.jasperreports.engine.export.JRCsvExporterParameter;
|
||||
import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
|
||||
import net.sf.jasperreports.engine.export.JRHtmlExporter;
|
||||
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
|
||||
import net.sf.jasperreports.engine.export.JRPdfExporter;
|
||||
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;
|
||||
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
|
||||
import net.sf.jasperreports.engine.util.JRLoader;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 18.11.2004
|
||||
*/
|
||||
public class JasperReportsUtilsTests extends TestCase {
|
||||
|
||||
public void testRenderAsCsvWithDataSource() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getDataSource(), writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertCsvOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderAsCsvWithCollection() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getData(), writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertCsvOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderAsCsvWithExporterParameters() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
Map<JRExporterParameter, Object> exporterParameters = new HashMap<JRExporterParameter, Object>();
|
||||
exporterParameters.put(JRCsvExporterParameter.FIELD_DELIMITER, "~");
|
||||
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getData(), writer, exporterParameters);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertCsvOutputCorrect(output);
|
||||
assertTrue("Delimiter is incorrect", output.contains("~"));
|
||||
}
|
||||
|
||||
public void testRenderAsHtmlWithDataSource() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getDataSource(), writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertHtmlOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderAsHtmlWithCollection() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getData(), writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertHtmlOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderAsHtmlWithExporterParameters() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
Map<JRExporterParameter, Object> exporterParameters = new HashMap<JRExporterParameter, Object>();
|
||||
String uri = "/my/uri";
|
||||
exporterParameters.put(JRHtmlExporterParameter.IMAGES_URI, uri);
|
||||
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getData(), writer, exporterParameters);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertHtmlOutputCorrect(output);
|
||||
assertTrue("URI not included", output.contains(uri));
|
||||
}
|
||||
|
||||
public void testRenderAsPdfWithDataSource() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getDataSource(), os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertPdfOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderAsPdfWithCollection() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getData(), os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertPdfOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderAsPdfWithExporterParameters() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
Map<JRExporterParameter, Object> exporterParameters = new HashMap<JRExporterParameter, Object>();
|
||||
exporterParameters.put(JRPdfExporterParameter.PDF_VERSION, JRPdfExporterParameter.PDF_VERSION_1_6);
|
||||
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getData(), os, exporterParameters);
|
||||
byte[] output = os.toByteArray();
|
||||
assertPdfOutputCorrect(output);
|
||||
assertTrue(new String(output).contains("PDF-1.6"));
|
||||
}
|
||||
|
||||
public void testRenderAsXlsWithDataSource() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getDataSource(), os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertXlsOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderAsXlsWithCollection() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getData(), os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertXlsOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderAsXlsWithExporterParameters() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
Map<JRExporterParameter, Object> exporterParameters = new HashMap<JRExporterParameter, Object>();
|
||||
|
||||
SimpleProgressMonitor monitor = new SimpleProgressMonitor();
|
||||
exporterParameters.put(JRXlsExporterParameter.PROGRESS_MONITOR, monitor);
|
||||
|
||||
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getData(), os, exporterParameters);
|
||||
byte[] output = os.toByteArray();
|
||||
assertXlsOutputCorrect(output);
|
||||
assertTrue(monitor.isInvoked());
|
||||
}
|
||||
|
||||
public void testRenderWithWriter() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperPrint print = JasperFillManager.fillReport(getReport(), getParameters(), getDataSource());
|
||||
JasperReportsUtils.render(new JRHtmlExporter(), print, writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertHtmlOutputCorrect(output);
|
||||
}
|
||||
|
||||
public void testRenderWithOutputStream() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperPrint print = JasperFillManager.fillReport(getReport(), getParameters(), getDataSource());
|
||||
JasperReportsUtils.render(new JRPdfExporter(), print, os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertPdfOutputCorrect(output);
|
||||
}
|
||||
|
||||
private void assertCsvOutputCorrect(String output) {
|
||||
assertTrue("Output length should be greater than 0", (output.length() > 0));
|
||||
assertTrue("Output should start with Dear Lord!", output.startsWith("Dear Lord!"));
|
||||
assertTrue("Output should contain 'MeineSeite'", output.contains("MeineSeite"));
|
||||
}
|
||||
|
||||
private void assertHtmlOutputCorrect(String output) {
|
||||
assertTrue("Output length should be greater than 0", (output.length() > 0));
|
||||
assertTrue("Output should contain <html>", output.contains("<html>"));
|
||||
assertTrue("Output should contain 'MeineSeite'", output.contains("MeineSeite"));
|
||||
}
|
||||
|
||||
private void assertPdfOutputCorrect(byte[] output) throws Exception {
|
||||
assertTrue("Output length should be greater than 0", (output.length > 0));
|
||||
|
||||
String translated = new String(output, "US-ASCII");
|
||||
assertTrue("Output should start with %PDF", translated.startsWith("%PDF"));
|
||||
}
|
||||
|
||||
private void assertXlsOutputCorrect(byte[] output) throws Exception {
|
||||
HSSFWorkbook workbook = new HSSFWorkbook(new ByteArrayInputStream(output));
|
||||
HSSFSheet sheet = workbook.getSheetAt(0);
|
||||
assertNotNull("Sheet should not be null", sheet);
|
||||
HSSFRow row = sheet.getRow(3);
|
||||
HSSFCell cell = row.getCell((short) 1);
|
||||
assertNotNull("Cell should not be null", cell);
|
||||
assertEquals("Cell content should be Dear Lord!", "Dear Lord!", cell.getRichStringCellValue().getString());
|
||||
}
|
||||
|
||||
private JasperReport getReport() throws Exception {
|
||||
ClassPathResource resource = new ClassPathResource("DataSourceReport.jasper", getClass());
|
||||
return (JasperReport) JRLoader.loadObject(resource.getInputStream());
|
||||
}
|
||||
|
||||
private Map<String, Object> getParameters() {
|
||||
Map<String, Object> model = new HashMap<String, Object>();
|
||||
model.put("ReportTitle", "Dear Lord!");
|
||||
model.put(JRParameter.REPORT_LOCALE, Locale.GERMAN);
|
||||
model.put(JRParameter.REPORT_RESOURCE_BUNDLE,
|
||||
ResourceBundle.getBundle("org/springframework/ui/jasperreports/messages", Locale.GERMAN));
|
||||
return model;
|
||||
}
|
||||
|
||||
private JRDataSource getDataSource() {
|
||||
return new JRBeanCollectionDataSource(getData());
|
||||
}
|
||||
|
||||
private List<PersonBean> getData() {
|
||||
List<PersonBean> list = new ArrayList<PersonBean>();
|
||||
for (int x = 0; x < 10; x++) {
|
||||
PersonBean bean = new PersonBean();
|
||||
bean.setId(x);
|
||||
bean.setName("Rob Harrop");
|
||||
bean.setStreet("foo");
|
||||
list.add(bean);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private static class SimpleProgressMonitor implements JRExportProgressMonitor {
|
||||
|
||||
private boolean invoked = false;
|
||||
|
||||
@Override
|
||||
public void afterPageExport() {
|
||||
this.invoked = true;
|
||||
}
|
||||
|
||||
public boolean isInvoked() {
|
||||
return invoked;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author 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.ui.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class PersonBean {
|
||||
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String street;
|
||||
|
||||
private String city;
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author 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.ui.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class ProductBean {
|
||||
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
private float quantity;
|
||||
|
||||
private float price;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public float getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(float quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public float getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(float price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.springframework.cache;
|
||||
|
||||
/**
|
||||
* Interface that defines the common cache operations.
|
||||
* Interface that defines common cache operations.
|
||||
*
|
||||
* <b>Note:</b> Due to the generic use of caching, it is recommended that
|
||||
* implementations allow storage of <tt>null</tt> values (for example to
|
||||
|
||||
Vendored
+21
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.cache.annotation;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -27,12 +26,11 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportAware;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Abstract base {@code @Configuration} class providing common structure for enabling
|
||||
* Spring's annotation-driven cache management capability.
|
||||
* Abstract base {@code @Configuration} class providing common structure
|
||||
* for enabling Spring's annotation-driven cache management capability.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
@@ -42,22 +40,28 @@ import org.springframework.util.CollectionUtils;
|
||||
public abstract class AbstractCachingConfiguration implements ImportAware {
|
||||
|
||||
protected AnnotationAttributes enableCaching;
|
||||
|
||||
protected CacheManager cacheManager;
|
||||
|
||||
protected KeyGenerator keyGenerator;
|
||||
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
private Collection<CacheManager> cacheManagerBeans;
|
||||
@Autowired(required=false)
|
||||
|
||||
@Autowired(required = false)
|
||||
private Collection<CachingConfigurer> cachingConfigurers;
|
||||
|
||||
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
this.enableCaching = AnnotationAttributes.fromMap(
|
||||
importMetadata.getAnnotationAttributes(EnableCaching.class.getName(), false));
|
||||
Assert.notNull(this.enableCaching,
|
||||
"@EnableCaching is not present on importing class " +
|
||||
importMetadata.getClassName());
|
||||
if (this.enableCaching == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"@EnableCaching is not present on importing class " + importMetadata.getClassName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine which {@code CacheManager} bean to use. Prefer the result of
|
||||
* {@link CachingConfigurer#cacheManager()} over any by-type matching. If none, fall
|
||||
@@ -68,20 +72,20 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
|
||||
*/
|
||||
@PostConstruct
|
||||
protected void reconcileCacheManager() {
|
||||
if (!CollectionUtils.isEmpty(cachingConfigurers)) {
|
||||
int nConfigurers = cachingConfigurers.size();
|
||||
if (!CollectionUtils.isEmpty(this.cachingConfigurers)) {
|
||||
int nConfigurers = this.cachingConfigurers.size();
|
||||
if (nConfigurers > 1) {
|
||||
throw new IllegalStateException(nConfigurers + " implementations of " +
|
||||
"CachingConfigurer were found when only 1 was expected. " +
|
||||
"Refactor the configuration such that CachingConfigurer is " +
|
||||
"implemented only once or not at all.");
|
||||
}
|
||||
CachingConfigurer cachingConfigurer = cachingConfigurers.iterator().next();
|
||||
CachingConfigurer cachingConfigurer = this.cachingConfigurers.iterator().next();
|
||||
this.cacheManager = cachingConfigurer.cacheManager();
|
||||
this.keyGenerator = cachingConfigurer.keyGenerator();
|
||||
}
|
||||
else if (!CollectionUtils.isEmpty(cacheManagerBeans)) {
|
||||
int nManagers = cacheManagerBeans.size();
|
||||
else if (!CollectionUtils.isEmpty(this.cacheManagerBeans)) {
|
||||
int nManagers = this.cacheManagerBeans.size();
|
||||
if (nManagers > 1) {
|
||||
throw new IllegalStateException(nManagers + " beans of type CacheManager " +
|
||||
"were found when only 1 was expected. Remove all but one of the " +
|
||||
@@ -89,8 +93,7 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
|
||||
"to make explicit which CacheManager should be used for " +
|
||||
"annotation-driven cache management.");
|
||||
}
|
||||
CacheManager cacheManager = cacheManagerBeans.iterator().next();
|
||||
this.cacheManager = cacheManager;
|
||||
this.cacheManager = cacheManager = this.cacheManagerBeans.iterator().next();
|
||||
// keyGenerator remains null; will fall back to default within CacheInterceptor
|
||||
}
|
||||
else {
|
||||
@@ -99,4 +102,5 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
|
||||
"from your configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -151,13 +151,12 @@ public @interface EnableCaching {
|
||||
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
|
||||
* to standard Java interface-based proxies. The default is {@code false}. <strong>
|
||||
* Applicable only if {@link #mode()} is set to {@link AdviceMode#PROXY}</strong>.
|
||||
*
|
||||
* <p>Note that setting this attribute to {@code true} will affect <em>all</em>
|
||||
* Spring-managed beans requiring proxying, not just those marked with
|
||||
* {@code @Cacheable}. For example, other beans marked with Spring's
|
||||
* {@code @Transactional} annotation will be upgraded to subclass proxying at the same
|
||||
* time. This approach has no negative impact in practice unless one is explicitly
|
||||
* expecting one type of proxy vs another, e.g. in tests.
|
||||
* Spring-managed beans requiring proxying, not just those marked with {@code @Cacheable}.
|
||||
* For example, other beans marked with Spring's {@code @Transactional} annotation will
|
||||
* be upgraded to subclass proxying at the same time. This approach has no negative
|
||||
* impact in practice unless one is explicitly expecting one type of proxy vs another,
|
||||
* e.g. in tests.
|
||||
*/
|
||||
boolean proxyTargetClass() default false;
|
||||
|
||||
@@ -174,4 +173,5 @@ public @interface EnableCaching {
|
||||
* The default is {@link Ordered#LOWEST_PRECEDENCE}.
|
||||
*/
|
||||
int order() default Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
}
|
||||
|
||||
Vendored
+5
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -70,7 +70,10 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
if (cachings != null) {
|
||||
ops = lazyInit(ops);
|
||||
for (Caching caching : cachings) {
|
||||
ops.addAll(parseCachingAnnotation(ae, caching));
|
||||
Collection<CacheOperation> cachingOps = parseCachingAnnotation(ae, caching);
|
||||
if (cachingOps != null) {
|
||||
ops.addAll(cachingOps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -16,16 +16,17 @@
|
||||
|
||||
package org.springframework.cache.concurrent;
|
||||
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.support.SimpleValueWrapper;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.support.SimpleValueWrapper;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple {@link Cache} implementation based on the core JDK
|
||||
* {@code java.util.concurrent} package.
|
||||
* Simple {@link org.springframework.cache.Cache} implementation based on the
|
||||
* core JDK {@code java.util.concurrent} package.
|
||||
*
|
||||
* <p>Useful for testing or simple caching scenarios, typically in combination
|
||||
* with {@link org.springframework.cache.support.SimpleCacheManager} or
|
||||
@@ -62,7 +63,8 @@ public class ConcurrentMapCache implements Cache {
|
||||
/**
|
||||
* Create a new ConcurrentMapCache with the specified name.
|
||||
* @param name the name of the cache
|
||||
* @param allowNullValues whether to accept and convert null values for this cache
|
||||
* @param allowNullValues whether to accept and convert {@code null}
|
||||
* values for this cache
|
||||
*/
|
||||
public ConcurrentMapCache(String name, boolean allowNullValues) {
|
||||
this(name, new ConcurrentHashMap<Object, Object>(256), allowNullValues);
|
||||
@@ -70,13 +72,15 @@ public class ConcurrentMapCache implements Cache {
|
||||
|
||||
/**
|
||||
* Create a new ConcurrentMapCache with the specified name and the
|
||||
* given internal ConcurrentMap to use.
|
||||
* given internal {@link ConcurrentMap} to use.
|
||||
* @param name the name of the cache
|
||||
* @param store the ConcurrentMap to use as an internal store
|
||||
* @param allowNullValues whether to allow {@code null} values
|
||||
* (adapting them to an internal null holder value)
|
||||
*/
|
||||
public ConcurrentMapCache(String name, ConcurrentMap<Object, Object> store, boolean allowNullValues) {
|
||||
Assert.notNull(name, "Name must not be null");
|
||||
Assert.notNull(store, "Store must not be null");
|
||||
this.name = name;
|
||||
this.store = store;
|
||||
this.allowNullValues = allowNullValues;
|
||||
@@ -142,6 +146,10 @@ public class ConcurrentMapCache implements Cache {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class NullHolder implements Serializable {
|
||||
|
||||
private Object readResolve() {
|
||||
return NULL_HOLDER;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -212,13 +212,14 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
|
||||
return false;
|
||||
}
|
||||
DefaultCacheKey otherKey = (DefaultCacheKey) other;
|
||||
return (this.method.equals(otherKey.method) && ObjectUtils.nullSafeEquals(this.targetClass,
|
||||
otherKey.targetClass));
|
||||
return (this.method.equals(otherKey.method) &&
|
||||
ObjectUtils.nullSafeEquals(this.targetClass, otherKey.targetClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.method.hashCode() * 29 + (this.targetClass != null ? this.targetClass.hashCode() : 0);
|
||||
return this.method.hashCode() + (this.targetClass != null ? this.targetClass.hashCode() * 29 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -53,6 +53,7 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
|
||||
* Name of the ConversionService bean in the factory.
|
||||
* If none is supplied, default conversion rules apply.
|
||||
* @see org.springframework.core.convert.ConversionService
|
||||
* @since 3.0
|
||||
*/
|
||||
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
|
||||
|
||||
@@ -60,12 +61,14 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
|
||||
* Name of the LoadTimeWeaver bean in the factory. If such a bean is supplied,
|
||||
* the context will use a temporary ClassLoader for type matching, in order
|
||||
* to allow the LoadTimeWeaver to process all actual bean classes.
|
||||
* @since 2.5
|
||||
* @see org.springframework.instrument.classloading.LoadTimeWeaver
|
||||
*/
|
||||
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
|
||||
|
||||
/**
|
||||
* Name of the {@link Environment} bean in the factory.
|
||||
* @since 3.1
|
||||
*/
|
||||
String ENVIRONMENT_BEAN_NAME = "environment";
|
||||
|
||||
@@ -84,6 +87,7 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
|
||||
|
||||
/**
|
||||
* Set the unique id of this application context.
|
||||
* @since 3.0
|
||||
*/
|
||||
void setId(String id);
|
||||
|
||||
@@ -99,12 +103,14 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
|
||||
|
||||
/**
|
||||
* Return the Environment for this application context in configurable form.
|
||||
* @since 3.1
|
||||
*/
|
||||
ConfigurableEnvironment getEnvironment();
|
||||
|
||||
/**
|
||||
* Set the {@code Environment} for this application context.
|
||||
* @param environment the new environment
|
||||
* @since 3.1
|
||||
*/
|
||||
void setEnvironment(ConfigurableEnvironment environment);
|
||||
|
||||
@@ -112,9 +118,9 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
|
||||
* Add a new BeanFactoryPostProcessor that will get applied to the internal
|
||||
* bean factory of this application context on refresh, before any of the
|
||||
* bean definitions get evaluated. To be invoked during context configuration.
|
||||
* @param beanFactoryPostProcessor the factory processor to register
|
||||
* @param postProcessor the factory processor to register
|
||||
*/
|
||||
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor);
|
||||
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);
|
||||
|
||||
/**
|
||||
* Add a new ApplicationListener that will be notified on context events
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -17,13 +17,15 @@
|
||||
package org.springframework.context;
|
||||
|
||||
/**
|
||||
* Interface defining methods for start/stop lifecycle control.
|
||||
* A common interface defining methods for start/stop lifecycle control.
|
||||
* The typical use case for this is to control asynchronous processing.
|
||||
* <b>NOTE: This interface does not imply specific auto-startup semantics.
|
||||
* Consider implementing {@link SmartLifecycle} for that purpose.</b>
|
||||
*
|
||||
* <p>Can be implemented by both components (typically a Spring bean defined in
|
||||
* a Spring {@link org.springframework.beans.factory.BeanFactory}) and containers
|
||||
* (typically a Spring {@link ApplicationContext}). Containers will propagate
|
||||
* start/stop signals to all components that apply.
|
||||
* <p>Can be implemented by both components (typically a Spring bean defined in a
|
||||
* Spring context) and containers (typically a Spring {@link ApplicationContext}
|
||||
* itself). Containers will propagate start/stop signals to all components that
|
||||
* apply within each container, e.g. for a stop/restart scenario at runtime.
|
||||
*
|
||||
* <p>Can be used for direct invocations or for management operations via JMX.
|
||||
* In the latter case, the {@link org.springframework.jmx.export.MBeanExporter}
|
||||
@@ -32,10 +34,10 @@ package org.springframework.context;
|
||||
* restricting the visibility of activity-controlled components to the Lifecycle
|
||||
* interface.
|
||||
*
|
||||
* <p>Note that the Lifecycle interface is only supported on <b>top-level singleton beans</b>.
|
||||
* On any other component, the Lifecycle interface will remain undetected and hence ignored.
|
||||
* Also, note that the extended {@link SmartLifecycle} interface provides more sophisticated
|
||||
* integration with the container's startup and shutdown phases.
|
||||
* <p>Note that the Lifecycle interface is only supported on <b>top-level singleton
|
||||
* beans</b>. On any other component, the Lifecycle interface will remain undetected
|
||||
* and hence ignored. Also, note that the extended {@link SmartLifecycle} interface
|
||||
* provides integration with the application context's startup and shutdown phases.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
@@ -51,6 +53,7 @@ public interface Lifecycle {
|
||||
* Should not throw an exception if the component is already running.
|
||||
* <p>In the case of a container, this will propagate the start signal
|
||||
* to all components that apply.
|
||||
* @see SmartLifecycle#isAutoStartup()
|
||||
*/
|
||||
void start();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -17,8 +17,8 @@
|
||||
package org.springframework.context;
|
||||
|
||||
/**
|
||||
* An extension of the {@link Lifecycle} interface for those objects that require to be
|
||||
* started upon ApplicationContext refresh and/or shutdown in a particular order.
|
||||
* An extension of the {@link Lifecycle} interface for those objects that require to
|
||||
* be started upon ApplicationContext refresh and/or shutdown in a particular order.
|
||||
* The {@link #isAutoStartup()} return value indicates whether this object should
|
||||
* be started at the time of a context refresh. The callback-accepting
|
||||
* {@link #stop(Runnable)} method is useful for objects that have an asynchronous
|
||||
@@ -55,26 +55,37 @@ package org.springframework.context;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @since 3.0
|
||||
* @see LifecycleProcessor
|
||||
* @see ConfigurableApplicationContext
|
||||
*/
|
||||
public interface SmartLifecycle extends Lifecycle, Phased {
|
||||
|
||||
/**
|
||||
* Return whether this Lifecycle component should be started automatically
|
||||
* by the container when the ApplicationContext is refreshed. A value of
|
||||
* "false" indicates that the component is intended to be started manually.
|
||||
* Returns {@code true} if this {@code Lifecycle} component should get
|
||||
* started automatically by the container at the time that the containing
|
||||
* {@link ApplicationContext} gets refreshed.
|
||||
* <p>A value of {@code false} indicates that the component is intended to
|
||||
* be started through an explicit {@link #start()} call instead, analogous
|
||||
* to a plain {@link Lifecycle} implementation.
|
||||
* @see #start()
|
||||
* @see #getPhase()
|
||||
* @see LifecycleProcessor#onRefresh()
|
||||
* @see ConfigurableApplicationContext#refresh()
|
||||
*/
|
||||
boolean isAutoStartup();
|
||||
|
||||
/**
|
||||
* Indicates that a Lifecycle component must stop if it is currently running.
|
||||
* <p>The provided callback is used by the {@link LifecycleProcessor} to support an
|
||||
* ordered, and potentially concurrent, shutdown of all components having a
|
||||
* <p>The provided callback is used by the {@link LifecycleProcessor} to support
|
||||
* an ordered, and potentially concurrent, shutdown of all components having a
|
||||
* common shutdown order value. The callback <b>must</b> be executed after
|
||||
* the SmartLifecycle component does indeed stop.
|
||||
* <p>The {@code LifecycleProcessor} will call <i>only</i> this variant of the
|
||||
* the {@code SmartLifecycle} component does indeed stop.
|
||||
* <p>The {@link LifecycleProcessor} will call <i>only</i> this variant of the
|
||||
* {@code stop} method; i.e. {@link Lifecycle#stop()} will not be called for
|
||||
* {@link SmartLifecycle} implementations unless explicitly delegated to within
|
||||
* this method.
|
||||
* {@code SmartLifecycle} implementations unless explicitly delegated to within
|
||||
* the implementation of this method.
|
||||
* @see #stop()
|
||||
* @see #getPhase()
|
||||
*/
|
||||
void stop(Runnable callback);
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -139,7 +139,7 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
|
||||
* <p>The default implementation simply builds a decapitalized version
|
||||
* of the short class name: e.g. "mypackage.MyJdbcDao" -> "myJdbcDao".
|
||||
* <p>Note that inner classes will thus have names of the form
|
||||
* "outerClassName.innerClassName", which because of the period in the
|
||||
* "outerClassName.InnerClassName", which because of the period in the
|
||||
* name may be an issue if you are autowiring by name.
|
||||
* @param definition the bean definition to build a bean name for
|
||||
* @return the default bean name (never {@code null})
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
logger.warn(String.format("%s was imported but no annotations were found " +
|
||||
"having both 'mode' and 'proxyTargetClass' attributes of type " +
|
||||
"AdviceMode and boolean respectively. This means that auto proxy " +
|
||||
"creator registration and configuration may not have occured as " +
|
||||
"creator registration and configuration may not have occurred as " +
|
||||
"intended, and components may not be proxied as expected. Check to " +
|
||||
"ensure that %s has been @Import'ed on the same class where these " +
|
||||
"annotations are declared; otherwise remove the import of %s " +
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -39,7 +39,8 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
* public MyBean myBean() {
|
||||
* // instantiate and configure MyBean obj
|
||||
* return obj;
|
||||
* }</pre>
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <h3>Bean Names</h3>
|
||||
*
|
||||
@@ -55,7 +56,8 @@ 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>
|
||||
*
|
||||
@@ -70,7 +72,8 @@ 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>
|
||||
*
|
||||
@@ -87,14 +90,17 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public FooService fooService() {
|
||||
* return new FooService(fooRepository());
|
||||
* }
|
||||
*
|
||||
* @Bean
|
||||
* public FooRepository fooRepository() {
|
||||
* return new JdbcFooRepository(dataSource());
|
||||
* }
|
||||
*
|
||||
* // ...
|
||||
* }</pre>
|
||||
*
|
||||
@@ -152,7 +158,8 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
* @Bean
|
||||
* public static PropertyPlaceholderConfigurer ppc() {
|
||||
* // instantiate, configure and return ppc ...
|
||||
* }</pre>
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* By marking this method as {@code static}, it can be invoked without causing instantiation of its
|
||||
* declaring {@code @Configuration} class, thus avoiding the above-mentioned lifecycle conflicts.
|
||||
@@ -191,6 +198,13 @@ public @interface Bean {
|
||||
|
||||
/**
|
||||
* Are dependencies to be injected via convention-based autowiring by name or type?
|
||||
* <p>Note that this autowire mode is just about externally driven autowiring based
|
||||
* on bean property setter methods by convention, analogous to XML bean definitions.
|
||||
* <p>The default mode does allow for annotation-driven autowiring. "no" refers to
|
||||
* externally driven autowiring only, not affecting any autowiring demands that the
|
||||
* bean class itself expresses through annotations.
|
||||
* @see Autowire#BY_NAME
|
||||
* @see Autowire#BY_TYPE
|
||||
*/
|
||||
Autowire autowire() default Autowire.NO;
|
||||
|
||||
|
||||
+11
-7
@@ -283,7 +283,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
|
||||
if (beanType != null) {
|
||||
InjectionMetadata metadata = findResourceMetadata(beanName, beanType);
|
||||
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
|
||||
metadata.checkConfigMembers(beanDefinition);
|
||||
}
|
||||
}
|
||||
@@ -299,7 +299,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass());
|
||||
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
|
||||
try {
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
@@ -310,15 +310,19 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||
}
|
||||
|
||||
|
||||
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz) {
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, PropertyValues pvs) {
|
||||
// Fall back to class name as cache key, for backwards compatibility with custom callers.
|
||||
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
|
||||
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
|
||||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(cacheKey);
|
||||
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
|
||||
if (metadata != null) {
|
||||
metadata.clear(pvs);
|
||||
}
|
||||
|
||||
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
Class<?> targetClass = clazz;
|
||||
|
||||
@@ -357,7 +361,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||
if (method.getParameterTypes().length != 1) {
|
||||
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
|
||||
}
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method, clazz);
|
||||
currElements.add(new WebServiceRefElement(method, pd));
|
||||
}
|
||||
else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass)) {
|
||||
@@ -367,7 +371,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||
if (method.getParameterTypes().length != 1) {
|
||||
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
|
||||
}
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method, clazz);
|
||||
currElements.add(new EjbRefElement(method, pd));
|
||||
}
|
||||
else if (method.isAnnotationPresent(Resource.class)) {
|
||||
@@ -379,7 +383,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
|
||||
}
|
||||
if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method, clazz);
|
||||
currElements.add(new ResourceElement(method, pd));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -240,9 +240,8 @@ class ConfigurationClassEnhancer {
|
||||
/**
|
||||
* Enhance a {@link Bean @Bean} method to check the supplied BeanFactory for the
|
||||
* existence of this bean object.
|
||||
* @throws Throwable as a catch-all for any exception that may be thrown when
|
||||
* invoking the super implementation of the proxied method i.e., the actual
|
||||
* {@code @Bean} method.
|
||||
* @throws Throwable as a catch-all for any exception that may be thrown when invoking the
|
||||
* super implementation of the proxied method i.e., the actual {@code @Bean} method
|
||||
*/
|
||||
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
|
||||
MethodProxy cglibMethodProxy) throws Throwable {
|
||||
|
||||
+26
-16
@@ -23,7 +23,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
@@ -101,8 +100,6 @@ class ConfigurationClassParser {
|
||||
|
||||
private final ImportStack importStack = new ImportStack();
|
||||
|
||||
private final Set<Class<?>> importBeanDefinitionRegistrars = new HashSet<Class<?>>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link ConfigurationClassParser} instance that will be used
|
||||
@@ -202,7 +199,7 @@ class ConfigurationClassParser {
|
||||
|
||||
// Process any @Import annotations
|
||||
Set<Object> imports = new LinkedHashSet<Object>();
|
||||
Set<Object> visited = new LinkedHashSet<Object>();
|
||||
Set<String> visited = new LinkedHashSet<String>();
|
||||
collectImports(metadata, imports, visited);
|
||||
if (!imports.isEmpty()) {
|
||||
processImport(configClass, metadata, imports, true);
|
||||
@@ -318,7 +315,7 @@ class ConfigurationClassParser {
|
||||
* @param visited used to track visited classes to prevent infinite recursion
|
||||
* @throws IOException if there is any problem reading metadata from the named class
|
||||
*/
|
||||
private void collectImports(AnnotationMetadata metadata, Set<Object> imports, Set<Object> visited) throws IOException {
|
||||
private void collectImports(AnnotationMetadata metadata, Set<Object> imports, Set<String> visited) throws IOException {
|
||||
String className = metadata.getClassName();
|
||||
if (visited.add(className)) {
|
||||
if (metadata instanceof StandardAnnotationMetadata) {
|
||||
@@ -330,9 +327,13 @@ class ConfigurationClassParser {
|
||||
}
|
||||
Map<String, Object> attributes = stdMetadata.getAnnotationAttributes(Import.class.getName(), false);
|
||||
if (attributes != null) {
|
||||
Class[] value = (Class[]) attributes.get("value");
|
||||
Class<?>[] value = (Class<?>[]) attributes.get("value");
|
||||
if (!ObjectUtils.isEmpty(value)) {
|
||||
imports.addAll(Arrays.asList(value));
|
||||
for (Class<?> importedClass : value) {
|
||||
// Catch duplicate from ASM-based parsing...
|
||||
imports.remove(importedClass.getName());
|
||||
imports.add(importedClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -345,7 +346,7 @@ class ConfigurationClassParser {
|
||||
imports, visited);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
//
|
||||
// Silently ignore...
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -353,7 +354,19 @@ class ConfigurationClassParser {
|
||||
if (attributes != null) {
|
||||
String[] value = (String[]) attributes.get("value");
|
||||
if (!ObjectUtils.isEmpty(value)) {
|
||||
imports.addAll(Arrays.asList(value));
|
||||
for (String importedClassName : value) {
|
||||
// Catch duplicate from reflection-based parsing...
|
||||
boolean alreadyThereAsClass = false;
|
||||
for (Object existingImport : imports) {
|
||||
if (existingImport instanceof Class &&
|
||||
((Class<?>) existingImport).getName().equals(importedClassName)) {
|
||||
alreadyThereAsClass = true;
|
||||
}
|
||||
}
|
||||
if (!alreadyThereAsClass) {
|
||||
imports.add(importedClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -384,13 +397,10 @@ class ConfigurationClassParser {
|
||||
// delegate to it to register additional bean definitions
|
||||
Class<?> candidateClass = (candidate instanceof Class ? (Class) candidate :
|
||||
this.resourceLoader.getClassLoader().loadClass((String) candidate));
|
||||
if (!this.importBeanDefinitionRegistrars.contains(candidateClass)) {
|
||||
ImportBeanDefinitionRegistrar registrar =
|
||||
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
|
||||
invokeAwareMethods(registrar);
|
||||
registrar.registerBeanDefinitions(metadata, this.registry);
|
||||
this.importBeanDefinitionRegistrars.add(candidateClass);
|
||||
}
|
||||
ImportBeanDefinitionRegistrar registrar =
|
||||
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
|
||||
invokeAwareMethods(registrar);
|
||||
registrar.registerBeanDefinitions(metadata, this.registry);
|
||||
}
|
||||
else {
|
||||
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
|
||||
|
||||
+13
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -26,16 +26,15 @@ import org.springframework.context.weaving.DefaultContextLoadTimeWeaver;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.springframework.context.weaving.AspectJWeavingEnabler.*;
|
||||
|
||||
/**
|
||||
* {@code @Configuration} class that registers a {@link LoadTimeWeaver} bean.
|
||||
*
|
||||
* <p>This configuration class is automatically imported when using the @{@link
|
||||
* EnableLoadTimeWeaving} annotation. See {@code @EnableLoadTimeWeaving} Javadoc for
|
||||
* complete usage details.
|
||||
* <p>This configuration class is automatically imported when using the
|
||||
* {@link EnableLoadTimeWeaving} annotation. See {@code @EnableLoadTimeWeaving}
|
||||
* javadoc for complete usage details.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
@@ -47,28 +46,31 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade
|
||||
|
||||
private AnnotationAttributes enableLTW;
|
||||
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
private LoadTimeWeavingConfigurer ltwConfigurer;
|
||||
|
||||
private ClassLoader beanClassLoader;
|
||||
|
||||
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
this.enableLTW = MetadataUtils.attributesFor(importMetadata, EnableLoadTimeWeaving.class);
|
||||
Assert.notNull(this.enableLTW,
|
||||
"@EnableLoadTimeWeaving is not present on importing class " +
|
||||
importMetadata.getClassName());
|
||||
if (this.enableLTW == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"@EnableLoadTimeWeaving is not present on importing class " + importMetadata.getClassName());
|
||||
}
|
||||
}
|
||||
|
||||
public void setBeanClassLoader(ClassLoader beanClassLoader) {
|
||||
this.beanClassLoader = beanClassLoader;
|
||||
}
|
||||
|
||||
@Bean(name=ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME)
|
||||
|
||||
@Bean(name = ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public LoadTimeWeaver loadTimeWeaver() {
|
||||
LoadTimeWeaver loadTimeWeaver = null;
|
||||
|
||||
if (ltwConfigurer != null) {
|
||||
if (this.ltwConfigurer != null) {
|
||||
// the user has provided a custom LTW instance
|
||||
loadTimeWeaver = ltwConfigurer.getLoadTimeWeaver();
|
||||
}
|
||||
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -30,7 +30,6 @@ import org.springframework.jmx.export.annotation.AnnotationMBeanExporter;
|
||||
import org.springframework.jmx.support.RegistrationPolicy;
|
||||
import org.springframework.jmx.support.WebSphereMBeanServerFactoryBean;
|
||||
import org.springframework.jndi.JndiLocatorDelegate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -50,23 +49,26 @@ public class MBeanExportConfiguration implements ImportAware, BeanFactoryAware {
|
||||
|
||||
private static final String MBEAN_EXPORTER_BEAN_NAME = "mbeanExporter";
|
||||
|
||||
private AnnotationAttributes attributes;
|
||||
private AnnotationAttributes enableMBeanExport;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
Map<String, Object> map = importMetadata.getAnnotationAttributes(EnableMBeanExport.class.getName());
|
||||
this.attributes = AnnotationAttributes.fromMap(map);
|
||||
Assert.notNull(this.attributes,
|
||||
"@EnableMBeanExport is not present on importing class " + importMetadata.getClassName());
|
||||
this.enableMBeanExport = AnnotationAttributes.fromMap(map);
|
||||
if (this.enableMBeanExport == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"@EnableMBeanExport is not present on importing class " + importMetadata.getClassName());
|
||||
}
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@Bean(name=MBEAN_EXPORTER_BEAN_NAME)
|
||||
|
||||
@Bean(name = MBEAN_EXPORTER_BEAN_NAME)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public AnnotationMBeanExporter mbeanExporter() {
|
||||
AnnotationMBeanExporter exporter = new AnnotationMBeanExporter();
|
||||
@@ -77,14 +79,14 @@ public class MBeanExportConfiguration implements ImportAware, BeanFactoryAware {
|
||||
}
|
||||
|
||||
private void setupDomain(AnnotationMBeanExporter exporter) {
|
||||
String defaultDomain = this.attributes.getString("defaultDomain");
|
||||
String defaultDomain = this.enableMBeanExport.getString("defaultDomain");
|
||||
if (StringUtils.hasText(defaultDomain)) {
|
||||
exporter.setDefaultDomain(defaultDomain);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupServer(AnnotationMBeanExporter exporter) {
|
||||
String server = this.attributes.getString("server");
|
||||
String server = this.enableMBeanExport.getString("server");
|
||||
if (StringUtils.hasText(server)) {
|
||||
exporter.setServer(this.beanFactory.getBean(server, MBeanServer.class));
|
||||
}
|
||||
@@ -97,7 +99,7 @@ public class MBeanExportConfiguration implements ImportAware, BeanFactoryAware {
|
||||
}
|
||||
|
||||
private void setupRegistrationPolicy(AnnotationMBeanExporter exporter) {
|
||||
RegistrationPolicy registrationPolicy = this.attributes.getEnum("registration");
|
||||
RegistrationPolicy registrationPolicy = this.enableMBeanExport.getEnum("registration");
|
||||
exporter.setRegistrationPolicy(registrationPolicy);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -28,16 +28,16 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||
* Indicates the 'role' hint for a given bean.
|
||||
*
|
||||
* <p>May be used on any class directly or indirectly annotated with
|
||||
* {@link org.springframework.stereotype.Component} or on methods annotated with
|
||||
* {@link Bean}.
|
||||
* {@link org.springframework.stereotype.Component} or on methods
|
||||
* annotated with {@link Bean}.
|
||||
*
|
||||
* <p>If this annotation is not present on a Component or Bean definition, the
|
||||
* default value of {@link BeanDefinition#ROLE_APPLICATION} will apply.
|
||||
* <p>If this annotation is not present on a Component or Bean definition,
|
||||
* the default value of {@link BeanDefinition#ROLE_APPLICATION} will apply.
|
||||
*
|
||||
* <p>If Role is present on a {@link Configuration @Configuration} class, this
|
||||
* indicates the role of the configuration class bean definition and does not
|
||||
* cascade to all @{@code Bean} methods defined within. This behavior is
|
||||
* different than that of the @{@link Lazy} annotation, for example.
|
||||
* <p>If Role is present on a {@link Configuration @Configuration} class,
|
||||
* this indicates the role of the configuration class bean definition and
|
||||
* does not cascade to all @{@code Bean} methods defined within. This behavior
|
||||
* is different than that of the @{@link Lazy} annotation, for example.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
|
||||
+103
-65
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.support.AbstractBeanFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.OrderComparator;
|
||||
@@ -64,42 +65,8 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private Object retrievalMutex = this.defaultRetriever;
|
||||
|
||||
public void addApplicationListener(ApplicationListener listener) {
|
||||
synchronized (this.defaultRetriever) {
|
||||
this.defaultRetriever.applicationListeners.add(listener);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void addApplicationListenerBean(String listenerBeanName) {
|
||||
synchronized (this.defaultRetriever) {
|
||||
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeApplicationListener(ApplicationListener listener) {
|
||||
synchronized (this.defaultRetriever) {
|
||||
this.defaultRetriever.applicationListeners.remove(listener);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeApplicationListenerBean(String listenerBeanName) {
|
||||
synchronized (this.defaultRetriever) {
|
||||
this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllListeners() {
|
||||
synchronized (this.defaultRetriever) {
|
||||
this.defaultRetriever.applicationListeners.clear();
|
||||
this.defaultRetriever.applicationListenerBeans.clear();
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
@@ -110,6 +77,9 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
if (this.beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory) {
|
||||
this.beanClassLoader = ((ConfigurableBeanFactory) beanFactory).getBeanClassLoader();
|
||||
}
|
||||
if (beanFactory instanceof AbstractBeanFactory) {
|
||||
this.retrievalMutex = ((AbstractBeanFactory) beanFactory).getSingletonMutex();
|
||||
}
|
||||
}
|
||||
|
||||
private BeanFactory getBeanFactory() {
|
||||
@@ -121,13 +91,50 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
}
|
||||
|
||||
|
||||
public void addApplicationListener(ApplicationListener listener) {
|
||||
synchronized (this.retrievalMutex) {
|
||||
this.defaultRetriever.applicationListeners.add(listener);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void addApplicationListenerBean(String listenerBeanName) {
|
||||
synchronized (this.retrievalMutex) {
|
||||
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeApplicationListener(ApplicationListener listener) {
|
||||
synchronized (this.retrievalMutex) {
|
||||
this.defaultRetriever.applicationListeners.remove(listener);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeApplicationListenerBean(String listenerBeanName) {
|
||||
synchronized (this.retrievalMutex) {
|
||||
this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllListeners() {
|
||||
synchronized (this.retrievalMutex) {
|
||||
this.defaultRetriever.applicationListeners.clear();
|
||||
this.defaultRetriever.applicationListenerBeans.clear();
|
||||
this.retrieverCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a Collection containing all ApplicationListeners.
|
||||
* @return a Collection of ApplicationListeners
|
||||
* @see org.springframework.context.ApplicationListener
|
||||
*/
|
||||
protected Collection<ApplicationListener> getApplicationListeners() {
|
||||
synchronized (this.defaultRetriever) {
|
||||
synchronized (this.retrievalMutex) {
|
||||
return this.defaultRetriever.getApplicationListeners();
|
||||
}
|
||||
}
|
||||
@@ -145,43 +152,74 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
Object source = event.getSource();
|
||||
Class<?> sourceType = (source != null ? source.getClass() : null);
|
||||
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
|
||||
|
||||
// Quick check for existing entry on ConcurrentHashMap...
|
||||
ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
|
||||
if (retriever != null) {
|
||||
return retriever.getApplicationListeners();
|
||||
}
|
||||
else {
|
||||
retriever = new ListenerRetriever(true);
|
||||
LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
|
||||
Set<ApplicationListener> listeners;
|
||||
Set<String> listenerBeans;
|
||||
synchronized (this.defaultRetriever) {
|
||||
listeners = new LinkedHashSet<ApplicationListener>(this.defaultRetriever.applicationListeners);
|
||||
listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
|
||||
|
||||
if (this.beanClassLoader == null ||
|
||||
(ClassUtils.isCacheSafe(eventType, this.beanClassLoader) &&
|
||||
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
|
||||
// Fully synchronized building and caching of a ListenerRetriever
|
||||
synchronized (this.retrievalMutex) {
|
||||
retriever = this.retrieverCache.get(cacheKey);
|
||||
if (retriever != null) {
|
||||
return retriever.getApplicationListeners();
|
||||
}
|
||||
retriever = new ListenerRetriever(true);
|
||||
Collection<ApplicationListener> listeners =
|
||||
retrieveApplicationListeners(eventType, sourceType, retriever);
|
||||
this.retrieverCache.put(cacheKey, retriever);
|
||||
return listeners;
|
||||
}
|
||||
for (ApplicationListener listener : listeners) {
|
||||
if (supportsEvent(listener, eventType, sourceType)) {
|
||||
}
|
||||
else {
|
||||
// No ListenerRetriever caching -> no synchronization necessary
|
||||
return retrieveApplicationListeners(eventType, sourceType, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually retrieve the application listeners for the given event and source type.
|
||||
* @param eventType the application event type
|
||||
* @param sourceType the event source type
|
||||
* @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)
|
||||
* @return the pre-filtered list of application listeners for the given event and source type
|
||||
*/
|
||||
private Collection<ApplicationListener> retrieveApplicationListeners(
|
||||
Class<? extends ApplicationEvent> eventType, Class<?> sourceType, ListenerRetriever retriever) {
|
||||
|
||||
LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
|
||||
Set<ApplicationListener> listeners;
|
||||
Set<String> listenerBeans;
|
||||
synchronized (this.retrievalMutex) {
|
||||
listeners = new LinkedHashSet<ApplicationListener>(this.defaultRetriever.applicationListeners);
|
||||
listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
|
||||
}
|
||||
for (ApplicationListener listener : listeners) {
|
||||
if (supportsEvent(listener, eventType, sourceType)) {
|
||||
if (retriever != null) {
|
||||
retriever.applicationListeners.add(listener);
|
||||
}
|
||||
allListeners.add(listener);
|
||||
}
|
||||
}
|
||||
if (!listenerBeans.isEmpty()) {
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
for (String listenerBeanName : listenerBeans) {
|
||||
ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
|
||||
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
|
||||
if (retriever != null) {
|
||||
retriever.applicationListenerBeans.add(listenerBeanName);
|
||||
}
|
||||
allListeners.add(listener);
|
||||
}
|
||||
}
|
||||
if (!listenerBeans.isEmpty()) {
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
for (String listenerBeanName : listenerBeans) {
|
||||
ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
|
||||
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
|
||||
retriever.applicationListenerBeans.add(listenerBeanName);
|
||||
allListeners.add(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
OrderComparator.sort(allListeners);
|
||||
if (this.beanClassLoader == null ||
|
||||
(ClassUtils.isCacheSafe(eventType, this.beanClassLoader) &&
|
||||
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
|
||||
this.retrieverCache.put(cacheKey, retriever);
|
||||
}
|
||||
return allListeners;
|
||||
}
|
||||
OrderComparator.sort(allListeners);
|
||||
return allListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,7 +235,7 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
* for the given event type
|
||||
*/
|
||||
protected boolean supportsEvent(
|
||||
ApplicationListener listener, Class<? extends ApplicationEvent> eventType, Class sourceType) {
|
||||
ApplicationListener listener, Class<? extends ApplicationEvent> eventType, Class<?> sourceType) {
|
||||
|
||||
SmartApplicationListener smartListener = (listener instanceof SmartApplicationListener ?
|
||||
(SmartApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
|
||||
|
||||
+16
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -53,6 +53,7 @@ import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.EmbeddedValueResolverAware;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.HierarchicalMessageSource;
|
||||
import org.springframework.context.LifecycleProcessor;
|
||||
@@ -404,8 +405,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
}
|
||||
}
|
||||
|
||||
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor) {
|
||||
this.beanFactoryPostProcessors.add(beanFactoryPostProcessor);
|
||||
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
|
||||
Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
|
||||
this.beanFactoryPostProcessors.add(postProcessor);
|
||||
}
|
||||
|
||||
|
||||
@@ -418,6 +420,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
}
|
||||
|
||||
public void addApplicationListener(ApplicationListener<?> listener) {
|
||||
Assert.notNull(listener, "ApplicationListener must not be null");
|
||||
if (this.applicationEventMulticaster != null) {
|
||||
this.applicationEventMulticaster.addApplicationListener(listener);
|
||||
}
|
||||
@@ -483,7 +486,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
}
|
||||
|
||||
catch (BeansException ex) {
|
||||
logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Exception encountered during context initialization - " +
|
||||
"cancelling refresh attempt: " + ex);
|
||||
}
|
||||
|
||||
// Destroy already created singletons to avoid dangling resources.
|
||||
destroyBeans();
|
||||
@@ -557,11 +563,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
|
||||
// Configure the bean factory with context callbacks.
|
||||
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
|
||||
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
|
||||
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
|
||||
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
|
||||
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
|
||||
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
|
||||
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
|
||||
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
|
||||
|
||||
// BeanFactory interface not registered as resolvable type in a plain factory.
|
||||
// MessageSource registered (and found for autowiring) as a bean.
|
||||
@@ -884,11 +891,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
for (ApplicationListener<?> listener : getApplicationListeners()) {
|
||||
getApplicationEventMulticaster().addApplicationListener(listener);
|
||||
}
|
||||
|
||||
// Do not initialize FactoryBeans here: We need to leave all regular beans
|
||||
// uninitialized to let post-processors apply to them!
|
||||
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
|
||||
for (String lisName : listenerBeanNames) {
|
||||
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
|
||||
for (String listenerBeanName : listenerBeanNames) {
|
||||
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1287,7 +1295,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return getLifecycleProcessor().isRunning();
|
||||
return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -422,6 +422,8 @@ public class ResourceBundleMessageSource extends AbstractMessageSource implement
|
||||
@Override
|
||||
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
|
||||
throws IllegalAccessException, InstantiationException, IOException {
|
||||
|
||||
// Special handling of default encoding
|
||||
if (format.equals("java.properties")) {
|
||||
String bundleName = toBundleName(baseName, locale);
|
||||
final String resourceName = toResourceName(bundleName, "properties");
|
||||
@@ -468,6 +470,7 @@ public class ResourceBundleMessageSource extends AbstractMessageSource implement
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Delegate handling of "java.class" format to standard Control
|
||||
return super.newBundle(baseName, locale, format, loader, reload);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.format.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -28,19 +29,19 @@ import java.lang.annotation.Target;
|
||||
* Can be applied to {@code java.util.Date}, {@code java.util.Calendar}, {@code java.long.Long},
|
||||
* Joda-Time value types; and as of Spring 4 and JDK 8, to JSR-310 <code>java.time</code> types too.
|
||||
*
|
||||
* <p>For style-based formatting, set the {@link #style()} attribute to be the style pattern code.
|
||||
* <p>For style-based formatting, set the {@link #style} attribute to be the style pattern code.
|
||||
* The first character of the code is the date style, and the second character is the time style.
|
||||
* Specify a character of 'S' for short style, 'M' for medium, 'L' for long, and 'F' for full.
|
||||
* A date or time may be omitted by specifying the style character '-'.
|
||||
*
|
||||
* <p>For ISO-based formatting, set the {@link #iso()} attribute to be the desired {@link ISO} format,
|
||||
* <p>For ISO-based formatting, set the {@link #iso} attribute to be the desired {@link ISO} format,
|
||||
* such as {@link ISO#DATE}. For custom formatting, set the {@link #pattern()} attribute to be the
|
||||
* DateTime pattern, such as {@code yyyy/MM/dd hh:mm:ss a}.
|
||||
*
|
||||
* <p>Each attribute is mutually exclusive, so only set one attribute per annotation instance
|
||||
* (the one most convenient one for your formatting needs).
|
||||
* When the pattern attribute is specified, it takes precedence over both the style and ISO attribute.
|
||||
* When the iso attribute is specified, if takes precedence over the style attribute.
|
||||
* When the {@link #iso} attribute is specified, it takes precedence over the style attribute.
|
||||
* When no annotation attributes are specified, the default format applied is style-based
|
||||
* with a style code of 'SS' (short date, short time).
|
||||
*
|
||||
@@ -49,8 +50,9 @@ import java.lang.annotation.Target;
|
||||
* @since 3.0
|
||||
* @see org.joda.time.format.DateTimeFormat
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
|
||||
public @interface DateTimeFormat {
|
||||
|
||||
/**
|
||||
@@ -80,23 +82,23 @@ public @interface DateTimeFormat {
|
||||
/**
|
||||
* Common ISO date time format patterns.
|
||||
*/
|
||||
public enum ISO {
|
||||
enum ISO {
|
||||
|
||||
/**
|
||||
* The most common ISO Date Format {@code yyyy-MM-dd},
|
||||
* e.g. 2000-10-31.
|
||||
* e.g. "2000-10-31".
|
||||
*/
|
||||
DATE,
|
||||
|
||||
/**
|
||||
* The most common ISO Time Format {@code HH:mm:ss.SSSZ},
|
||||
* e.g. 01:30:00.000-05:00.
|
||||
* e.g. "01:30:00.000-05:00".
|
||||
*/
|
||||
TIME,
|
||||
|
||||
/**
|
||||
* The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSZ},
|
||||
* e.g. 2000-10-31 01:30:00.000-05:00.
|
||||
* e.g. "2000-10-31T01:30:00.000-05:00".
|
||||
* <p>This is the default if no annotation value is specified.
|
||||
*/
|
||||
DATE_TIME,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -189,7 +189,7 @@ public class DateFormatter implements Formatter<Date> {
|
||||
if (timeStyle != -1) {
|
||||
return DateFormat.getTimeInstance(timeStyle, locale);
|
||||
}
|
||||
throw new IllegalStateException("Unsupported style pattern '"+ this.stylePattern+ "'");
|
||||
throw new IllegalStateException("Unsupported style pattern '" + this.stylePattern + "'");
|
||||
|
||||
}
|
||||
return DateFormat.getDateInstance(this.style, locale);
|
||||
|
||||
+17
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -107,7 +107,7 @@ public class MBeanClientInterceptor
|
||||
|
||||
private boolean useStrictCasing = true;
|
||||
|
||||
private Class managementInterface;
|
||||
private Class<?> managementInterface;
|
||||
|
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
@@ -215,7 +215,7 @@ public class MBeanClientInterceptor
|
||||
* setters and getters for MBean attributes and conventional Java methods
|
||||
* for MBean operations.
|
||||
*/
|
||||
public void setManagementInterface(Class managementInterface) {
|
||||
public void setManagementInterface(Class<?> managementInterface) {
|
||||
this.managementInterface = managementInterface;
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ public class MBeanClientInterceptor
|
||||
* Return the management interface of the target MBean,
|
||||
* or {@code null} if none specified.
|
||||
*/
|
||||
protected final Class getManagementInterface() {
|
||||
protected final Class<?> getManagementInterface() {
|
||||
return this.managementInterface;
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ public class MBeanClientInterceptor
|
||||
this.invocationHandler = null;
|
||||
if (this.useStrictCasing) {
|
||||
// Use the JDK's own MBeanServerInvocationHandler,
|
||||
// in particular for native MXBean support on Java 6.
|
||||
// in particular for native MXBean support on Java 6+.
|
||||
if (JmxUtils.isMXBeanSupportAvailable()) {
|
||||
this.invocationHandler =
|
||||
new MBeanServerInvocationHandler(this.serverToUse, this.objectName,
|
||||
@@ -297,7 +297,7 @@ public class MBeanClientInterceptor
|
||||
MBeanOperationInfo[] operationInfo = info.getOperations();
|
||||
this.allowedOperations = new HashMap<MethodCacheKey, MBeanOperationInfo>(operationInfo.length);
|
||||
for (MBeanOperationInfo infoEle : operationInfo) {
|
||||
Class[] paramTypes = JmxUtils.parameterInfoToTypes(infoEle.getSignature(), this.beanClassLoader);
|
||||
Class<?>[] paramTypes = JmxUtils.parameterInfoToTypes(infoEle.getSignature(), this.beanClassLoader);
|
||||
this.allowedOperations.put(new MethodCacheKey(infoEle.getName(), paramTypes), infoEle);
|
||||
}
|
||||
}
|
||||
@@ -531,7 +531,7 @@ public class MBeanClientInterceptor
|
||||
* is necessary
|
||||
*/
|
||||
protected Object convertResultValueIfNecessary(Object result, MethodParameter parameter) {
|
||||
Class targetClass = parameter.getParameterType();
|
||||
Class<?> targetClass = parameter.getParameterType();
|
||||
try {
|
||||
if (result == null) {
|
||||
return null;
|
||||
@@ -549,7 +549,7 @@ public class MBeanClientInterceptor
|
||||
return convertDataArrayToTargetArray(array, targetClass);
|
||||
}
|
||||
else if (Collection.class.isAssignableFrom(targetClass)) {
|
||||
Class elementType = GenericCollectionTypeResolver.getCollectionParameterType(parameter);
|
||||
Class<?> elementType = GenericCollectionTypeResolver.getCollectionParameterType(parameter);
|
||||
if (elementType != null) {
|
||||
return convertDataArrayToTargetCollection(array, targetClass, elementType);
|
||||
}
|
||||
@@ -565,7 +565,7 @@ public class MBeanClientInterceptor
|
||||
return convertDataArrayToTargetArray(array, targetClass);
|
||||
}
|
||||
else if (Collection.class.isAssignableFrom(targetClass)) {
|
||||
Class elementType = GenericCollectionTypeResolver.getCollectionParameterType(parameter);
|
||||
Class<?> elementType = GenericCollectionTypeResolver.getCollectionParameterType(parameter);
|
||||
if (elementType != null) {
|
||||
return convertDataArrayToTargetCollection(array, targetClass, elementType);
|
||||
}
|
||||
@@ -581,8 +581,8 @@ public class MBeanClientInterceptor
|
||||
}
|
||||
}
|
||||
|
||||
private Object convertDataArrayToTargetArray(Object[] array, Class targetClass) throws NoSuchMethodException {
|
||||
Class targetType = targetClass.getComponentType();
|
||||
private Object convertDataArrayToTargetArray(Object[] array, Class<?> targetClass) throws NoSuchMethodException {
|
||||
Class<?> targetType = targetClass.getComponentType();
|
||||
Method fromMethod = targetType.getMethod("from", array.getClass().getComponentType());
|
||||
Object resultArray = Array.newInstance(targetType, array.length);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
@@ -592,11 +592,11 @@ public class MBeanClientInterceptor
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Collection convertDataArrayToTargetCollection(Object[] array, Class collectionType, Class elementType)
|
||||
private Collection<?> convertDataArrayToTargetCollection(Object[] array, Class<?> collectionType, Class<?> elementType)
|
||||
throws NoSuchMethodException {
|
||||
|
||||
Method fromMethod = elementType.getMethod("from", array.getClass().getComponentType());
|
||||
Collection resultColl = CollectionFactory.createCollection(collectionType, Array.getLength(array));
|
||||
Collection<Object> resultColl = CollectionFactory.createCollection(collectionType, Array.getLength(array));
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
resultColl.add(ReflectionUtils.invokeMethod(fromMethod, null, array[i]));
|
||||
}
|
||||
@@ -608,6 +608,7 @@ public class MBeanClientInterceptor
|
||||
this.connector.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple wrapper class around a method name and its signature.
|
||||
* Used as the key when caching methods.
|
||||
@@ -616,7 +617,7 @@ public class MBeanClientInterceptor
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Class[] parameterTypes;
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
/**
|
||||
* Create a new instance of {@code MethodCacheKey} with the supplied
|
||||
@@ -624,9 +625,9 @@ public class MBeanClientInterceptor
|
||||
* @param name the name of the method
|
||||
* @param parameterTypes the arguments in the method signature
|
||||
*/
|
||||
public MethodCacheKey(String name, Class[] parameterTypes) {
|
||||
public MethodCacheKey(String name, Class<?>[] parameterTypes) {
|
||||
this.name = name;
|
||||
this.parameterTypes = (parameterTypes != null ? parameterTypes : new Class[0]);
|
||||
this.parameterTypes = (parameterTypes != null ? parameterTypes : new Class<?>[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -446,7 +446,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
objectName = JmxUtils.appendIdentityToObjectName(objectName, managedResource);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Throwable ex) {
|
||||
throw new MBeanExportException("Unable to generate ObjectName for MBean [" + managedResource + "]", ex);
|
||||
}
|
||||
registerManagedResource(managedResource, objectName);
|
||||
@@ -548,7 +548,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 the lazy load behavior is
|
||||
* the {@code MBeanServer} so that 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
|
||||
@@ -556,7 +556,8 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
* @param mapValue the value configured for this bean in the beans map;
|
||||
* may be either the {@code String} name of a bean, or the bean itself
|
||||
* @param beanKey the key associated with this bean in the beans map
|
||||
* @return the {@code ObjectName} under which the resource was registered
|
||||
* @return the {@code ObjectName} under which the resource was registered,
|
||||
* or {@code null} if the actual resource was {@code null} as well
|
||||
* @throws MBeanExportException if the export failed
|
||||
* @see #setBeans
|
||||
* @see #registerBeanInstance
|
||||
@@ -577,12 +578,14 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
}
|
||||
else {
|
||||
Object bean = this.beanFactory.getBean(beanName);
|
||||
ObjectName objectName = registerBeanInstance(bean, beanKey);
|
||||
replaceNotificationListenerBeanNameKeysIfNecessary(beanName, objectName);
|
||||
return objectName;
|
||||
if (bean != null) {
|
||||
ObjectName objectName = registerBeanInstance(bean, beanKey);
|
||||
replaceNotificationListenerBeanNameKeysIfNecessary(beanName, objectName);
|
||||
return objectName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (mapValue != null) {
|
||||
// Plain bean instance -> register it directly.
|
||||
if (this.beanFactory != null) {
|
||||
Map<String, ?> beansOfSameType =
|
||||
@@ -599,10 +602,11 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
return registerBeanInstance(mapValue, beanKey);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Throwable ex) {
|
||||
throw new UnableToRegisterMBeanException(
|
||||
"Unable to register MBean [" + mapValue + "] with key '" + beanKey + "'", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -794,7 +798,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
mbean.setManagedResource(managedResource, MR_TYPE_OBJECT_REFERENCE);
|
||||
return mbean;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Throwable ex) {
|
||||
throw new MBeanExportException("Could not create ModelMBean for managed resource [" +
|
||||
managedResource + "] with key '" + beanKey + "'", ex);
|
||||
}
|
||||
@@ -960,7 +964,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Throwable ex) {
|
||||
throw new MBeanExportException("Unable to register NotificationListener", ex);
|
||||
}
|
||||
}
|
||||
@@ -980,7 +984,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
|
||||
this.server.removeNotificationListener(mappedObjectName, bean.getNotificationListener(),
|
||||
bean.getNotificationFilter(), bean.getHandback());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Throwable ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Unable to unregister NotificationListener", ex);
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -72,7 +72,7 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
|
||||
* @param methodNames an array of method names indicating the methods to use
|
||||
* @see #setMethodMappings
|
||||
*/
|
||||
public void setManagedMethods(String[] methodNames) {
|
||||
public void setManagedMethods(String... methodNames) {
|
||||
this.managedMethods = new HashSet<String>(Arrays.asList(methodNames));
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
|
||||
*/
|
||||
public void setMethodMappings(Properties mappings) {
|
||||
this.methodMappings = new HashMap<String, Set<String>>();
|
||||
for (Enumeration en = mappings.keys(); en.hasMoreElements();) {
|
||||
for (Enumeration<?> en = mappings.keys(); en.hasMoreElements();) {
|
||||
String beanKey = (String) en.nextElement();
|
||||
String[] methodNames = StringUtils.commaDelimitedListToStringArray(mappings.getProperty(beanKey));
|
||||
this.methodMappings.put(beanKey, new HashSet<String>(Arrays.asList(methodNames)));
|
||||
|
||||
+1
-1
@@ -138,7 +138,7 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
|
||||
* the {@code JMXConnectorServer} will be started in a separate thread.
|
||||
* If the {@code daemon} flag is set to {@code true}, that thread will be
|
||||
* started as a daemon thread.
|
||||
* @throws JMException if a problem occured when registering the connector server
|
||||
* @throws JMException if a problem occurred when registering the connector server
|
||||
* with the {@code MBeanServer}
|
||||
* @throws IOException if there is a problem starting the connector server
|
||||
*/
|
||||
|
||||
@@ -145,7 +145,7 @@ public abstract class JmxUtils {
|
||||
* @return the parameter types as classes
|
||||
* @throws ClassNotFoundException if a parameter type could not be resolved
|
||||
*/
|
||||
public static Class[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo) throws ClassNotFoundException {
|
||||
public static Class<?>[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo) throws ClassNotFoundException {
|
||||
return parameterInfoToTypes(paramInfo, ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
@@ -157,12 +157,12 @@ public abstract class JmxUtils {
|
||||
* @return the parameter types as classes
|
||||
* @throws ClassNotFoundException if a parameter type could not be resolved
|
||||
*/
|
||||
public static Class[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo, ClassLoader classLoader)
|
||||
public static Class<?>[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo, ClassLoader classLoader)
|
||||
throws ClassNotFoundException {
|
||||
|
||||
Class[] types = null;
|
||||
Class<?>[] types = null;
|
||||
if (paramInfo != null && paramInfo.length > 0) {
|
||||
types = new Class[paramInfo.length];
|
||||
types = new Class<?>[paramInfo.length];
|
||||
for (int x = 0; x < paramInfo.length; x++) {
|
||||
types[x] = ClassUtils.forName(paramInfo[x].getType(), classLoader);
|
||||
}
|
||||
@@ -178,7 +178,7 @@ public abstract class JmxUtils {
|
||||
* @return the signature as array of argument types
|
||||
*/
|
||||
public static String[] getMethodSignature(Method method) {
|
||||
Class[] types = method.getParameterTypes();
|
||||
Class<?>[] types = method.getParameterTypes();
|
||||
String[] signature = new String[types.length];
|
||||
for (int x = 0; x < types.length; x++) {
|
||||
signature[x] = types[x].getName();
|
||||
@@ -282,7 +282,7 @@ public abstract class JmxUtils {
|
||||
return null;
|
||||
}
|
||||
String mbeanInterfaceName = clazz.getName() + MBEAN_SUFFIX;
|
||||
Class[] implementedInterfaces = clazz.getInterfaces();
|
||||
Class<?>[] implementedInterfaces = clazz.getInterfaces();
|
||||
for (Class<?> iface : implementedInterfaces) {
|
||||
if (iface.getName().equals(mbeanInterfaceName)) {
|
||||
return iface;
|
||||
@@ -302,7 +302,7 @@ public abstract class JmxUtils {
|
||||
if (clazz == null || clazz.getSuperclass() == null) {
|
||||
return null;
|
||||
}
|
||||
Class[] implementedInterfaces = clazz.getInterfaces();
|
||||
Class<?>[] implementedInterfaces = clazz.getInterfaces();
|
||||
for (Class<?> iface : implementedInterfaces) {
|
||||
boolean isMxBean = iface.getName().endsWith(MXBEAN_SUFFIX);
|
||||
if (mxBeanAnnotationAvailable) {
|
||||
|
||||
+6
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -24,7 +24,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportAware;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
@@ -46,14 +45,16 @@ public abstract class AbstractAsyncConfiguration implements ImportAware {
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
this.enableAsync = AnnotationAttributes.fromMap(
|
||||
importMetadata.getAnnotationAttributes(EnableAsync.class.getName(), false));
|
||||
Assert.notNull(this.enableAsync,
|
||||
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
|
||||
if (this.enableAsync == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect any {@link AsyncConfigurer} beans through autowiring.
|
||||
*/
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
void setConfigurers(Collection<AsyncConfigurer> configurers) {
|
||||
if (CollectionUtils.isEmpty(configurers)) {
|
||||
return;
|
||||
|
||||
+25
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -37,16 +37,18 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
* @Configuration
|
||||
* @EnableScheduling
|
||||
* public class AppConfig {
|
||||
*
|
||||
* // various @Bean definitions
|
||||
* }</pre>
|
||||
*
|
||||
* This enables detection of @{@link Scheduled} annotations on any Spring-managed
|
||||
* bean in the container. For example, given a class {@code MyTask}
|
||||
* bean in the container. For example, given a class {@code MyTask}
|
||||
*
|
||||
* <pre class="code">
|
||||
* package com.myco.tasks;
|
||||
*
|
||||
* public class MyTask {
|
||||
*
|
||||
* @Scheduled(fixedRate=1000)
|
||||
* public void work() {
|
||||
* // task execution logic
|
||||
@@ -60,6 +62,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
* @Configuration
|
||||
* @EnableScheduling
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Bean
|
||||
* public MyTask task() {
|
||||
* return new MyTask();
|
||||
@@ -72,6 +75,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableScheduling
|
||||
* @ComponentScan(basePackages="com.myco.tasks")
|
||||
* public class AppConfig {
|
||||
* }</pre>
|
||||
@@ -83,6 +87,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
* @Configuration
|
||||
* @EnableScheduling
|
||||
* public class AppConfig {
|
||||
*
|
||||
* @Scheduled(fixedRate=1000)
|
||||
* public void work() {
|
||||
* // task execution logic
|
||||
@@ -100,6 +105,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
* @Configuration
|
||||
* @EnableScheduling
|
||||
* public class AppConfig implements SchedulingConfigurer {
|
||||
*
|
||||
* @Override
|
||||
* public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
|
||||
* taskRegistrar.setScheduler(taskExecutor());
|
||||
@@ -111,11 +117,11 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* Note in the example above the use of {@code @Bean(destroyMethod="shutdown")}. This
|
||||
* ensures that the task executor is properly shut down when the Spring application
|
||||
* context itself is closed.
|
||||
* <p>Note in the example above the use of {@code @Bean(destroyMethod="shutdown")}.
|
||||
* This ensures that the task executor is properly shut down when the Spring
|
||||
* application context itself is closed.
|
||||
*
|
||||
* Implementing {@code SchedulingConfigurer} also allows for fine-grained
|
||||
* <p>Implementing {@code SchedulingConfigurer} also allows for fine-grained
|
||||
* control over task registration via the {@code ScheduledTaskRegistrar}.
|
||||
* For example, the following configures the execution of a particular bean
|
||||
* method per a custom {@code Trigger} implementation:
|
||||
@@ -124,6 +130,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
* @Configuration
|
||||
* @EnableScheduling
|
||||
* public class AppConfig implements SchedulingConfigurer {
|
||||
*
|
||||
* @Override
|
||||
* public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
|
||||
* taskRegistrar.setScheduler(taskScheduler());
|
||||
@@ -150,22 +157,32 @@ 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 ref="myTask" method="work" fixed-rate="1000"/>
|
||||
*
|
||||
* <task:scheduled-tasks scheduler="taskScheduler">
|
||||
* <task:scheduled ref="myTask" method="work" fixed-rate="1000"/>
|
||||
* </task:scheduled-tasks>
|
||||
*
|
||||
* <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
|
||||
* through direct access to actual componentry.<p>
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
* @see Scheduled
|
||||
* @see SchedulingConfiguration
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
|
||||
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
|
||||
Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
|
||||
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
|
||||
Class<? extends Annotation> customAsyncAnnotation = enableAsync.getClass("annotation");
|
||||
Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
|
||||
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
|
||||
bpp.setAsyncAnnotationType(customAsyncAnnotation);
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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,12 +55,12 @@ import org.springframework.util.StringValueResolver;
|
||||
* to the "fixedRate", "fixedDelay", or "cron" expression provided via the annotation.
|
||||
*
|
||||
* <p>This post-processor is automatically registered by Spring's
|
||||
* {@code <task:annotation-driven>} XML element, and also by the @{@link EnableScheduling}
|
||||
* annotation.
|
||||
* {@code <task:annotation-driven>} XML element, and also by the
|
||||
* @{@link EnableScheduling} annotation.
|
||||
*
|
||||
* <p>Auto-detects any {@link SchedulingConfigurer} instances in the container,
|
||||
* allowing for customization of the scheduler to be used or for fine-grained control
|
||||
* over task registration (e.g. registration of {@link Trigger} tasks.
|
||||
* <p>Autodetects any {@link SchedulingConfigurer} instances in the container,
|
||||
* allowing for customization of the scheduler to be used or for fine-grained
|
||||
* control over task registration (e.g. registration of {@link Trigger} tasks.
|
||||
* See the @{@link EnableScheduling} javadocs for complete usage details.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
@@ -154,9 +154,9 @@ public class ScheduledAnnotationBeanPostProcessor
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(final Object bean, String beanName) {
|
||||
if (!this.nonAnnotatedClasses.containsKey(bean.getClass())) {
|
||||
Class<?> targetClass = AopUtils.getTargetClass(bean);
|
||||
if (!this.nonAnnotatedClasses.containsKey(targetClass)) {
|
||||
final Set<Method> annotatedMethods = new LinkedHashSet<Method>(1);
|
||||
Class<?> targetClass = AopUtils.getTargetClass(bean);
|
||||
ReflectionUtils.doWithMethods(targetClass, new MethodCallback() {
|
||||
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
|
||||
Scheduled scheduled = AnnotationUtils.getAnnotation(method, Scheduled.class);
|
||||
@@ -167,7 +167,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
||||
}
|
||||
});
|
||||
if (annotatedMethods.isEmpty()) {
|
||||
this.nonAnnotatedClasses.put(bean.getClass(), Boolean.TRUE);
|
||||
this.nonAnnotatedClasses.put(targetClass, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -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,6 +45,7 @@ public class TriggerTask extends Task {
|
||||
|
||||
|
||||
public Trigger getTrigger() {
|
||||
return trigger;
|
||||
return this.trigger;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+47
-31
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -29,7 +29,8 @@ import java.util.TimeZone;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Date sequence generator for a <a href="http://www.manpagez.com/man/5/crontab/">Crontab pattern</a>,
|
||||
* Date sequence generator for a
|
||||
* <a href="http://www.manpagez.com/man/5/crontab/">Crontab pattern</a>,
|
||||
* allowing clients to specify a pattern that the sequence matches.
|
||||
*
|
||||
* <p>The pattern is a list of six single space-separated fields: representing
|
||||
@@ -41,6 +42,7 @@ import org.springframework.util.StringUtils;
|
||||
* <li>"0 0 * * * *" = the top of every hour of every day.</li>
|
||||
* <li>"*/10 * * * * *" = every ten seconds.</li>
|
||||
* <li>"0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day.</li>
|
||||
* <li>"0 * 6,19 * * *" = 6:00 AM and 7:00 PM every day.</li>
|
||||
* <li>"0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day.</li>
|
||||
* <li>"0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays</li>
|
||||
* <li>"0 0 0 25 12 ?" = every Christmas Day at midnight</li>
|
||||
@@ -53,22 +55,22 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class CronSequenceGenerator {
|
||||
|
||||
private final BitSet seconds = new BitSet(60);
|
||||
|
||||
private final BitSet minutes = new BitSet(60);
|
||||
|
||||
private final BitSet hours = new BitSet(24);
|
||||
|
||||
private final BitSet daysOfWeek = new BitSet(7);
|
||||
|
||||
private final BitSet daysOfMonth = new BitSet(31);
|
||||
|
||||
private final BitSet months = new BitSet(12);
|
||||
|
||||
private final String expression;
|
||||
|
||||
private final TimeZone timeZone;
|
||||
|
||||
private final BitSet months = new BitSet(12);
|
||||
|
||||
private final BitSet daysOfMonth = new BitSet(31);
|
||||
|
||||
private final BitSet daysOfWeek = new BitSet(7);
|
||||
|
||||
private final BitSet hours = new BitSet(24);
|
||||
|
||||
private final BitSet minutes = new BitSet(60);
|
||||
|
||||
private final BitSet seconds = new BitSet(60);
|
||||
|
||||
|
||||
/**
|
||||
* Construct a {@link CronSequenceGenerator} from the pattern provided,
|
||||
@@ -95,6 +97,14 @@ public class CronSequenceGenerator {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the cron pattern that this sequence generator has been built for.
|
||||
*/
|
||||
String getExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the next {@link Date} in the sequence matching the Cron pattern and
|
||||
* after the value provided. The return value will have a whole number of
|
||||
@@ -106,7 +116,7 @@ public class CronSequenceGenerator {
|
||||
/*
|
||||
The plan:
|
||||
|
||||
1 Round up to the next whole second
|
||||
1 Start with whole second (rounding up if necessary)
|
||||
|
||||
2 If seconds match move on, otherwise find the next match:
|
||||
2.1 If next match is in the next minute then roll forwards
|
||||
@@ -118,8 +128,6 @@ public class CronSequenceGenerator {
|
||||
4 If hour matches move on, otherwise find the next match
|
||||
4.1 If next match is in the next day then roll forwards,
|
||||
4.2 Reset the minutes and seconds and go to 2
|
||||
|
||||
...
|
||||
*/
|
||||
|
||||
Calendar calendar = new GregorianCalendar();
|
||||
@@ -271,9 +279,9 @@ public class CronSequenceGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the values in the commaSeparatedList (case insensitive) with
|
||||
* their index in the list.
|
||||
* @return a new string with the values from the list replaced
|
||||
* Replace the values in the comma-separated list (case insensitive)
|
||||
* with their index in the list.
|
||||
* @return a new String with the values from the list replaced
|
||||
*/
|
||||
private String replaceOrdinals(String value, String commaSeparatedList) {
|
||||
String[] list = StringUtils.commaDelimitedListToStringArray(commaSeparatedList);
|
||||
@@ -332,6 +340,10 @@ public class CronSequenceGenerator {
|
||||
range[1] = max - 1;
|
||||
}
|
||||
int delta = Integer.valueOf(split[1]);
|
||||
if (delta <= 0) {
|
||||
throw new IllegalArgumentException("Incrementer delta must be 1 or higher: '" +
|
||||
field + "' in expression \"" + this.expression + "\"");
|
||||
}
|
||||
for (int i = range[0]; i <= range[1]; i += delta) {
|
||||
bits.set(i);
|
||||
}
|
||||
@@ -366,28 +378,32 @@ public class CronSequenceGenerator {
|
||||
throw new IllegalArgumentException("Range less than minimum (" + min + "): '" +
|
||||
field + "' in expression \"" + this.expression + "\"");
|
||||
}
|
||||
if (result[0] > result[1]) {
|
||||
throw new IllegalArgumentException("Invalid inverted range: '" + field +
|
||||
"' in expression \"" + this.expression + "\"");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String getExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof CronSequenceGenerator)) {
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof CronSequenceGenerator)) {
|
||||
return false;
|
||||
}
|
||||
CronSequenceGenerator cron = (CronSequenceGenerator) obj;
|
||||
return cron.months.equals(this.months) && cron.daysOfMonth.equals(this.daysOfMonth)
|
||||
&& cron.daysOfWeek.equals(this.daysOfWeek) && cron.hours.equals(this.hours)
|
||||
&& cron.minutes.equals(this.minutes) && cron.seconds.equals(this.seconds);
|
||||
CronSequenceGenerator otherCron = (CronSequenceGenerator) other;
|
||||
return (this.months.equals(otherCron.months) && this.daysOfMonth.equals(otherCron.daysOfMonth) &&
|
||||
this.daysOfWeek.equals(otherCron.daysOfWeek) && this.hours.equals(otherCron.hours) &&
|
||||
this.minutes.equals(otherCron.minutes) && this.seconds.equals(otherCron.seconds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 37 + 17 * this.months.hashCode() + 29 * this.daysOfMonth.hashCode() + 37 * this.daysOfWeek.hashCode()
|
||||
+ 41 * this.hours.hashCode() + 53 * this.minutes.hashCode() + 61 * this.seconds.hashCode();
|
||||
return (17 * this.months.hashCode() + 29 * this.daysOfMonth.hashCode() + 37 * this.daysOfWeek.hashCode() +
|
||||
41 * this.hours.hashCode() + 53 * this.minutes.hashCode() + 61 * this.seconds.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+21
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -37,21 +37,29 @@ public class CronTrigger implements Trigger {
|
||||
|
||||
/**
|
||||
* Build a {@link CronTrigger} from the pattern provided in the default time zone.
|
||||
* @param cronExpression a space-separated list of time fields,
|
||||
* following cron expression conventions
|
||||
* @param expression a space-separated list of time fields, following cron
|
||||
* expression conventions
|
||||
*/
|
||||
public CronTrigger(String cronExpression) {
|
||||
this.sequenceGenerator = new CronSequenceGenerator(cronExpression);
|
||||
public CronTrigger(String expression) {
|
||||
this.sequenceGenerator = new CronSequenceGenerator(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link CronTrigger} from the pattern provided.
|
||||
* @param cronExpression a space-separated list of time fields,
|
||||
* following cron expression conventions
|
||||
* Build a {@link CronTrigger} from the pattern provided in the given time zone.
|
||||
* @param expression a space-separated list of time fields, following cron
|
||||
* expression conventions
|
||||
* @param timeZone a time zone in which the trigger times will be generated
|
||||
*/
|
||||
public CronTrigger(String cronExpression, TimeZone timeZone) {
|
||||
this.sequenceGenerator = new CronSequenceGenerator(cronExpression, timeZone);
|
||||
public CronTrigger(String expression, TimeZone timeZone) {
|
||||
this.sequenceGenerator = new CronSequenceGenerator(expression, timeZone);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the cron pattern that this trigger has been built with.
|
||||
*/
|
||||
public String getExpression() {
|
||||
return this.sequenceGenerator.getExpression();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,14 +86,11 @@ public class CronTrigger implements Trigger {
|
||||
return this.sequenceGenerator.next(date);
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return this.sequenceGenerator.getExpression();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (this == obj || (obj instanceof CronTrigger &&
|
||||
this.sequenceGenerator.equals(((CronTrigger) obj).sequenceGenerator)));
|
||||
public boolean equals(Object other) {
|
||||
return (this == other || (other instanceof CronTrigger &&
|
||||
this.sequenceGenerator.equals(((CronTrigger) other).sequenceGenerator)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+29
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -114,9 +114,9 @@ public class BshScriptFactory implements ScriptFactory, BeanClassLoaderAware {
|
||||
public Object getScriptedObject(ScriptSource scriptSource, Class<?>... actualInterfaces)
|
||||
throws IOException, ScriptCompilationException {
|
||||
|
||||
try {
|
||||
Class<?> clazz;
|
||||
Class<?> clazz;
|
||||
|
||||
try {
|
||||
synchronized (this.scriptClassMonitor) {
|
||||
boolean requiresScriptEvaluation = (this.wasModifiedForTypeCheck && this.scriptClass == null);
|
||||
this.wasModifiedForTypeCheck = false;
|
||||
@@ -140,33 +140,39 @@ public class BshScriptFactory implements ScriptFactory, BeanClassLoaderAware {
|
||||
}
|
||||
clazz = this.scriptClass;
|
||||
}
|
||||
}
|
||||
catch (EvalError ex) {
|
||||
this.scriptClass = null;
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
}
|
||||
|
||||
if (clazz != null) {
|
||||
// A Class: We need to create an instance for every call.
|
||||
try {
|
||||
return clazz.newInstance();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new ScriptCompilationException(
|
||||
scriptSource, "Could not instantiate script class: " + clazz.getName(), ex);
|
||||
}
|
||||
if (clazz != null) {
|
||||
// A Class: We need to create an instance for every call.
|
||||
try {
|
||||
return clazz.newInstance();
|
||||
}
|
||||
else {
|
||||
// Not a Class: We need to evaluate the script for every call.
|
||||
catch (Throwable ex) {
|
||||
throw new ScriptCompilationException(
|
||||
scriptSource, "Could not instantiate script class: " + clazz.getName(), ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Not a Class: We need to evaluate the script for every call.
|
||||
try {
|
||||
return BshScriptUtils.createBshObject(
|
||||
scriptSource.getScriptAsString(), actualInterfaces, this.beanClassLoader);
|
||||
}
|
||||
}
|
||||
catch (EvalError ex) {
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
catch (EvalError ex) {
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> getScriptedObjectType(ScriptSource scriptSource)
|
||||
throws IOException, ScriptCompilationException {
|
||||
|
||||
try {
|
||||
synchronized (this.scriptClassMonitor) {
|
||||
synchronized (this.scriptClassMonitor) {
|
||||
try {
|
||||
if (scriptSource.isModified()) {
|
||||
// New script content: Let's check whether it evaluates to a Class.
|
||||
this.wasModifiedForTypeCheck = true;
|
||||
@@ -174,9 +180,10 @@ public class BshScriptFactory implements ScriptFactory, BeanClassLoaderAware {
|
||||
}
|
||||
return this.scriptClass;
|
||||
}
|
||||
}
|
||||
catch (EvalError ex) {
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
catch (EvalError ex) {
|
||||
this.scriptClass = null;
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -39,13 +39,13 @@ import org.springframework.util.xml.DomUtils;
|
||||
* Allows for objects written using dynamic languages to be easily exposed with
|
||||
* the {@link org.springframework.beans.factory.BeanFactory}.
|
||||
*
|
||||
* <p>The script for each object can be specified either as a reference to the Resource
|
||||
* containing it (using the '{@code script-source}' attribute) or inline in the XML configuration
|
||||
* itself (using the '{@code inline-script}' attribute.
|
||||
* <p>The script for each object can be specified either as a reference to the
|
||||
* resource containing it (using the '{@code script-source}' attribute) or inline
|
||||
* in the XML configuration itself (using the '{@code inline-script}' attribute.
|
||||
*
|
||||
* <p>By default, dynamic objects created with these tags are <strong>not</strong> refreshable.
|
||||
* To enable refreshing, specify the refresh check delay for each object (in milliseconds) using the
|
||||
* '{@code refresh-check-delay}' attribute.
|
||||
* <p>By default, dynamic objects created with these tags are <strong>not</strong>
|
||||
* refreshable. To enable refreshing, specify the refresh check delay for each
|
||||
* object (in milliseconds) using the '{@code refresh-check-delay}' attribute.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Rod Johnson
|
||||
@@ -171,14 +171,13 @@ class ScriptBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
// Attach any refresh metadata.
|
||||
String refreshCheckDelay = element.getAttribute(REFRESH_CHECK_DELAY_ATTRIBUTE);
|
||||
if (StringUtils.hasText(refreshCheckDelay)) {
|
||||
bd.setAttribute(ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, new Long(refreshCheckDelay));
|
||||
bd.setAttribute(ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, Long.valueOf(refreshCheckDelay));
|
||||
}
|
||||
|
||||
// Attach any proxy target class metadata.
|
||||
String proxyTargetClass = element.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE);
|
||||
if (StringUtils.hasText(proxyTargetClass)) {
|
||||
Boolean flag = new Boolean(proxyTargetClass);
|
||||
bd.setAttribute(ScriptFactoryPostProcessor.PROXY_TARGET_CLASS_ATTRIBUTE, flag);
|
||||
bd.setAttribute(ScriptFactoryPostProcessor.PROXY_TARGET_CLASS_ATTRIBUTE, Boolean.valueOf(proxyTargetClass));
|
||||
}
|
||||
|
||||
// Add constructor arguments.
|
||||
@@ -213,7 +212,7 @@ class ScriptBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
*/
|
||||
private String resolveScriptSource(Element element, XmlReaderContext readerContext) {
|
||||
boolean hasScriptSource = element.hasAttribute(SCRIPT_SOURCE_ATTRIBUTE);
|
||||
List elements = DomUtils.getChildElementsByTagName(element, INLINE_SCRIPT_ELEMENT);
|
||||
List<Element> elements = DomUtils.getChildElementsByTagName(element, INLINE_SCRIPT_ELEMENT);
|
||||
if (hasScriptSource && !elements.isEmpty()) {
|
||||
readerContext.error("Only one of 'script-source' and 'inline-script' should be specified.", element);
|
||||
return null;
|
||||
@@ -222,7 +221,7 @@ class ScriptBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
return element.getAttribute(SCRIPT_SOURCE_ATTRIBUTE);
|
||||
}
|
||||
else if (!elements.isEmpty()) {
|
||||
Element inlineElement = (Element) elements.get(0);
|
||||
Element inlineElement = elements.get(0);
|
||||
return "inline:" + DomUtils.getTextValue(inlineElement);
|
||||
}
|
||||
else {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -40,7 +40,7 @@ public class ScriptingDefaultsParser implements BeanDefinitionParser {
|
||||
LangNamespaceUtils.registerScriptFactoryPostProcessorIfNecessary(parserContext.getRegistry());
|
||||
String refreshCheckDelay = element.getAttribute(REFRESH_CHECK_DELAY_ATTRIBUTE);
|
||||
if (StringUtils.hasText(refreshCheckDelay)) {
|
||||
bd.getPropertyValues().add("defaultRefreshCheckDelay", new Long(refreshCheckDelay));
|
||||
bd.getPropertyValues().add("defaultRefreshCheckDelay", Long.valueOf(refreshCheckDelay));
|
||||
}
|
||||
String proxyTargetClass = element.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE);
|
||||
if (StringUtils.hasText(proxyTargetClass)) {
|
||||
|
||||
+21
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -24,7 +24,6 @@ import groovy.lang.MetaClass;
|
||||
import groovy.lang.Script;
|
||||
import org.codehaus.groovy.control.CompilationFailedException;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
@@ -99,7 +98,7 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
|
||||
}
|
||||
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
if (beanFactory instanceof ConfigurableListableBeanFactory) {
|
||||
((ConfigurableListableBeanFactory) beanFactory).ignoreDependencyType(MetaClass.class);
|
||||
}
|
||||
@@ -151,10 +150,9 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
|
||||
public Object getScriptedObject(ScriptSource scriptSource, Class<?>... actualInterfaces)
|
||||
throws IOException, ScriptCompilationException {
|
||||
|
||||
try {
|
||||
Class<?> scriptClassToExecute;
|
||||
|
||||
synchronized (this.scriptClassMonitor) {
|
||||
synchronized (this.scriptClassMonitor) {
|
||||
try {
|
||||
Class<?> scriptClassToExecute;
|
||||
this.wasModifiedForTypeCheck = false;
|
||||
|
||||
if (this.cachedResult != null) {
|
||||
@@ -179,21 +177,23 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
|
||||
}
|
||||
}
|
||||
scriptClassToExecute = this.scriptClass;
|
||||
}
|
||||
|
||||
// Process re-execution outside of the synchronized block.
|
||||
return executeScript(scriptSource, scriptClassToExecute);
|
||||
}
|
||||
catch (CompilationFailedException ex) {
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
// Process re-execution outside of the synchronized block.
|
||||
return executeScript(scriptSource, scriptClassToExecute);
|
||||
}
|
||||
catch (CompilationFailedException ex) {
|
||||
this.scriptClass = null;
|
||||
this.scriptResultClass = null;
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> getScriptedObjectType(ScriptSource scriptSource)
|
||||
throws IOException, ScriptCompilationException {
|
||||
|
||||
try {
|
||||
synchronized (this.scriptClassMonitor) {
|
||||
synchronized (this.scriptClassMonitor) {
|
||||
try {
|
||||
if (this.scriptClass == null || scriptSource.isModified()) {
|
||||
// New script content...
|
||||
this.wasModifiedForTypeCheck = true;
|
||||
@@ -212,9 +212,12 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
|
||||
}
|
||||
return this.scriptResultClass;
|
||||
}
|
||||
}
|
||||
catch (CompilationFailedException ex) {
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
catch (CompilationFailedException ex) {
|
||||
this.scriptClass = null;
|
||||
this.scriptResultClass = null;
|
||||
this.cachedResult = null;
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user