mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
284 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f428cbb72f | |||
| 6a5d986b33 | |||
| 8ce9236b0f | |||
| 1a626ab948 | |||
| 56194a1051 | |||
| a496836e46 | |||
| 974e7b88ee | |||
| 069704f4a0 | |||
| d38eb9d6a0 | |||
| 5bd4f88af1 | |||
| b16a3229bc | |||
| a409233e80 | |||
| 7a97ba54ea | |||
| 9de85f1336 | |||
| 484a2f3f2d | |||
| 5bd5df3ec4 | |||
| b51685bf00 | |||
| 687d350b57 | |||
| 73dfa9a968 | |||
| 5a66a339a6 | |||
| 45598ca53a | |||
| 4b30fe2b44 | |||
| e94c69149e | |||
| c69fdfadfc | |||
| bd060a19ac | |||
| 5515112f87 | |||
| 89cadfa8d9 | |||
| 73da153e5c | |||
| 75b323e6c2 | |||
| 13637ec3b5 | |||
| 7da02fb7e3 | |||
| 92c210201e | |||
| ae6d778c3e | |||
| e24ac55480 | |||
| b17a6f9e03 | |||
| 4c050207e7 | |||
| 7ac99c1c2d | |||
| 42e550a178 | |||
| 1b78afe445 | |||
| 001cecd46a | |||
| 21b7dc1ce4 | |||
| a403a754e9 | |||
| 2ae2249842 | |||
| 484addb4f8 | |||
| 65e423219e | |||
| 22fc3255b7 | |||
| 322b0f431f | |||
| 1ff1c950fb | |||
| 1e9b2b1c07 | |||
| 19e944bd4f | |||
| e9e864b093 | |||
| f4b644dfec | |||
| b129fb4b62 | |||
| 50f7ffddf8 | |||
| 4298744c4a | |||
| 44b2657c8e | |||
| 9f69638420 | |||
| 740751bc01 | |||
| de8d4e917d | |||
| fa8acfafbf | |||
| d5bfddac69 | |||
| 1b0d838a19 | |||
| a0f52bf633 | |||
| a9dd927870 | |||
| 323ccf99e5 | |||
| 437eca0b25 | |||
| 965f3c6434 | |||
| 6df7ba2447 | |||
| 1d6f71718d | |||
| 4a6e9a5557 | |||
| 357ca21675 | |||
| 874859493b | |||
| 75a6f3b2b6 | |||
| 88456d4799 | |||
| c44de3c5df | |||
| 9d1789e718 | |||
| 849b6ccb8b | |||
| 997ca5cd3f | |||
| a54bc6650e | |||
| 70424a7e3d | |||
| 318d04cd2b | |||
| d9ff109b0f | |||
| 8501cef98d | |||
| c99a104919 | |||
| 193c289080 | |||
| 9c3270ad35 | |||
| e4a9ade991 | |||
| fbd83015b1 | |||
| 3a15595d0c | |||
| 289a6091f1 | |||
| 3502f6fdc2 | |||
| 8d67a982ec | |||
| c09e10405b | |||
| 6a727e1ed7 | |||
| 246a6db1ca | |||
| 8748ba4c4b | |||
| 2989f01013 | |||
| c6a7732a30 | |||
| e54c9d4a93 | |||
| ac19c696fe | |||
| fecbcd4e93 | |||
| 59396e1a6f | |||
| c4ef47b29f | |||
| c2fdd56107 | |||
| 98536e1387 | |||
| ba13950d3a | |||
| 0009806deb | |||
| 6deee3e818 | |||
| d3acf45ea4 | |||
| 573f1d77f2 | |||
| 1ca06537c1 | |||
| 1ab0850303 | |||
| 2a9eaab674 | |||
| 1fbd38c2d8 | |||
| 49eafe4261 | |||
| b0ed385f84 | |||
| 5d54adfb9a | |||
| 1cbc353dd1 | |||
| 4cf1795359 | |||
| 5629fa2c9f | |||
| 2903cb7f50 | |||
| 986d219391 | |||
| de4da5ea4e | |||
| e8c656d2bc | |||
| bcda243f63 | |||
| 64f304c333 | |||
| 5f6b04251e | |||
| 618cb6155c | |||
| f3dd22da5b | |||
| 6e4bbac6f7 | |||
| 2e4963fca3 | |||
| 4d0adc7d95 | |||
| 3b3f27d5ff | |||
| f32b13c5b3 | |||
| 1897d8e858 | |||
| 71126faae0 | |||
| 9cc03fa8b0 | |||
| 59189e5957 | |||
| 65a8aa1c09 | |||
| f046a066ec | |||
| 6e1cac9145 | |||
| 7cafa6764c | |||
| c1cb0311aa | |||
| f2478cf8cf | |||
| 977084a6b8 | |||
| 0e7e49bab0 | |||
| 301ba01427 | |||
| 881817678f | |||
| b8c92ce931 | |||
| 6158634d67 | |||
| 8d8bb04783 | |||
| 2cac3a8255 | |||
| 25a3019234 | |||
| 3dff1b3f6e | |||
| b1295d0499 | |||
| eeeb0a6546 | |||
| 1bde920cce | |||
| e02ff3a0da | |||
| ff377a3836 | |||
| ddb2bdf8c6 | |||
| b9ebdaaf37 | |||
| 4187e04b69 | |||
| d512cca3fd | |||
| 4bc3e0c2b4 | |||
| d57d914b26 | |||
| 68463e2018 | |||
| 6fa9539ae2 | |||
| ff53a26333 | |||
| b70d400c71 | |||
| 346d0e271d | |||
| c15f23bf0c | |||
| 0962c66592 | |||
| b643f7836c | |||
| 56fdda167e | |||
| 017f2a8ccc | |||
| f7898951bd | |||
| bd6b7b08f3 | |||
| bc043245cc | |||
| 6e8a3fb4db | |||
| 1f12214b45 | |||
| c6bd0c9f3d | |||
| fb22915563 | |||
| c5c27f2963 | |||
| 3e6cfb7c6d | |||
| 8e68ac44d2 | |||
| 81c50dc674 | |||
| 57aa3d1e3b | |||
| 2c45b09263 | |||
| 59f12635f9 | |||
| 901d48c803 | |||
| 0bc7c47bea | |||
| 06e2bada0a | |||
| 8181c0237f | |||
| d4af8c86b2 | |||
| 39ddd0f349 | |||
| 073e78b68d | |||
| f9754f92f4 | |||
| d5f358c33c | |||
| 295df21f06 | |||
| 57a9e8e6dd | |||
| e83491fbe9 | |||
| 37ee264fbf | |||
| 8b5563ecab | |||
| 0a3a82fd83 | |||
| 8b071633d3 | |||
| caed04473e | |||
| 87abdb92da | |||
| 6d11b40353 | |||
| 350f318d2e | |||
| 608ef46516 | |||
| d60446a4fe | |||
| 722cb36e01 | |||
| 5ba37762fe | |||
| f2dc075335 | |||
| 3b0eca921c | |||
| efe2539cf3 | |||
| 0030ff8711 | |||
| f93ca28884 | |||
| 4be416e2ca | |||
| 2033f50f22 | |||
| e33fb892f1 | |||
| afe461609c | |||
| 33d655a634 | |||
| 2654dbfcf1 | |||
| 14440949b3 | |||
| 05dec6d23e | |||
| cc77b4b995 | |||
| fd964ca4b1 | |||
| 5fd761ee39 | |||
| 8fda96cadb | |||
| 9926b68473 | |||
| d8a2672505 | |||
| b125b5e398 | |||
| 65743a68e6 | |||
| f187ca6413 | |||
| 13c213481a | |||
| ce9402618c | |||
| a041769799 | |||
| 09cb7f4c31 | |||
| 04f954956c | |||
| fe4472dbeb | |||
| b708027e94 | |||
| 333449598f | |||
| 03b2d9399e | |||
| 4ccf33e36b | |||
| 5eebe946bd | |||
| 13fa69bdaf | |||
| 4aeca67c4d | |||
| b695b15243 | |||
| ef4b62caa0 | |||
| 238e9ae59f | |||
| 347f2890df | |||
| 8b5a013423 | |||
| a73d9bbed5 | |||
| c1bc74c83f | |||
| f68fdd4454 | |||
| 19640ec3f9 | |||
| 69c882cfbc | |||
| 64af3a0f64 | |||
| d7959edb3e | |||
| 0b77c8835c | |||
| 28f15057ac | |||
| e5025419c2 | |||
| d53ede9bd3 | |||
| 092b3d4a52 | |||
| bf4cadadda | |||
| a9bad580d9 | |||
| 6f6ff33202 | |||
| 4bb837582e | |||
| 3368dcae22 | |||
| 86704112b0 | |||
| d62dd2dd8d | |||
| e935018b0c | |||
| 0747cd6a70 | |||
| 0a30b71dc3 | |||
| 03118542f4 | |||
| 1b3b058ebd | |||
| 8aa94aee27 | |||
| 6dbc828aa1 | |||
| 3c31e0378f | |||
| e6e6b8f4ad | |||
| 4fe94dffc0 | |||
| 4b8a937bee | |||
| 55fc731c59 |
+15
-14
@@ -40,7 +40,7 @@ configure(allprojects) { project ->
|
||||
ext.ejbVersion = "3.0"
|
||||
ext.fileuploadVersion = "1.3.3"
|
||||
ext.freemarkerVersion = "2.3.23"
|
||||
ext.groovyVersion = "2.4.13"
|
||||
ext.groovyVersion = "2.4.15"
|
||||
ext.gsonVersion = "2.8.2"
|
||||
ext.guavaVersion = "20.0"
|
||||
ext.hamcrestVersion = "1.3"
|
||||
@@ -51,8 +51,8 @@ configure(allprojects) { project ->
|
||||
ext.hibval5Version = "5.2.5.Final"
|
||||
ext.hsqldbVersion = "2.3.4"
|
||||
ext.httpasyncVersion = "4.1.3"
|
||||
ext.httpclientVersion = "4.5.3"
|
||||
ext.jackson2Version = "2.8.10"
|
||||
ext.httpclientVersion = "4.5.5"
|
||||
ext.jackson2Version = "2.8.11.2"
|
||||
ext.jasperreportsVersion = "6.2.1" // our tests fail with JR-internal NPEs against 6.2.2 and higher
|
||||
ext.javamailVersion = "1.5.6"
|
||||
ext.jettyVersion = "9.3.14.v20161028" // as of 9.3.15, Jetty has hard Servlet 3.1 requirement
|
||||
@@ -62,20 +62,20 @@ configure(allprojects) { project ->
|
||||
ext.jtaVersion = "1.2"
|
||||
ext.junitVersion = "4.12"
|
||||
ext.log4jVersion = "1.2.17"
|
||||
ext.nettyVersion = "4.1.17.Final"
|
||||
ext.nettyVersion = "4.1.29.Final"
|
||||
ext.okhttpVersion = "2.7.5"
|
||||
ext.okhttp3Version = "3.8.1"
|
||||
ext.openjpaVersion = "2.4.2"
|
||||
ext.poiVersion = "3.14"
|
||||
ext.reactorVersion = "2.0.8.RELEASE"
|
||||
ext.romeVersion = "1.7.4"
|
||||
ext.slf4jVersion = "1.7.21"
|
||||
ext.slf4jVersion = "1.7.25"
|
||||
ext.snakeyamlVersion = "1.17"
|
||||
ext.snifferVersion = "1.15"
|
||||
ext.snifferVersion = "1.16"
|
||||
ext.testngVersion = "6.9.10"
|
||||
ext.tiles2Version = "2.2.2"
|
||||
ext.tiles3Version = "3.0.7"
|
||||
ext.tomcatVersion = "8.5.23"
|
||||
ext.tomcatVersion = "8.5.33"
|
||||
ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support
|
||||
ext.undertowVersion = "1.3.33.Final"
|
||||
ext.xmlunitVersion = "1.6"
|
||||
@@ -293,7 +293,7 @@ project("spring-core") {
|
||||
// both into the spring-core jar. cglib 3.2 itself depends on asm 5.x and is therefore
|
||||
// further transformed by the JarJar task to depend on org.springframework.asm; this
|
||||
// avoids including two different copies of asm unnecessarily.
|
||||
def cglibVersion = "3.2.5"
|
||||
def cglibVersion = "3.2.6"
|
||||
def objenesisVersion = "2.6"
|
||||
|
||||
configurations {
|
||||
@@ -316,7 +316,7 @@ project("spring-core") {
|
||||
}
|
||||
// Repackage net.sf.cglib => org.springframework.cglib
|
||||
rule(pattern: "net.sf.cglib.**", result: "org.springframework.cglib.@1")
|
||||
// As mentioned above, transform cglib"s internal asm dependencies from
|
||||
// As mentioned above, transform cglib's internal asm dependencies from
|
||||
// org.objectweb.asm => org.springframework.asm. Doing this counts on the
|
||||
// the fact that Spring and cglib depend on the same version of asm!
|
||||
rule(pattern: "org.objectweb.asm.**", result: "org.springframework.asm.@1")
|
||||
@@ -704,7 +704,7 @@ project("spring-web") {
|
||||
optional("com.squareup.okhttp:okhttp:${okhttpVersion}")
|
||||
optional("com.squareup.okhttp3:okhttp:${okhttp3Version}")
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
|
||||
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.11")
|
||||
optional("com.google.code.gson:gson:${gsonVersion}")
|
||||
optional("com.rometools:rome:${romeVersion}")
|
||||
optional("org.eclipse.jetty:jetty-servlet:${jettyVersion}") {
|
||||
@@ -720,12 +720,13 @@ project("spring-web") {
|
||||
testCompile(project(":spring-context-support")) // for JafMediaTypeFactory
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
testCompile("org.skyscreamer:jsonassert:1.4.0")
|
||||
testCompile("org.apache.taglibs:taglibs-standard-jstlel:1.2.1") {
|
||||
exclude group: "org.apache.taglibs", module: "taglibs-standard-spec"
|
||||
}
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.module:jackson-module-kotlin:${jackson2Version}")
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda:2.8.11")
|
||||
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.8.11")
|
||||
testCompile("com.fasterxml.jackson.module:jackson-module-kotlin:2.8.11.1")
|
||||
testCompile("com.squareup.okhttp3:mockwebserver:${okhttp3Version}")
|
||||
testRuntime("com.sun.mail:javax.mail:${javamailVersion}")
|
||||
}
|
||||
@@ -836,7 +837,7 @@ project("spring-webmvc") {
|
||||
exclude group: "org.springframework", module: "spring-context"
|
||||
}
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
|
||||
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.11")
|
||||
optional("com.rometools:rome:${romeVersion}")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("org.apache.tiles:tiles-api:${tiles3Version}")
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.3.13.BUILD-SNAPSHOT
|
||||
version=4.3.19.RELEASE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,10 +48,11 @@ import java.lang.reflect.Method;
|
||||
public interface MethodMatcher {
|
||||
|
||||
/**
|
||||
* Perform static checking whether the given method matches. If this
|
||||
* returns {@code false} or if the {@link #isRuntime()} method
|
||||
* returns {@code false}, no runtime check (i.e. no.
|
||||
* {@link #matches(java.lang.reflect.Method, Class, Object[])} call) will be made.
|
||||
* Perform static checking whether the given method matches.
|
||||
* <p>If this returns {@code false} or if the {@link #isRuntime()}
|
||||
* method returns {@code false}, no runtime check (i.e. no
|
||||
* {@link #matches(java.lang.reflect.Method, Class, Object[])} call)
|
||||
* will be made.
|
||||
* @param method the candidate method
|
||||
* @param targetClass the target class (may be {@code null}, in which case
|
||||
* the candidate class must be taken to be the method's declaring class)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -227,7 +227,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <b>declaration order</b> of this advice within the aspect
|
||||
* Set the declaration order of this advice within the aspect.
|
||||
*/
|
||||
public void setDeclarationOrder(int order) {
|
||||
this.declarationOrder = order;
|
||||
@@ -366,7 +366,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
* to which argument name. There are multiple strategies for determining
|
||||
* this binding, which are arranged in a ChainOfResponsibility.
|
||||
*/
|
||||
public synchronized final void calculateArgumentBindings() {
|
||||
public final synchronized void calculateArgumentBindings() {
|
||||
// The simple case... nothing to bind.
|
||||
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
|
||||
return;
|
||||
@@ -374,10 +374,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
|
||||
int numUnboundArgs = this.parameterTypes.length;
|
||||
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
|
||||
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
|
||||
numUnboundArgs--;
|
||||
}
|
||||
else if (maybeBindJoinPointStaticPart(parameterTypes[0])) {
|
||||
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0]) ||
|
||||
maybeBindJoinPointStaticPart(parameterTypes[0])) {
|
||||
numUnboundArgs--;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -415,7 +415,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
String toMatch = tokens[i];
|
||||
int firstParenIndex = toMatch.indexOf("(");
|
||||
int firstParenIndex = toMatch.indexOf('(');
|
||||
if (firstParenIndex != -1) {
|
||||
toMatch = toMatch.substring(0, firstParenIndex);
|
||||
}
|
||||
@@ -575,7 +575,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
if (toMatch.startsWith("!")) {
|
||||
toMatch = toMatch.substring(1);
|
||||
}
|
||||
int firstParenIndex = toMatch.indexOf("(");
|
||||
int firstParenIndex = toMatch.indexOf('(');
|
||||
if (firstParenIndex != -1) {
|
||||
toMatch = toMatch.substring(0, firstParenIndex);
|
||||
}
|
||||
|
||||
+12
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import org.aopalliance.aop.Advice;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.IntroductionAdvisor;
|
||||
import org.springframework.aop.IntroductionInterceptor;
|
||||
import org.springframework.aop.support.ClassFilters;
|
||||
import org.springframework.aop.support.DelegatePerTargetObjectIntroductionInterceptor;
|
||||
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
||||
@@ -34,12 +35,12 @@ import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
||||
*/
|
||||
public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
|
||||
private final Advice advice;
|
||||
|
||||
private final Class<?> introducedInterface;
|
||||
|
||||
private final ClassFilter typePatternClassFilter;
|
||||
|
||||
private final Advice advice;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new advisor for this DeclareParents field.
|
||||
@@ -48,8 +49,8 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
* @param defaultImpl the default implementation class
|
||||
*/
|
||||
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> defaultImpl) {
|
||||
this(interfaceType, typePattern, defaultImpl,
|
||||
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
|
||||
this(interfaceType, typePattern,
|
||||
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,8 +60,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
* @param delegateRef the delegate implementation object
|
||||
*/
|
||||
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Object delegateRef) {
|
||||
this(interfaceType, typePattern, delegateRef.getClass(),
|
||||
new DelegatingIntroductionInterceptor(delegateRef));
|
||||
this(interfaceType, typePattern, new DelegatingIntroductionInterceptor(delegateRef));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,23 +68,21 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
|
||||
* (cannot use method such as init() to share common code, due the use of final fields)
|
||||
* @param interfaceType static field defining the introduction
|
||||
* @param typePattern type pattern the introduction is restricted to
|
||||
* @param implementationClass implementation class
|
||||
* @param advice delegation advice
|
||||
* @param interceptor the delegation advice as {@link IntroductionInterceptor}
|
||||
*/
|
||||
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> implementationClass, Advice advice) {
|
||||
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, IntroductionInterceptor interceptor) {
|
||||
this.advice = interceptor;
|
||||
this.introducedInterface = interfaceType;
|
||||
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
|
||||
|
||||
// Excludes methods implemented.
|
||||
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
|
||||
ClassFilter exclusion = new ClassFilter() {
|
||||
@Override
|
||||
public boolean matches(Class<?> clazz) {
|
||||
return !(introducedInterface.isAssignableFrom(clazz));
|
||||
return !introducedInterface.isAssignableFrom(clazz);
|
||||
}
|
||||
};
|
||||
|
||||
this.typePatternClassFilter = ClassFilters.intersection(typePatternFilter, exclusion);
|
||||
this.advice = advice;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+14
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,17 +32,15 @@ import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of AspectJ ProceedingJoinPoint interface
|
||||
* wrapping an AOP Alliance MethodInvocation.
|
||||
* An implementation of the AspectJ {@link ProceedingJoinPoint} interface
|
||||
* wrapping an AOP Alliance {@link org.aopalliance.intercept.MethodInvocation}.
|
||||
*
|
||||
* <p><b>Note</b>: the {@code getThis()} method returns the current Spring AOP proxy.
|
||||
* <p><b>Note</b>: The {@code getThis()} method returns the current Spring AOP proxy.
|
||||
* The {@code getTarget()} method returns the current Spring AOP target (which may be
|
||||
* {@code null} if there is no target), and is a plain POJO without any advice.
|
||||
* <b>If you want to call the object and have the advice take effect, use
|
||||
* {@code getThis()}.</b> A common example is casting the object to an
|
||||
* introduced interface in the implementation of an introduction.
|
||||
*
|
||||
* <p>Of course there is no such distinction between target and proxy in AspectJ.
|
||||
* {@code null} if there is no target instance) as a plain POJO without any advice.
|
||||
* <b>If you want to call the object and have the advice take effect, use {@code getThis()}.</b>
|
||||
* A common example is casting the object to an introduced interface in the implementation of
|
||||
* an introduction. There is no such distinction between target and proxy in AspectJ itself.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
@@ -56,7 +54,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
|
||||
private final ProxyMethodInvocation methodInvocation;
|
||||
|
||||
private Object[] defensiveCopyOfArgs;
|
||||
private Object[] args;
|
||||
|
||||
/** Lazily initialized signature object */
|
||||
private Signature signature;
|
||||
@@ -75,6 +73,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
this.methodInvocation = methodInvocation;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void set$AroundClosure(AroundClosure aroundClosure) {
|
||||
throw new UnsupportedOperationException();
|
||||
@@ -115,12 +114,10 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
|
||||
@Override
|
||||
public Object[] getArgs() {
|
||||
if (this.defensiveCopyOfArgs == null) {
|
||||
Object[] argsSource = this.methodInvocation.getArguments();
|
||||
this.defensiveCopyOfArgs = new Object[argsSource.length];
|
||||
System.arraycopy(argsSource, 0, this.defensiveCopyOfArgs, 0, argsSource.length);
|
||||
if (this.args == null) {
|
||||
this.args = this.methodInvocation.getArguments().clone();
|
||||
}
|
||||
return this.defensiveCopyOfArgs;
|
||||
return this.args;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,7 +125,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
if (this.signature == null) {
|
||||
this.signature = new MethodSignatureImpl();
|
||||
}
|
||||
return signature;
|
||||
return this.signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,6 +41,7 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
|
||||
this.aspectClass = aspectClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the specified aspect class (never {@code null}).
|
||||
*/
|
||||
@@ -48,7 +49,6 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
|
||||
return this.aspectClass;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Object getAspectInstance() {
|
||||
try {
|
||||
|
||||
+37
-50
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,6 +59,9 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
|
||||
private static final String AJC_MAGIC = "ajc$";
|
||||
|
||||
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
|
||||
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
|
||||
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
@@ -122,14 +125,12 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
|
||||
/**
|
||||
* Find and return the first AspectJ annotation on the given method
|
||||
* (there <i>should</i> only be one anyway...)
|
||||
* (there <i>should</i> only be one anyway...).
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
|
||||
Class<?>[] classesToLookFor = new Class<?>[] {
|
||||
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
|
||||
for (Class<?> c : classesToLookFor) {
|
||||
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
|
||||
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
|
||||
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
|
||||
if (foundAnnotation != null) {
|
||||
return foundAnnotation;
|
||||
}
|
||||
@@ -148,14 +149,13 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enum for AspectJ annotation types.
|
||||
* @see AspectJAnnotation#getAnnotationType()
|
||||
*/
|
||||
protected enum AspectJAnnotationType {
|
||||
|
||||
AtPointcut,
|
||||
AtBefore,
|
||||
AtAfter,
|
||||
AtAfterReturning,
|
||||
AtAfterThrowing,
|
||||
AtAround
|
||||
AtPointcut, AtAround, AtBefore, AtAfter, AtAfterReturning, AtAfterThrowing
|
||||
}
|
||||
|
||||
|
||||
@@ -165,18 +165,18 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
*/
|
||||
protected static class AspectJAnnotation<A extends Annotation> {
|
||||
|
||||
private static final String[] EXPRESSION_PROPERTIES = new String[] {"value", "pointcut"};
|
||||
private static final String[] EXPRESSION_ATTRIBUTES = new String[] {"pointcut", "value"};
|
||||
|
||||
private static Map<Class<?>, AspectJAnnotationType> annotationTypes =
|
||||
new HashMap<Class<?>, AspectJAnnotationType>();
|
||||
private static Map<Class<?>, AspectJAnnotationType> annotationTypeMap =
|
||||
new HashMap<Class<?>, AspectJAnnotationType>(8);
|
||||
|
||||
static {
|
||||
annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
|
||||
annotationTypes.put(After.class,AspectJAnnotationType.AtAfter);
|
||||
annotationTypes.put(AfterReturning.class,AspectJAnnotationType.AtAfterReturning);
|
||||
annotationTypes.put(AfterThrowing.class,AspectJAnnotationType.AtAfterThrowing);
|
||||
annotationTypes.put(Around.class,AspectJAnnotationType.AtAround);
|
||||
annotationTypes.put(Before.class,AspectJAnnotationType.AtBefore);
|
||||
annotationTypeMap.put(Pointcut.class, AspectJAnnotationType.AtPointcut);
|
||||
annotationTypeMap.put(Around.class, AspectJAnnotationType.AtAround);
|
||||
annotationTypeMap.put(Before.class, AspectJAnnotationType.AtBefore);
|
||||
annotationTypeMap.put(After.class, AspectJAnnotationType.AtAfter);
|
||||
annotationTypeMap.put(AfterReturning.class, AspectJAnnotationType.AtAfterReturning);
|
||||
annotationTypeMap.put(AfterThrowing.class, AspectJAnnotationType.AtAfterThrowing);
|
||||
}
|
||||
|
||||
private final A annotation;
|
||||
@@ -190,44 +190,31 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
public AspectJAnnotation(A annotation) {
|
||||
this.annotation = annotation;
|
||||
this.annotationType = determineAnnotationType(annotation);
|
||||
// We know these methods exist with the same name on each object,
|
||||
// but need to invoke them reflectively as there isn't a common interface.
|
||||
try {
|
||||
this.pointcutExpression = resolveExpression(annotation);
|
||||
this.argumentNames = (String) annotation.getClass().getMethod("argNames").invoke(annotation);
|
||||
this.argumentNames = (String) AnnotationUtils.getValue(annotation, "argNames");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalArgumentException(annotation + " cannot be an AspectJ annotation", ex);
|
||||
throw new IllegalArgumentException(annotation + " is not a valid AspectJ annotation", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private AspectJAnnotationType determineAnnotationType(A annotation) {
|
||||
for (Class<?> type : annotationTypes.keySet()) {
|
||||
if (type.isInstance(annotation)) {
|
||||
return annotationTypes.get(type);
|
||||
}
|
||||
AspectJAnnotationType type = annotationTypeMap.get(annotation.annotationType());
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
throw new IllegalStateException("Unknown annotation type: " + annotation.toString());
|
||||
throw new IllegalStateException("Unknown annotation type: " + annotation);
|
||||
}
|
||||
|
||||
private String resolveExpression(A annotation) throws Exception {
|
||||
String expression = null;
|
||||
for (String methodName : EXPRESSION_PROPERTIES) {
|
||||
Method method;
|
||||
try {
|
||||
method = annotation.getClass().getDeclaredMethod(methodName);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
method = null;
|
||||
}
|
||||
if (method != null) {
|
||||
String candidate = (String) method.invoke(annotation);
|
||||
if (StringUtils.hasText(candidate)) {
|
||||
expression = candidate;
|
||||
}
|
||||
private String resolveExpression(A annotation) {
|
||||
for (String attributeName : EXPRESSION_ATTRIBUTES) {
|
||||
String candidate = (String) AnnotationUtils.getValue(annotation, attributeName);
|
||||
if (StringUtils.hasText(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
throw new IllegalStateException("Failed to resolve expression: " + annotation);
|
||||
}
|
||||
|
||||
public AspectJAnnotationType getAnnotationType() {
|
||||
@@ -268,11 +255,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
if (annotation == null) {
|
||||
return null;
|
||||
}
|
||||
StringTokenizer strTok = new StringTokenizer(annotation.getArgumentNames(), ",");
|
||||
if (strTok.countTokens() > 0) {
|
||||
String[] names = new String[strTok.countTokens()];
|
||||
StringTokenizer nameTokens = new StringTokenizer(annotation.getArgumentNames(), ",");
|
||||
if (nameTokens.countTokens() > 0) {
|
||||
String[] names = new String[nameTokens.countTokens()];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = strTok.nextToken();
|
||||
names[i] = nameTokens.nextToken();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
+14
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -168,19 +168,19 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||
synchronized (aspectCache) {
|
||||
// To be safe, check within full lock now...
|
||||
instance = aspectCache.get(aspectClass);
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
}
|
||||
try {
|
||||
instance = aspectClass.newInstance();
|
||||
aspectCache.put(aspectClass, instance);
|
||||
return instance;
|
||||
}
|
||||
catch (InstantiationException ex) {
|
||||
throw new AopConfigException("Unable to instantiate aspect class [" + aspectClass.getName() + "]", ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new AopConfigException("Cannot access aspect class [" + aspectClass.getName() + "]", ex);
|
||||
if (instance == null) {
|
||||
try {
|
||||
instance = aspectClass.newInstance();
|
||||
aspectCache.put(aspectClass, instance);
|
||||
}
|
||||
catch (InstantiationException ex) {
|
||||
throw new AopConfigException(
|
||||
"Unable to instantiate aspect class: " + aspectClass.getName(), ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new AopConfigException(
|
||||
"Could not access aspect constructor: " + aspectClass.getName(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -127,7 +127,7 @@ public class AspectMetadata implements Serializable {
|
||||
*/
|
||||
private String findPerClause(Class<?> aspectClass) {
|
||||
String str = aspectClass.getAnnotation(Aspect.class).value();
|
||||
str = str.substring(str.indexOf("(") + 1);
|
||||
str = str.substring(str.indexOf('(') + 1);
|
||||
str = str.substring(0, str.length() - 1);
|
||||
return str;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ public class AspectMetadata implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the aspect class.
|
||||
* Return the aspect name.
|
||||
*/
|
||||
public String getAspectName() {
|
||||
return this.aspectName;
|
||||
|
||||
+52
-51
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -109,14 +109,40 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
|
||||
/**
|
||||
* The pointcut for Spring AOP to use. Actual behaviour of the pointcut will change
|
||||
* depending on the state of the advice.
|
||||
* The pointcut for Spring AOP to use.
|
||||
* Actual behaviour of the pointcut will change depending on the state of the advice.
|
||||
*/
|
||||
@Override
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLazy() {
|
||||
return this.lazy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAdviceInstantiated() {
|
||||
return (this.instantiatedAdvice != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily instantiate advice if necessary.
|
||||
*/
|
||||
@Override
|
||||
public synchronized Advice getAdvice() {
|
||||
if (this.instantiatedAdvice == null) {
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
}
|
||||
return this.instantiatedAdvice;
|
||||
}
|
||||
|
||||
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
|
||||
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
|
||||
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only of interest for Spring AOP: AspectJ instantiation semantics
|
||||
* are much richer. In AspectJ terminology, all a return of {@code true}
|
||||
@@ -134,33 +160,6 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
return this.aspectInstanceFactory.getAspectMetadata();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily instantiate advice if necessary.
|
||||
*/
|
||||
@Override
|
||||
public synchronized Advice getAdvice() {
|
||||
if (this.instantiatedAdvice == null) {
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
}
|
||||
return this.instantiatedAdvice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLazy() {
|
||||
return this.lazy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAdviceInstantiated() {
|
||||
return (this.instantiatedAdvice != null);
|
||||
}
|
||||
|
||||
|
||||
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
|
||||
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
|
||||
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
|
||||
}
|
||||
|
||||
public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() {
|
||||
return this.aspectInstanceFactory;
|
||||
}
|
||||
@@ -213,33 +212,26 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
}
|
||||
else {
|
||||
switch (aspectJAnnotation.getAnnotationType()) {
|
||||
case AtPointcut:
|
||||
case AtAround:
|
||||
this.isBeforeAdvice = false;
|
||||
this.isAfterAdvice = false;
|
||||
break;
|
||||
case AtBefore:
|
||||
this.isBeforeAdvice = true;
|
||||
this.isAfterAdvice = false;
|
||||
break;
|
||||
case AtAfter:
|
||||
case AtAfterReturning:
|
||||
case AtAfterThrowing:
|
||||
this.isBeforeAdvice = false;
|
||||
this.isAfterAdvice = true;
|
||||
this.isBeforeAdvice = false;
|
||||
break;
|
||||
case AtAround:
|
||||
case AtPointcut:
|
||||
this.isAfterAdvice = false;
|
||||
this.isBeforeAdvice = false;
|
||||
break;
|
||||
case AtBefore:
|
||||
this.isAfterAdvice = false;
|
||||
this.isBeforeAdvice = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
|
||||
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
|
||||
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
|
||||
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
|
||||
inputStream.defaultReadObject();
|
||||
try {
|
||||
@@ -250,11 +242,18 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
|
||||
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
|
||||
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pointcut implementation that changes its behaviour when the advice is instantiated.
|
||||
* Note that this is a <i>dynamic</i> pointcut. Otherwise it might
|
||||
* be optimized out if it does not at first match statically.
|
||||
* Note that this is a <i>dynamic</i> pointcut; otherwise it might be optimized out
|
||||
* if it does not at first match statically.
|
||||
*/
|
||||
private class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut {
|
||||
|
||||
@@ -264,8 +263,9 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
private LazySingletonAspectInstanceFactoryDecorator aspectInstanceFactory;
|
||||
|
||||
private PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut,
|
||||
public PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut,
|
||||
Pointcut preInstantiationPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
|
||||
|
||||
this.declaredPointcut = declaredPointcut;
|
||||
this.preInstantiationPointcut = preInstantiationPointcut;
|
||||
if (aspectInstanceFactory instanceof LazySingletonAspectInstanceFactoryDecorator) {
|
||||
@@ -275,7 +275,8 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
// We're either instantiated and matching on declared pointcut, or uninstantiated matching on either pointcut
|
||||
// We're either instantiated and matching on declared pointcut,
|
||||
// or uninstantiated matching on either pointcut...
|
||||
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)) ||
|
||||
this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass);
|
||||
}
|
||||
|
||||
+15
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,9 +20,9 @@ import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
@@ -131,7 +131,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
|
||||
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
|
||||
|
||||
List<Advisor> advisors = new LinkedList<Advisor>();
|
||||
List<Advisor> advisors = new ArrayList<Advisor>();
|
||||
for (Method method : getAdvisorMethods(aspectClass)) {
|
||||
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
|
||||
if (advisor != null) {
|
||||
@@ -157,7 +157,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
}
|
||||
|
||||
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
|
||||
final List<Method> methods = new LinkedList<Method>();
|
||||
final List<Method> methods = new ArrayList<Method>();
|
||||
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException {
|
||||
@@ -176,7 +176,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
* for the given introduction field.
|
||||
* <p>Resulting Advisors will need to be evaluated for targets.
|
||||
* @param introductionField the field to introspect
|
||||
* @return {@code null} if not an Advisor
|
||||
* @return the Advisor instance, or {@code null} if not an Advisor
|
||||
*/
|
||||
private Advisor getDeclareParentsAdvisor(Field introductionField) {
|
||||
DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
|
||||
@@ -253,6 +253,15 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
AbstractAspectJAdvice springAdvice;
|
||||
|
||||
switch (aspectJAnnotation.getAnnotationType()) {
|
||||
case AtPointcut:
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
|
||||
}
|
||||
return null;
|
||||
case AtAround:
|
||||
springAdvice = new AspectJAroundAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
break;
|
||||
case AtBefore:
|
||||
springAdvice = new AspectJMethodBeforeAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
@@ -277,15 +286,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
|
||||
}
|
||||
break;
|
||||
case AtAround:
|
||||
springAdvice = new AspectJAroundAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
break;
|
||||
case AtPointcut:
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
|
||||
}
|
||||
return null;
|
||||
default:
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported advice type on method: " + candidateAdviceMethod);
|
||||
@@ -299,6 +299,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
springAdvice.setArgumentNamesFromStringArray(argNames);
|
||||
}
|
||||
springAdvice.calculateArgumentBindings();
|
||||
|
||||
return springAdvice;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,11 +31,10 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* Utility class for handling registration of AOP auto-proxy creators.
|
||||
*
|
||||
* <p>Only a single auto-proxy creator can be registered yet multiple concrete
|
||||
* implementations are available. Therefore this class wraps a simple escalation
|
||||
* protocol, allowing classes to request a particular auto-proxy creator and know
|
||||
* that class, {@code or a subclass thereof}, will eventually be resident
|
||||
* in the application context.
|
||||
* <p>Only a single auto-proxy creator should be registered yet multiple concrete
|
||||
* implementations are available. This class provides a simple escalation protocol,
|
||||
* allowing a caller to request a particular auto-proxy creator and know that creator,
|
||||
* <i>or a more capable variant thereof</i>, will be registered as a post-processor.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
@@ -54,12 +53,10 @@ public abstract class AopConfigUtils {
|
||||
/**
|
||||
* Stores the auto proxy creator classes in escalation order.
|
||||
*/
|
||||
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>();
|
||||
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>(3);
|
||||
|
||||
/**
|
||||
* Setup the escalation list.
|
||||
*/
|
||||
static {
|
||||
// Set up the escalation list...
|
||||
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
|
||||
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
|
||||
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
|
||||
@@ -107,6 +104,7 @@ public abstract class AopConfigUtils {
|
||||
|
||||
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||
|
||||
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
|
||||
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
|
||||
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
|
||||
@@ -118,6 +116,7 @@ public abstract class AopConfigUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,11 +27,11 @@ import org.springframework.beans.factory.xml.ParserContext;
|
||||
* Utility class for handling registration of auto-proxy creators used internally
|
||||
* by the '{@code aop}' namespace tags.
|
||||
*
|
||||
* <p>Only a single auto-proxy creator can be registered and multiple tags may wish
|
||||
* to register different concrete implementations. As such this class delegates to
|
||||
* {@link AopConfigUtils} which wraps a simple escalation protocol. Therefore classes
|
||||
* may request a particular auto-proxy creator and know that class, <i>or a subclass
|
||||
* thereof</i>, will eventually be resident in the application context.
|
||||
* <p>Only a single auto-proxy creator should be registered and multiple configuration
|
||||
* elements may wish to register different concrete implementations. As such this class
|
||||
* delegates to {@link AopConfigUtils} which provides a simple escalation protocol.
|
||||
* Callers may request a particular auto-proxy creator and know that creator,
|
||||
* <i>or a more capable variant thereof</i>, will be registered as a post-processor.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
@@ -81,11 +81,11 @@ public abstract class AopNamespaceUtils {
|
||||
|
||||
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
|
||||
if (sourceElement != null) {
|
||||
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
|
||||
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
|
||||
if (proxyTargetClass) {
|
||||
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
|
||||
}
|
||||
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
|
||||
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
|
||||
if (exposeProxy) {
|
||||
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
|
||||
}
|
||||
@@ -94,9 +94,8 @@ public abstract class AopNamespaceUtils {
|
||||
|
||||
private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {
|
||||
if (beanDefinition != null) {
|
||||
BeanComponentDefinition componentDefinition =
|
||||
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
|
||||
parserContext.registerComponent(componentDefinition);
|
||||
parserContext.registerComponent(
|
||||
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -90,7 +90,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu
|
||||
return proxyFactory.getProxy(getProxyClassLoader());
|
||||
}
|
||||
|
||||
// No async proxy needed.
|
||||
// No proxy needed.
|
||||
return bean;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu
|
||||
* Subclasses may choose to implement this: for example,
|
||||
* to change the interfaces exposed.
|
||||
* <p>The default implementation is empty.
|
||||
* @param proxyFactory ProxyFactory that is already configured with
|
||||
* @param proxyFactory the ProxyFactory that is already configured with
|
||||
* target, advisor and interfaces and will be used to create the proxy
|
||||
* immediately after this method returns
|
||||
* @since 4.2.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,6 @@ import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -93,7 +92,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* List of Advisors. If an Advice is added, it will be wrapped
|
||||
* in an Advisor before being added to this List.
|
||||
*/
|
||||
private List<Advisor> advisors = new LinkedList<Advisor>();
|
||||
private List<Advisor> advisors = new ArrayList<Advisor>();
|
||||
|
||||
/**
|
||||
* Array updated on changes to the advisors list, which is easier
|
||||
@@ -234,7 +233,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
|
||||
@Override
|
||||
public Class<?>[] getProxiedInterfaces() {
|
||||
return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
|
||||
return ClassUtils.toClassArray(this.interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -480,7 +479,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* for the given method, based on this configuration.
|
||||
* @param method the proxied method
|
||||
* @param targetClass the target class
|
||||
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
|
||||
* @return a List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
|
||||
*/
|
||||
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
|
||||
MethodCacheKey cacheKey = new MethodCacheKey(method);
|
||||
@@ -534,7 +533,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
|
||||
/**
|
||||
* Build a configuration-only copy of this AdvisedSupport,
|
||||
* replacing the TargetSource
|
||||
* replacing the TargetSource.
|
||||
*/
|
||||
AdvisedSupport getConfigurationOnlyCopy() {
|
||||
AdvisedSupport copy = new AdvisedSupport();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -201,15 +201,13 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
return createProxyClassAndInstance(enhancer, callbacks);
|
||||
}
|
||||
catch (CodeGenerationException ex) {
|
||||
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
|
||||
this.advised.getTargetClass() + "]: " +
|
||||
"Common causes of this problem include using a final class or a non-visible class",
|
||||
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
|
||||
": Common causes of this problem include using a final class or a non-visible class",
|
||||
ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
|
||||
this.advised.getTargetClass() + "]: " +
|
||||
"Common causes of this problem include using a final class or a non-visible class",
|
||||
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
|
||||
": Common causes of this problem include using a final class or a non-visible class",
|
||||
ex);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
@@ -259,7 +257,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
Method[] methods = proxySuperClass.getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
int mod = method.getModifiers();
|
||||
if (!Modifier.isStatic(mod)) {
|
||||
if (!Modifier.isStatic(mod) && !Modifier.isPrivate(mod)) {
|
||||
if (Modifier.isFinal(mod)) {
|
||||
if (implementsInterface(method, ifcs)) {
|
||||
logger.warn("Unable to proxy interface-implementing method [" + method + "] because " +
|
||||
@@ -269,7 +267,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
"Calls to this method will NOT be routed to the target instance and " +
|
||||
"might lead to NPEs against uninitialized fields in the proxy instance.");
|
||||
}
|
||||
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && !Modifier.isPrivate(mod) &&
|
||||
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) &&
|
||||
proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) {
|
||||
logger.info("Method [" + method + "] is package-visible across different ClassLoaders " +
|
||||
"and cannot get proxied via CGLIB: Declare this method as public or protected " +
|
||||
@@ -294,20 +292,20 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
// unadvised but can return this). May be required to expose the proxy.
|
||||
Callback targetInterceptor;
|
||||
if (exposeProxy) {
|
||||
targetInterceptor = isStatic ?
|
||||
targetInterceptor = (isStatic ?
|
||||
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
|
||||
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
|
||||
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
|
||||
}
|
||||
else {
|
||||
targetInterceptor = isStatic ?
|
||||
targetInterceptor = (isStatic ?
|
||||
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
|
||||
new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
|
||||
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
|
||||
}
|
||||
|
||||
// Choose a "direct to target" dispatcher (used for
|
||||
// unadvised calls to static targets that cannot return this).
|
||||
Callback targetDispatcher = isStatic ?
|
||||
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
|
||||
Callback targetDispatcher = (isStatic ?
|
||||
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
|
||||
|
||||
Callback[] mainCallbacks = new Callback[] {
|
||||
aopInterceptor, // for normal advice
|
||||
@@ -812,12 +810,16 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
}
|
||||
// We must always proxy equals, to direct calls to this.
|
||||
if (AopUtils.isEqualsMethod(method)) {
|
||||
logger.debug("Found 'equals' method: " + method);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found 'equals' method: " + method);
|
||||
}
|
||||
return INVOKE_EQUALS;
|
||||
}
|
||||
// We must always calculate hashCode based on the proxy.
|
||||
if (AopUtils.isHashCodeMethod(method)) {
|
||||
logger.debug("Found 'hashCode' method: " + method);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found 'hashCode' method: " + method);
|
||||
}
|
||||
return INVOKE_HASHCODE;
|
||||
}
|
||||
Class<?> targetClass = this.advised.getTargetClass();
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -62,9 +62,9 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
|
||||
// Add it conditionally.
|
||||
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
|
||||
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
|
||||
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
|
||||
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
|
||||
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
|
||||
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
|
||||
if (mm.isRuntime()) {
|
||||
// Creating a new object instance in the getInterceptors() method
|
||||
// isn't a problem as we normally cache created chains.
|
||||
@@ -98,8 +98,7 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
|
||||
* Determine whether the Advisors contain matching introductions.
|
||||
*/
|
||||
private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
|
||||
for (int i = 0; i < config.getAdvisors().length; i++) {
|
||||
Advisor advisor = config.getAdvisors()[i];
|
||||
for (Advisor advisor : config.getAdvisors()) {
|
||||
if (advisor instanceof IntroductionAdvisor) {
|
||||
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
|
||||
if (ia.getClassFilter().matches(actualClass)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ public class ProxyCreatorSupport extends AdvisedSupport {
|
||||
|
||||
private AopProxyFactory aopProxyFactory;
|
||||
|
||||
private List<AdvisedSupportListener> listeners = new LinkedList<AdvisedSupportListener>();
|
||||
private final List<AdvisedSupportListener> listeners = new LinkedList<AdvisedSupportListener>();
|
||||
|
||||
/** Set to true when the first AOP proxy has been created */
|
||||
private boolean active = false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -640,7 +640,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
return this.beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,9 +50,9 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
|
||||
|
||||
|
||||
/**
|
||||
* Set the ordering which will apply to this class's implementation
|
||||
* of Ordered, used when applying multiple processors.
|
||||
* <p>Default value is {@code Integer.MAX_VALUE}, meaning that it's non-ordered.
|
||||
* Set the ordering which will apply to this processor's implementation
|
||||
* of {@link Ordered}, used when applying multiple processors.
|
||||
* <p>The default value is {@code Ordered.LOWEST_PRECEDENCE}, meaning non-ordered.
|
||||
* @param order the ordering value
|
||||
*/
|
||||
public void setOrder(int order) {
|
||||
|
||||
+10
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,15 +31,15 @@ import org.springframework.aop.Advisor;
|
||||
public interface AdvisorAdapterRegistry {
|
||||
|
||||
/**
|
||||
* Return an Advisor wrapping the given advice.
|
||||
* Return an {@link Advisor} wrapping the given advice.
|
||||
* <p>Should by default at least support
|
||||
* {@link org.aopalliance.intercept.MethodInterceptor},
|
||||
* {@link org.springframework.aop.MethodBeforeAdvice},
|
||||
* {@link org.springframework.aop.AfterReturningAdvice},
|
||||
* {@link org.springframework.aop.ThrowsAdvice}.
|
||||
* @param advice object that should be an advice
|
||||
* @return an Advisor wrapping the given advice. Never returns {@code null}.
|
||||
* If the advice parameter is an Advisor, return it.
|
||||
* @return an Advisor wrapping the given advice (never {@code null};
|
||||
* if the advice parameter is an Advisor, it is to be returned as-is)
|
||||
* @throws UnknownAdviceTypeException if no registered advisor adapter
|
||||
* can wrap the supposed advice
|
||||
*/
|
||||
@@ -48,21 +48,20 @@ public interface AdvisorAdapterRegistry {
|
||||
/**
|
||||
* Return an array of AOP Alliance MethodInterceptors to allow use of the
|
||||
* given Advisor in an interception-based framework.
|
||||
* <p>Don't worry about the pointcut associated with the Advisor,
|
||||
* if it's a PointcutAdvisor: just return an interceptor.
|
||||
* <p>Don't worry about the pointcut associated with the {@link Advisor}, if it is
|
||||
* a {@link org.springframework.aop.PointcutAdvisor}: just return an interceptor.
|
||||
* @param advisor Advisor to find an interceptor for
|
||||
* @return an array of MethodInterceptors to expose this Advisor's behavior
|
||||
* @throws UnknownAdviceTypeException if the Advisor type is
|
||||
* not understood by any registered AdvisorAdapter.
|
||||
* not understood by any registered AdvisorAdapter
|
||||
*/
|
||||
MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
|
||||
|
||||
/**
|
||||
* Register the given AdvisorAdapter. Note that it is not necessary to register
|
||||
* Register the given {@link AdvisorAdapter}. Note that it is not necessary to register
|
||||
* adapters for an AOP Alliance Interceptors or Spring Advices: these must be
|
||||
* automatically recognized by an AdvisorAdapterRegistry implementation.
|
||||
* @param adapter AdvisorAdapter that understands a particular Advisor
|
||||
* or Advice types
|
||||
* automatically recognized by an {@code AdvisorAdapterRegistry} implementation.
|
||||
* @param adapter AdvisorAdapter that understands particular Advisor or Advice types
|
||||
*/
|
||||
void registerAdvisorAdapter(AdvisorAdapter adapter);
|
||||
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,6 +31,8 @@ import org.springframework.util.Assert;
|
||||
* to use this class directly.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see MethodBeforeAdviceInterceptor
|
||||
* @see ThrowsAdviceInterceptor
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
|
||||
@@ -47,6 +49,7 @@ public class AfterReturningAdviceInterceptor implements MethodInterceptor, After
|
||||
this.advice = advice;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
Object retVal = mi.proceed();
|
||||
|
||||
+8
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import java.io.Serializable;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.BeforeAdvice;
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -30,11 +31,13 @@ import org.springframework.util.Assert;
|
||||
* to use this class directly.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see AfterReturningAdviceInterceptor
|
||||
* @see ThrowsAdviceInterceptor
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
|
||||
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
|
||||
|
||||
private MethodBeforeAdvice advice;
|
||||
private final MethodBeforeAdvice advice;
|
||||
|
||||
|
||||
/**
|
||||
@@ -46,9 +49,10 @@ public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Seriali
|
||||
this.advice = advice;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
|
||||
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
|
||||
return mi.proceed();
|
||||
}
|
||||
|
||||
|
||||
+38
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,6 +50,8 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @see MethodBeforeAdviceInterceptor
|
||||
* @see AfterReturningAdviceInterceptor
|
||||
*/
|
||||
public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
|
||||
@@ -66,9 +68,8 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
|
||||
/**
|
||||
* Create a new ThrowsAdviceInterceptor for the given ThrowsAdvice.
|
||||
* @param throwsAdvice the advice object that defines the exception
|
||||
* handler methods (usually a {@link org.springframework.aop.ThrowsAdvice}
|
||||
* implementation)
|
||||
* @param throwsAdvice the advice object that defines the exception handler methods
|
||||
* (usually a {@link org.springframework.aop.ThrowsAdvice} implementation)
|
||||
*/
|
||||
public ThrowsAdviceInterceptor(Object throwsAdvice) {
|
||||
Assert.notNull(throwsAdvice, "Advice must not be null");
|
||||
@@ -76,14 +77,17 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
|
||||
Method[] methods = throwsAdvice.getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.getName().equals(AFTER_THROWING) &&
|
||||
(method.getParameterTypes().length == 1 || method.getParameterTypes().length == 4) &&
|
||||
Throwable.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1])
|
||||
) {
|
||||
// Have an exception handler
|
||||
this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterTypes().length - 1], method);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found exception handler method: " + method);
|
||||
if (method.getName().equals(AFTER_THROWING)) {
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
if (paramTypes.length == 1 || paramTypes.length == 4) {
|
||||
Class<?> throwableParam = paramTypes[paramTypes.length - 1];
|
||||
if (Throwable.class.isAssignableFrom(throwableParam)) {
|
||||
// An exception handler to register...
|
||||
this.exceptionHandlerMap.put(throwableParam, method);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found exception handler method on throws advice: " + method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,14 +98,33 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of handler methods in this advice.
|
||||
*/
|
||||
public int getHandlerMethodCount() {
|
||||
return this.exceptionHandlerMap.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
return mi.proceed();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
Method handlerMethod = getExceptionHandler(ex);
|
||||
if (handlerMethod != null) {
|
||||
invokeHandlerMethod(mi, ex, handlerMethod);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the exception handle method. Can return null if not found.
|
||||
* Determine the exception handle method for the given exception.
|
||||
* @param exception the exception thrown
|
||||
* @return a handler for the given exception type
|
||||
* @return a handler for the given exception type, or {@code null} if none found
|
||||
*/
|
||||
private Method getExceptionHandler(Throwable exception) {
|
||||
Class<?> exceptionClass = exception.getClass();
|
||||
@@ -119,24 +142,10 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
return mi.proceed();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
Method handlerMethod = getExceptionHandler(ex);
|
||||
if (handlerMethod != null) {
|
||||
invokeHandlerMethod(mi, ex, handlerMethod);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable {
|
||||
Object[] handlerArgs;
|
||||
if (method.getParameterTypes().length == 1) {
|
||||
handlerArgs = new Object[] { ex };
|
||||
handlerArgs = new Object[] {ex};
|
||||
}
|
||||
else {
|
||||
handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex};
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -412,7 +412,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
// Found a matching TargetSource.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("TargetSourceCreator [" + tsc +
|
||||
" found custom TargetSource for bean with name '" + beanName + "'");
|
||||
"] found custom TargetSource for bean with name '" + beanName + "'");
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
@@ -553,7 +553,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
* Subclasses may choose to implement this: for example,
|
||||
* to change the interfaces exposed.
|
||||
* <p>The default implementation is empty.
|
||||
* @param proxyFactory ProxyFactory that is already configured with
|
||||
* @param proxyFactory a ProxyFactory that is already configured with
|
||||
* TargetSource and interfaces and will be used to create the proxy
|
||||
* immediately after this method returns
|
||||
*/
|
||||
|
||||
+12
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,7 @@
|
||||
|
||||
package org.springframework.aop.framework.autoproxy;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -43,7 +43,7 @@ public class BeanFactoryAdvisorRetrievalHelper {
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private String[] cachedAdvisorBeanNames;
|
||||
private volatile String[] cachedAdvisorBeanNames;
|
||||
|
||||
|
||||
/**
|
||||
@@ -64,22 +64,19 @@ public class BeanFactoryAdvisorRetrievalHelper {
|
||||
*/
|
||||
public List<Advisor> findAdvisorBeans() {
|
||||
// Determine list of advisor bean names, if not cached already.
|
||||
String[] advisorNames = null;
|
||||
synchronized (this) {
|
||||
advisorNames = this.cachedAdvisorBeanNames;
|
||||
if (advisorNames == null) {
|
||||
// Do not initialize FactoryBeans here: We need to leave all regular beans
|
||||
// uninitialized to let the auto-proxy creator apply to them!
|
||||
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||||
this.beanFactory, Advisor.class, true, false);
|
||||
this.cachedAdvisorBeanNames = advisorNames;
|
||||
}
|
||||
String[] advisorNames = this.cachedAdvisorBeanNames;
|
||||
if (advisorNames == null) {
|
||||
// Do not initialize FactoryBeans here: We need to leave all regular beans
|
||||
// uninitialized to let the auto-proxy creator apply to them!
|
||||
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||||
this.beanFactory, Advisor.class, true, false);
|
||||
this.cachedAdvisorBeanNames = advisorNames;
|
||||
}
|
||||
if (advisorNames.length == 0) {
|
||||
return new LinkedList<Advisor>();
|
||||
return new ArrayList<Advisor>();
|
||||
}
|
||||
|
||||
List<Advisor> advisors = new LinkedList<Advisor>();
|
||||
List<Advisor> advisors = new ArrayList<Advisor>();
|
||||
for (String name : advisorNames) {
|
||||
if (isEligibleBean(name)) {
|
||||
if (this.beanFactory.isCurrentlyInCreation(name)) {
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,13 +29,13 @@ import org.apache.commons.logging.LogFactory;
|
||||
*/
|
||||
public class SimpleAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
|
||||
|
||||
private final Log logger = LogFactory.getLog(SimpleAsyncUncaughtExceptionHandler.class);
|
||||
private static final Log logger = LogFactory.getLog(SimpleAsyncUncaughtExceptionHandler.class);
|
||||
|
||||
|
||||
@Override
|
||||
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error(String.format("Unexpected error occurred invoking async " +
|
||||
"method '%s'.", method), ex);
|
||||
logger.error("Unexpected error occurred invoking async method: " + method, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,7 +50,8 @@ import org.springframework.util.ClassUtils;
|
||||
* @see #setProxyTargetClass
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean<Object>, BeanFactoryAware {
|
||||
public class ScopedProxyFactoryBean extends ProxyConfig
|
||||
implements FactoryBean<Object>, BeanFactoryAware, AopInfrastructureBean {
|
||||
|
||||
/** The TargetSource that manages scoping */
|
||||
private final SimpleBeanTargetSource scopedTargetSource = new SimpleBeanTargetSource();
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -130,8 +130,9 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return ((targetClass != null && matchesPattern(ClassUtils.getQualifiedMethodName(method, targetClass))) ||
|
||||
matchesPattern(ClassUtils.getQualifiedMethodName(method)));
|
||||
return ((targetClass != null && targetClass != method.getDeclaringClass() &&
|
||||
matchesPattern(ClassUtils.getQualifiedMethodName(method, targetClass))) ||
|
||||
matchesPattern(ClassUtils.getQualifiedMethodName(method, method.getDeclaringClass())));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,7 +45,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
|
||||
|
||||
private final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
|
||||
|
||||
private int order = Integer.MAX_VALUE;
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
|
||||
|
||||
@Override
|
||||
public Class<?>[] getInterfaces() {
|
||||
return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
|
||||
return ClassUtils.toClassArray(this.interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -118,7 +118,6 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
@@ -128,7 +127,6 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
|
||||
return this.order;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Advice getAdvice() {
|
||||
return this.advice;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,8 @@ import org.springframework.aop.MethodMatcher;
|
||||
/**
|
||||
* Convenient abstract superclass for dynamic method matchers,
|
||||
* which do care about arguments at runtime.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public abstract class DynamicMethodMatcher implements MethodMatcher {
|
||||
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import org.springframework.aop.Pointcut;
|
||||
* Convenient superclass when we want to force subclasses to
|
||||
* implement MethodMatcher interface, but subclasses
|
||||
* will want to be pointcuts. The getClassFilter() method can
|
||||
* be overriden to customize ClassFilter behaviour as well.
|
||||
* be overridden to customize ClassFilter behaviour as well.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,15 +53,15 @@ public class IntroductionInfoSupport implements IntroductionInfo, Serializable {
|
||||
* due to the delegate implementing it. Call this method to exclude
|
||||
* internal interfaces from being visible at the proxy level.
|
||||
* <p>Does nothing if the interface is not implemented by the delegate.
|
||||
* @param intf the interface to suppress
|
||||
* @param ifc the interface to suppress
|
||||
*/
|
||||
public void suppressInterface(Class<?> intf) {
|
||||
this.publishedInterfaces.remove(intf);
|
||||
public void suppressInterface(Class<?> ifc) {
|
||||
this.publishedInterfaces.remove(ifc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getInterfaces() {
|
||||
return this.publishedInterfaces.toArray(new Class<?>[this.publishedInterfaces.size()]);
|
||||
return ClassUtils.toClassArray(this.publishedInterfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -94,7 +94,7 @@ public abstract class Pointcuts {
|
||||
@SuppressWarnings("serial")
|
||||
private static class SetterPointcut extends StaticMethodMatcherPointcut implements Serializable {
|
||||
|
||||
public static SetterPointcut INSTANCE = new SetterPointcut();
|
||||
public static final SetterPointcut INSTANCE = new SetterPointcut();
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
@@ -115,7 +115,7 @@ public abstract class Pointcuts {
|
||||
@SuppressWarnings("serial")
|
||||
private static class GetterPointcut extends StaticMethodMatcherPointcut implements Serializable {
|
||||
|
||||
public static GetterPointcut INSTANCE = new GetterPointcut();
|
||||
public static final GetterPointcut INSTANCE = new GetterPointcut();
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,8 @@ import java.io.Serializable;
|
||||
import org.springframework.aop.ClassFilter;
|
||||
|
||||
/**
|
||||
* Simple ClassFilter implementation that passes classes (and optionally subclasses)
|
||||
* Simple ClassFilter implementation that passes classes (and optionally subclasses).
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
@@ -37,7 +38,7 @@ public class RootClassFilter implements ClassFilter, Serializable {
|
||||
|
||||
@Override
|
||||
public boolean matches(Class<?> candidate) {
|
||||
return clazz.isAssignableFrom(candidate);
|
||||
return this.clazz.isAssignableFrom(candidate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,8 @@ import org.springframework.aop.MethodMatcher;
|
||||
/**
|
||||
* Convenient abstract superclass for static method matchers, which don't care
|
||||
* about arguments at runtime.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public abstract class StaticMethodMatcher implements MethodMatcher {
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,10 +36,10 @@ import org.springframework.util.Assert;
|
||||
public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMatcherPointcut
|
||||
implements PointcutAdvisor, Ordered, Serializable {
|
||||
|
||||
private int order = Integer.MAX_VALUE;
|
||||
|
||||
private Advice advice;
|
||||
|
||||
private int order = Integer.MAX_VALUE;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new StaticMethodMatcherPointcutAdvisor,
|
||||
|
||||
+23
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -60,7 +60,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
|
||||
private String targetBeanName;
|
||||
|
||||
/** Class of the target */
|
||||
private Class<?> targetClass;
|
||||
private volatile Class<?> targetClass;
|
||||
|
||||
/**
|
||||
* BeanFactory that owns this TargetSource. We need to hold onto this
|
||||
@@ -120,21 +120,28 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized Class<?> getTargetClass() {
|
||||
if (this.targetClass == null && this.beanFactory != null) {
|
||||
// Determine type of the target bean.
|
||||
this.targetClass = this.beanFactory.getType(this.targetBeanName);
|
||||
if (this.targetClass == null) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Getting bean with name '" + this.targetBeanName + "' in order to determine type");
|
||||
}
|
||||
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
|
||||
if (beanInstance != null) {
|
||||
this.targetClass = beanInstance.getClass();
|
||||
}
|
||||
}
|
||||
public Class<?> getTargetClass() {
|
||||
Class<?> targetClass = this.targetClass;
|
||||
if (targetClass != null) {
|
||||
return targetClass;
|
||||
}
|
||||
synchronized (this) {
|
||||
// Full check within synchronization, entering the BeanFactory interaction algorithm only once...
|
||||
targetClass = this.targetClass;
|
||||
if (targetClass == null && this.beanFactory != null) {
|
||||
// Determine type of the target bean.
|
||||
targetClass = this.beanFactory.getType(this.targetBeanName);
|
||||
if (targetClass == null) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Getting bean with name '" + this.targetBeanName + "' for type determination");
|
||||
}
|
||||
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
|
||||
targetClass = beanInstance.getClass();
|
||||
}
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
return targetClass;
|
||||
}
|
||||
return this.targetClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -74,8 +74,8 @@ public abstract class AbstractPrototypeBasedTargetSource extends AbstractBeanFac
|
||||
* @param target the bean instance to destroy
|
||||
*/
|
||||
protected void destroyPrototypeInstance(Object target) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Destroying instance of bean '" + getTargetBeanName() + "'");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Destroying instance of bean '" + getTargetBeanName() + "'");
|
||||
}
|
||||
if (getBeanFactory() instanceof ConfigurableBeanFactory) {
|
||||
((ConfigurableBeanFactory) getBeanFactory()).destroyBean(getTargetBeanName(), target);
|
||||
|
||||
+2
-2
@@ -44,7 +44,7 @@ import static org.junit.Assert.*;
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class MethodInvocationProceedingJoinPointTests {
|
||||
public class MethodInvocationProceedingJoinPointTests {
|
||||
|
||||
@Test
|
||||
public void testingBindingWithJoinPoint() {
|
||||
@@ -217,7 +217,7 @@ public final class MethodInvocationProceedingJoinPointTests {
|
||||
itb.unreliableFileOperation();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// we don't realy care...
|
||||
// we don't really care...
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-14
@@ -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.
|
||||
@@ -37,26 +37,26 @@ import static org.junit.Assert.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class ArgumentBindingTests {
|
||||
public class ArgumentBindingTests {
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testBindingInPointcutUsedByAdvice() {
|
||||
TestBean tb = new TestBean();
|
||||
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(tb);
|
||||
proxyFactory.addAspect(NamedPointcutWithArgs.class);
|
||||
|
||||
ITestBean proxiedTestBean = (ITestBean) proxyFactory.getProxy();
|
||||
proxiedTestBean.setName("Supercalifragalisticexpialidocious"); // should throw
|
||||
ITestBean proxiedTestBean = proxyFactory.getProxy();
|
||||
proxiedTestBean.setName("Supercalifragalisticexpialidocious");
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testAnnotationArgumentNameBinding() {
|
||||
TransactionalBean tb = new TransactionalBean();
|
||||
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(tb);
|
||||
proxyFactory.addAspect(PointcutWithAnnotationArgument.class);
|
||||
|
||||
ITransactionalBean proxiedTestBean = (ITransactionalBean) proxyFactory.getProxy();
|
||||
proxiedTestBean.doInTransaction(); // should throw
|
||||
ITransactionalBean proxiedTestBean = proxyFactory.getProxy();
|
||||
proxiedTestBean.doInTransaction();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,6 +71,7 @@ public final class ArgumentBindingTests {
|
||||
assertEquals("formal", pnames[0]);
|
||||
}
|
||||
|
||||
|
||||
public void methodWithOneParam(String aParam) {
|
||||
}
|
||||
|
||||
@@ -100,9 +101,6 @@ public final class ArgumentBindingTests {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@Aspect
|
||||
class PointcutWithAnnotationArgument {
|
||||
|
||||
@@ -115,9 +113,6 @@ class PointcutWithAnnotationArgument {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
@Aspect
|
||||
class NamedPointcutWithArgs {
|
||||
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,7 +47,7 @@ public final class ConcurrencyThrottleInterceptorTests {
|
||||
public void testSerializable() throws Exception {
|
||||
DerivedTestBean tb = new DerivedTestBean();
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.setInterfaces(new Class[] {ITestBean.class});
|
||||
proxyFactory.setInterfaces(ITestBean.class);
|
||||
ConcurrencyThrottleInterceptor cti = new ConcurrencyThrottleInterceptor();
|
||||
proxyFactory.addAdvice(cti);
|
||||
proxyFactory.setTarget(tb);
|
||||
@@ -75,7 +75,7 @@ public final class ConcurrencyThrottleInterceptorTests {
|
||||
private void testMultipleThreads(int concurrencyLimit) {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.setInterfaces(new Class[] {ITestBean.class});
|
||||
proxyFactory.setInterfaces(ITestBean.class);
|
||||
ConcurrencyThrottleInterceptor cti = new ConcurrencyThrottleInterceptor();
|
||||
cti.setConcurrencyLimit(concurrencyLimit);
|
||||
proxyFactory.addAdvice(cti);
|
||||
@@ -95,7 +95,7 @@ public final class ConcurrencyThrottleInterceptorTests {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
threads[i] = new ConcurrencyThread(proxy,
|
||||
i % 2 == 0 ? (Throwable) new OutOfMemoryError() : (Throwable) new IllegalStateException());
|
||||
i % 2 == 0 ? new OutOfMemoryError() : new IllegalStateException());
|
||||
threads[i].start();
|
||||
}
|
||||
for (int i = 0; i < NR_OF_THREADS; i++) {
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -83,7 +83,7 @@ public final class CustomizableTraceInterceptorTests {
|
||||
public void testSunnyDayPathLogsCorrectly() throws Throwable {
|
||||
|
||||
MethodInvocation methodInvocation = mock(MethodInvocation.class);
|
||||
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
|
||||
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString"));
|
||||
given(methodInvocation.getThis()).willReturn(this);
|
||||
|
||||
Log log = mock(Log.class);
|
||||
@@ -101,7 +101,7 @@ public final class CustomizableTraceInterceptorTests {
|
||||
MethodInvocation methodInvocation = mock(MethodInvocation.class);
|
||||
|
||||
IllegalArgumentException exception = new IllegalArgumentException();
|
||||
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
|
||||
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString"));
|
||||
given(methodInvocation.getThis()).willReturn(this);
|
||||
given(methodInvocation.proceed()).willThrow(exception);
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ public final class SimpleTraceInterceptorTests {
|
||||
@Test
|
||||
public void testSunnyDayPathLogsCorrectly() throws Throwable {
|
||||
MethodInvocation mi = mock(MethodInvocation.class);
|
||||
given(mi.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
|
||||
given(mi.getMethod()).willReturn(String.class.getMethod("toString"));
|
||||
given(mi.getThis()).willReturn(this);
|
||||
|
||||
Log log = mock(Log.class);
|
||||
@@ -48,7 +48,7 @@ public final class SimpleTraceInterceptorTests {
|
||||
@Test
|
||||
public void testExceptionPathStillLogsCorrectly() throws Throwable {
|
||||
MethodInvocation mi = mock(MethodInvocation.class);
|
||||
given(mi.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
|
||||
given(mi.getMethod()).willReturn(String.class.getMethod("toString"));
|
||||
given(mi.getThis()).willReturn(this);
|
||||
IllegalArgumentException exception = new IllegalArgumentException();
|
||||
given(mi.proceed()).willThrow(exception);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// redefine the compileJava and compileTestJava tasks in order to
|
||||
// compile sources with ajc instead of javac
|
||||
// Redefine the compileJava and compileTestJava tasks in order to compile sources with ajc instead of javac
|
||||
|
||||
configurations {
|
||||
rt
|
||||
@@ -8,22 +7,14 @@ configurations {
|
||||
ajInpath
|
||||
}
|
||||
|
||||
// exclude spring-aspects as a module within IDEA until IDEA-64446 is resolved
|
||||
tasks.getByName("idea").onlyIf { false }
|
||||
tasks.getByName("ideaModule").onlyIf { false }
|
||||
|
||||
compileJava {
|
||||
actions = []
|
||||
dependsOn configurations.ajc.getTaskDependencyFromProjectDependency(true, "compileJava")
|
||||
|
||||
def outputDir = project.sourceSets.main.output.classesDir
|
||||
|
||||
inputs.files(project.sourceSets.main.allSource + project.sourceSets.main.compileClasspath)
|
||||
outputs.dir outputDir
|
||||
|
||||
ext.sourceCompatibility = project(":spring-core").compileJava.sourceCompatibility
|
||||
ext.targetCompatibility = project(":spring-core").compileJava.targetCompatibility
|
||||
|
||||
doLast{
|
||||
// Assemble runtime classpath from folders and JARs that actually exist
|
||||
def runtimeClasspath = project.files(sourceSets.main.runtimeClasspath.files.findAll({ it.exists() }))
|
||||
@@ -53,13 +44,9 @@ compileTestJava {
|
||||
dependsOn jar
|
||||
|
||||
def outputDir = project.sourceSets.test.output.classesDir
|
||||
|
||||
inputs.files(project.sourceSets.test.allSource + project.sourceSets.test.compileClasspath)
|
||||
outputs.dir outputDir
|
||||
|
||||
ext.sourceCompatibility = project(":spring-core").compileTestJava.sourceCompatibility
|
||||
ext.targetCompatibility = project(":spring-core").compileTestJava.targetCompatibility
|
||||
|
||||
doLast{
|
||||
// Assemble runtime classpath from folders and JARs that actually exist
|
||||
def runtimeClasspath = project.files(sourceSets.test.runtimeClasspath.files.findAll({ it.exists() }))
|
||||
|
||||
Vendored
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,6 +34,7 @@ import org.springframework.context.annotation.Role;
|
||||
* @see org.springframework.cache.annotation.CachingConfigurationSelector
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
|
||||
|
||||
@Bean(name = CacheManagementConfigUtils.CACHE_ASPECT_BEAN_NAME)
|
||||
|
||||
Vendored
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,6 +34,7 @@ import org.springframework.context.annotation.Role;
|
||||
* @see org.springframework.cache.annotation.CachingConfigurationSelector
|
||||
*/
|
||||
@Configuration
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
public class AspectJJCacheConfiguration extends AbstractJCacheConfiguration {
|
||||
|
||||
@Bean(name = CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
|
||||
* @see javax.transaction.Transactional
|
||||
* @see AnnotationTransactionAspect
|
||||
*/
|
||||
@RequiredTypes({"javax.transaction.Transactional"})
|
||||
@RequiredTypes("javax.transaction.Transactional")
|
||||
public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect {
|
||||
|
||||
public JtaAnnotationTransactionAspect() {
|
||||
|
||||
+10
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,6 +237,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
|
||||
Closure beans = new Closure(this) {
|
||||
@Override
|
||||
public Object call(Object[] args) {
|
||||
invokeBeanDefiningClosure((Closure) args[0]);
|
||||
return null;
|
||||
@@ -380,10 +381,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
refName = args[0].toString();
|
||||
}
|
||||
boolean parentRef = false;
|
||||
if (args.length > 1) {
|
||||
if (args[1] instanceof Boolean) {
|
||||
parentRef = (Boolean) args[1];
|
||||
}
|
||||
if (args.length > 1 && args[1] instanceof Boolean) {
|
||||
parentRef = (Boolean) args[1];
|
||||
}
|
||||
return new RuntimeBeanReference(refName, parentRef);
|
||||
}
|
||||
@@ -410,12 +409,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
|
||||
private boolean addDeferredProperty(String property, Object newValue) {
|
||||
if (newValue instanceof List) {
|
||||
this.deferredProperties.put(this.currentBeanDefinition.getBeanName() + '.' + property,
|
||||
new DeferredProperty(this.currentBeanDefinition, property, newValue));
|
||||
return true;
|
||||
}
|
||||
else if (newValue instanceof Map) {
|
||||
if (newValue instanceof List || newValue instanceof Map) {
|
||||
this.deferredProperties.put(this.currentBeanDefinition.getBeanName() + '.' + property,
|
||||
new DeferredProperty(this.currentBeanDefinition, property, newValue));
|
||||
return true;
|
||||
@@ -527,10 +521,10 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
Closure callable = (Closure) args[args.length - 1];
|
||||
callable.setDelegate(this);
|
||||
callable.setResolveStrategy(Closure.DELEGATE_FIRST);
|
||||
callable.call(new Object[]{currentBeanDefinition});
|
||||
callable.call(this.currentBeanDefinition);
|
||||
}
|
||||
|
||||
GroovyBeanDefinitionWrapper beanDefinition = currentBeanDefinition;
|
||||
GroovyBeanDefinitionWrapper beanDefinition = this.currentBeanDefinition;
|
||||
this.currentBeanDefinition = null;
|
||||
beanDefinition.getBeanDefinition().setAttribute(GroovyBeanDefinitionWrapper.class.getName(), beanDefinition);
|
||||
getRegistry().registerBeanDefinition(beanName, beanDefinition.getBeanDefinition());
|
||||
@@ -818,14 +812,17 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invokeMethod(String name, Object args) {
|
||||
return InvokerHelper.invokeMethod(this.propertyValue, name, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
return InvokerHelper.getProperty(this.propertyValue, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String name, Object value) {
|
||||
InvokerHelper.setProperty(this.propertyValue, name, value);
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -162,6 +162,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getProperty(String property) {
|
||||
if (this.definitionWrapper.isReadableProperty(property)) {
|
||||
return this.definitionWrapper.getPropertyValue(property);
|
||||
@@ -172,6 +173,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
|
||||
return super.getProperty(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String property, Object newValue) {
|
||||
if (PARENT.equals(property)) {
|
||||
setParent(newValue);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -311,23 +311,23 @@ public abstract class BeanUtils {
|
||||
public static Method resolveSignature(String signature, Class<?> clazz) {
|
||||
Assert.hasText(signature, "'signature' must not be empty");
|
||||
Assert.notNull(clazz, "Class must not be null");
|
||||
int firstParen = signature.indexOf("(");
|
||||
int lastParen = signature.indexOf(")");
|
||||
if (firstParen > -1 && lastParen == -1) {
|
||||
int startParen = signature.indexOf('(');
|
||||
int endParen = signature.indexOf(')');
|
||||
if (startParen > -1 && endParen == -1) {
|
||||
throw new IllegalArgumentException("Invalid method signature '" + signature +
|
||||
"': expected closing ')' for args list");
|
||||
}
|
||||
else if (lastParen > -1 && firstParen == -1) {
|
||||
else if (startParen == -1 && endParen > -1) {
|
||||
throw new IllegalArgumentException("Invalid method signature '" + signature +
|
||||
"': expected opening '(' for args list");
|
||||
}
|
||||
else if (firstParen == -1 && lastParen == -1) {
|
||||
else if (startParen == -1 && endParen == -1) {
|
||||
return findMethodWithMinimalParameters(clazz, signature);
|
||||
}
|
||||
else {
|
||||
String methodName = signature.substring(0, firstParen);
|
||||
String methodName = signature.substring(0, startParen);
|
||||
String[] parameterTypeNames =
|
||||
StringUtils.commaDelimitedListToStringArray(signature.substring(firstParen + 1, lastParen));
|
||||
StringUtils.commaDelimitedListToStringArray(signature.substring(startParen + 1, endParen));
|
||||
Class<?>[] parameterTypes = new Class<?>[parameterTypeNames.length];
|
||||
for (int i = 0; i < parameterTypeNames.length; i++) {
|
||||
String parameterTypeName = parameterTypeNames[i].trim();
|
||||
@@ -506,13 +506,14 @@ public abstract class BeanUtils {
|
||||
|
||||
/**
|
||||
* Check if the given type represents a "simple" value type:
|
||||
* a primitive, a String or other CharSequence, a Number, a Date,
|
||||
* a primitive, an enum, a String or other CharSequence, a Number, a Date,
|
||||
* a URI, a URL, a Locale or a Class.
|
||||
* @param clazz the type to check
|
||||
* @return whether the given type represents a "simple" value type
|
||||
*/
|
||||
public static boolean isSimpleValueType(Class<?> clazz) {
|
||||
return (ClassUtils.isPrimitiveOrWrapper(clazz) || clazz.isEnum() ||
|
||||
return (ClassUtils.isPrimitiveOrWrapper(clazz) ||
|
||||
Enum.class.isAssignableFrom(clazz) ||
|
||||
CharSequence.class.isAssignableFrom(clazz) ||
|
||||
Number.class.isAssignableFrom(clazz) ||
|
||||
Date.class.isAssignableFrom(clazz) ||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -224,10 +224,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
@Override
|
||||
protected BeanPropertyHandler getLocalPropertyHandler(String propertyName) {
|
||||
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
|
||||
if (pd != null) {
|
||||
return new BeanPropertyHandler(pd);
|
||||
}
|
||||
return null;
|
||||
return (pd != null ? new BeanPropertyHandler(pd) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -238,8 +235,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
||||
@Override
|
||||
protected NotWritablePropertyException createNotWritablePropertyException(String propertyName) {
|
||||
PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
|
||||
throw new NotWritablePropertyException(
|
||||
getRootClass(), getNestedPath() + propertyName,
|
||||
throw new NotWritablePropertyException(getRootClass(), getNestedPath() + propertyName,
|
||||
matches.buildErrorMessage(), matches.getPossibleMatches());
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -339,10 +339,10 @@ public class CachedIntrospectionResults {
|
||||
PropertyDescriptor getPropertyDescriptor(String name) {
|
||||
PropertyDescriptor pd = this.propertyDescriptorCache.get(name);
|
||||
if (pd == null && StringUtils.hasLength(name)) {
|
||||
// Same lenient fallback checking as in PropertyTypeDescriptor...
|
||||
pd = this.propertyDescriptorCache.get(name.substring(0, 1).toLowerCase() + name.substring(1));
|
||||
// Same lenient fallback checking as in Property...
|
||||
pd = this.propertyDescriptorCache.get(StringUtils.uncapitalize(name));
|
||||
if (pd == null) {
|
||||
pd = this.propertyDescriptorCache.get(name.substring(0, 1).toUpperCase() + name.substring(1));
|
||||
pd = this.propertyDescriptorCache.get(StringUtils.capitalize(name));
|
||||
}
|
||||
}
|
||||
return (pd == null || pd instanceof GenericTypeAwarePropertyDescriptor ? pd :
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,8 +76,8 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
|
||||
Field field = ReflectionUtils.findField(getWrappedClass(), propertyName);
|
||||
if (field != null) {
|
||||
propertyHandler = new FieldPropertyHandler(field);
|
||||
this.fieldMap.put(propertyName, propertyHandler);
|
||||
}
|
||||
this.fieldMap.put(propertyName, propertyHandler);
|
||||
}
|
||||
return propertyHandler;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,7 +41,7 @@ public interface Mergeable {
|
||||
* @param parent the object to merge with
|
||||
* @return the result of the merge operation
|
||||
* @throws IllegalArgumentException if the supplied parent is {@code null}
|
||||
* @exception IllegalStateException if merging is not enabled for this instance
|
||||
* @throws IllegalStateException if merging is not enabled for this instance
|
||||
* (i.e. {@code mergeEnabled} equals {@code false}).
|
||||
*/
|
||||
Object merge(Object parent);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -262,7 +262,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
/**
|
||||
* Get the raw property value, if any.
|
||||
* @param propertyName the name to search for
|
||||
* @return the raw property value, or {@code null}
|
||||
* @return the raw property value, or {@code null} if none found
|
||||
* @since 4.0
|
||||
* @see #getPropertyValue(String)
|
||||
* @see PropertyValue#getValue()
|
||||
@@ -283,11 +283,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
for (PropertyValue newPv : this.propertyValueList) {
|
||||
// if there wasn't an old one, add it
|
||||
PropertyValue pvOld = old.getPropertyValue(newPv.getName());
|
||||
if (pvOld == null) {
|
||||
changes.addPropertyValue(newPv);
|
||||
}
|
||||
else if (!pvOld.equals(newPv)) {
|
||||
// it's changed
|
||||
if (pvOld == null || !pvOld.equals(newPv)) {
|
||||
changes.addPropertyValue(newPv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class PropertyDescriptorUtils {
|
||||
}
|
||||
|
||||
if (writeMethod != null) {
|
||||
Class<?> params[] = writeMethod.getParameterTypes();
|
||||
Class<?>[] params = writeMethod.getParameterTypes();
|
||||
if (params.length != 1) {
|
||||
throw new IntrospectionException("Bad write method arg count: " + writeMethod);
|
||||
}
|
||||
@@ -109,7 +109,7 @@ class PropertyDescriptorUtils {
|
||||
Class<?> indexedPropertyType = null;
|
||||
|
||||
if (indexedReadMethod != null) {
|
||||
Class<?> params[] = indexedReadMethod.getParameterTypes();
|
||||
Class<?>[] params = indexedReadMethod.getParameterTypes();
|
||||
if (params.length != 1) {
|
||||
throw new IntrospectionException("Bad indexed read method arg count: " + indexedReadMethod);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ class PropertyDescriptorUtils {
|
||||
}
|
||||
|
||||
if (indexedWriteMethod != null) {
|
||||
Class<?> params[] = indexedWriteMethod.getParameterTypes();
|
||||
Class<?>[] params = indexedWriteMethod.getParameterTypes();
|
||||
if (params.length != 2) {
|
||||
throw new IntrospectionException("Bad indexed write method arg count: " + indexedWriteMethod);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,8 +156,8 @@ public abstract class PropertyMatches {
|
||||
if (s2.isEmpty()) {
|
||||
return s1.length();
|
||||
}
|
||||
int d[][] = new int[s1.length() + 1][s2.length() + 1];
|
||||
|
||||
int[][] d = new int[s1.length() + 1][s2.length() + 1];
|
||||
for (int i = 0; i <= s1.length(); i++) {
|
||||
d[i][0] = i;
|
||||
}
|
||||
@@ -166,18 +166,17 @@ public abstract class PropertyMatches {
|
||||
}
|
||||
|
||||
for (int i = 1; i <= s1.length(); i++) {
|
||||
char s_i = s1.charAt(i - 1);
|
||||
char c1 = s1.charAt(i - 1);
|
||||
for (int j = 1; j <= s2.length(); j++) {
|
||||
int cost;
|
||||
char t_j = s2.charAt(j - 1);
|
||||
if (s_i == t_j) {
|
||||
char c2 = s2.charAt(j - 1);
|
||||
if (c1 == c2) {
|
||||
cost = 0;
|
||||
}
|
||||
else {
|
||||
cost = 1;
|
||||
}
|
||||
d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1),
|
||||
d[i - 1][j - 1] + cost);
|
||||
d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1), d[i - 1][j - 1] + cost);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,24 +189,23 @@ public abstract class PropertyMatches {
|
||||
private static class BeanPropertyMatches extends PropertyMatches {
|
||||
|
||||
public BeanPropertyMatches(String propertyName, Class<?> beanClass, int maxDistance) {
|
||||
super(propertyName, calculateMatches(propertyName,
|
||||
BeanUtils.getPropertyDescriptors(beanClass), maxDistance));
|
||||
super(propertyName,
|
||||
calculateMatches(propertyName, BeanUtils.getPropertyDescriptors(beanClass), maxDistance));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate possible property alternatives for the given property and
|
||||
* class. Internally uses the {@code getStringDistance} method, which
|
||||
* in turn uses the Levenshtein algorithm to determine the distance between
|
||||
* two Strings.
|
||||
* @param propertyDescriptors the JavaBeans property descriptors to search
|
||||
* Generate possible property alternatives for the given property and class.
|
||||
* Internally uses the {@code getStringDistance} method, which in turn uses
|
||||
* the Levenshtein algorithm to determine the distance between two Strings.
|
||||
* @param descriptors the JavaBeans property descriptors to search
|
||||
* @param maxDistance the maximum distance to accept
|
||||
*/
|
||||
private static String[] calculateMatches(String propertyName, PropertyDescriptor[] propertyDescriptors, int maxDistance) {
|
||||
private static String[] calculateMatches(String name, PropertyDescriptor[] descriptors, int maxDistance) {
|
||||
List<String> candidates = new ArrayList<String>();
|
||||
for (PropertyDescriptor pd : propertyDescriptors) {
|
||||
for (PropertyDescriptor pd : descriptors) {
|
||||
if (pd.getWriteMethod() != null) {
|
||||
String possibleAlternative = pd.getName();
|
||||
if (calculateStringDistance(propertyName, possibleAlternative) <= maxDistance) {
|
||||
if (calculateStringDistance(name, possibleAlternative) <= maxDistance) {
|
||||
candidates.add(possibleAlternative);
|
||||
}
|
||||
}
|
||||
@@ -216,21 +214,16 @@ public abstract class PropertyMatches {
|
||||
return StringUtils.toStringArray(candidates);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String buildErrorMessage() {
|
||||
String propertyName = getPropertyName();
|
||||
String[] possibleMatches = getPossibleMatches();
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Bean property '");
|
||||
msg.append(propertyName);
|
||||
msg.append("' is not writable or has an invalid setter method. ");
|
||||
|
||||
if (ObjectUtils.isEmpty(possibleMatches)) {
|
||||
msg.append("Does the parameter type of the setter match the return type of the getter?");
|
||||
StringBuilder msg = new StringBuilder(160);
|
||||
msg.append("Bean property '").append(getPropertyName()).append(
|
||||
"' is not writable or has an invalid setter method. ");
|
||||
if (!ObjectUtils.isEmpty(getPossibleMatches())) {
|
||||
appendHintMessage(msg);
|
||||
}
|
||||
else {
|
||||
appendHintMessage(msg);
|
||||
msg.append("Does the parameter type of the setter match the return type of the getter?");
|
||||
}
|
||||
return msg.toString();
|
||||
}
|
||||
@@ -243,13 +236,13 @@ public abstract class PropertyMatches {
|
||||
super(propertyName, calculateMatches(propertyName, beanClass, maxDistance));
|
||||
}
|
||||
|
||||
private static String[] calculateMatches(final String propertyName, Class<?> beanClass, final int maxDistance) {
|
||||
private static String[] calculateMatches(final String name, Class<?> clazz, final int maxDistance) {
|
||||
final List<String> candidates = new ArrayList<String>();
|
||||
ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() {
|
||||
ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
|
||||
@Override
|
||||
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
|
||||
String possibleAlternative = field.getName();
|
||||
if (calculateStringDistance(propertyName, possibleAlternative) <= maxDistance) {
|
||||
if (calculateStringDistance(name, possibleAlternative) <= maxDistance) {
|
||||
candidates.add(possibleAlternative);
|
||||
}
|
||||
}
|
||||
@@ -260,14 +253,10 @@ public abstract class PropertyMatches {
|
||||
|
||||
@Override
|
||||
public String buildErrorMessage() {
|
||||
String propertyName = getPropertyName();
|
||||
String[] possibleMatches = getPossibleMatches();
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Bean property '");
|
||||
msg.append(propertyName);
|
||||
msg.append("' has no matching field. ");
|
||||
|
||||
if (!ObjectUtils.isEmpty(possibleMatches)) {
|
||||
StringBuilder msg = new StringBuilder(80);
|
||||
msg.append("Bean property '").append(getPropertyName()).append("' has no matching field.");
|
||||
if (!ObjectUtils.isEmpty(getPossibleMatches())) {
|
||||
msg.append(' ');
|
||||
appendHintMessage(msg);
|
||||
}
|
||||
return msg.toString();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,7 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.NumberUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -324,7 +325,7 @@ class TypeConverterDelegate {
|
||||
|
||||
if (Enum.class == requiredType) {
|
||||
// target type is declared as raw enum, treat the trimmed value as <enum.fqn>.FIELD_NAME
|
||||
int index = trimmedValue.lastIndexOf(".");
|
||||
int index = trimmedValue.lastIndexOf('.');
|
||||
if (index > - 1) {
|
||||
String enumType = trimmedValue.substring(0, index);
|
||||
String fieldName = trimmedValue.substring(index + 1);
|
||||
@@ -353,6 +354,7 @@ class TypeConverterDelegate {
|
||||
// to be checked, hence we don't return it right away.
|
||||
try {
|
||||
Field enumField = requiredType.getField(trimmedValue);
|
||||
ReflectionUtils.makeAccessible(enumField);
|
||||
convertedValue = enumField.get(null);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,7 +41,7 @@ public class TypeMismatchException extends PropertyAccessException {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new TypeMismatchException.
|
||||
* Create a new {@code TypeMismatchException}.
|
||||
* @param propertyChangeEvent the PropertyChangeEvent that resulted in the problem
|
||||
* @param requiredType the required target type
|
||||
*/
|
||||
@@ -50,7 +50,7 @@ public class TypeMismatchException extends PropertyAccessException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new TypeMismatchException.
|
||||
* Create a new {@code TypeMismatchException}.
|
||||
* @param propertyChangeEvent the PropertyChangeEvent that resulted in the problem
|
||||
* @param requiredType the required target type (or {@code null} if not known)
|
||||
* @param cause the root cause (may be {@code null})
|
||||
@@ -69,7 +69,7 @@ public class TypeMismatchException extends PropertyAccessException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new TypeMismatchException without PropertyChangeEvent.
|
||||
* Create a new {@code TypeMismatchException} without a {@code PropertyChangeEvent}.
|
||||
* @param value the offending value that couldn't be converted (may be {@code null})
|
||||
* @param requiredType the required target type (or {@code null} if not known)
|
||||
*/
|
||||
@@ -78,7 +78,7 @@ public class TypeMismatchException extends PropertyAccessException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new TypeMismatchException without PropertyChangeEvent.
|
||||
* Create a new {@code TypeMismatchException} without a {@code PropertyChangeEvent}.
|
||||
* @param value the offending value that couldn't be converted (may be {@code null})
|
||||
* @param requiredType the required target type (or {@code null} if not known)
|
||||
* @param cause the root cause (may be {@code null})
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -75,7 +75,7 @@ public class BeanDefinitionStoreException extends FatalBeanException {
|
||||
/**
|
||||
* Create a new BeanDefinitionStoreException.
|
||||
* @param resourceDescription description of the resource that the bean definition came from
|
||||
* @param beanName the name of the bean requested
|
||||
* @param beanName the name of the bean
|
||||
* @param msg the detail message (appended to an introductory message that indicates
|
||||
* the resource and the name of the bean)
|
||||
*/
|
||||
@@ -86,28 +86,28 @@ public class BeanDefinitionStoreException extends FatalBeanException {
|
||||
/**
|
||||
* Create a new BeanDefinitionStoreException.
|
||||
* @param resourceDescription description of the resource that the bean definition came from
|
||||
* @param beanName the name of the bean requested
|
||||
* @param beanName the name of the bean
|
||||
* @param msg the detail message (appended to an introductory message that indicates
|
||||
* the resource and the name of the bean)
|
||||
* @param cause the root cause (may be {@code null})
|
||||
*/
|
||||
public BeanDefinitionStoreException(String resourceDescription, String beanName, String msg, Throwable cause) {
|
||||
super("Invalid bean definition with name '" + beanName + "' defined in " + resourceDescription + ": " + msg, cause);
|
||||
super("Invalid bean definition with name '" + beanName + "' defined in " + resourceDescription + ": " + msg,
|
||||
cause);
|
||||
this.resourceDescription = resourceDescription;
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the description of the resource that the bean
|
||||
* definition came from, if any.
|
||||
* Return the description of the resource that the bean definition came from, if available.
|
||||
*/
|
||||
public String getResourceDescription() {
|
||||
return this.resourceDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the bean requested, if any.
|
||||
* Return the name of the bean, if available.
|
||||
*/
|
||||
public String getBeanName() {
|
||||
return this.beanName;
|
||||
|
||||
+30
-28
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -147,14 +147,7 @@ public abstract class BeanFactoryUtils {
|
||||
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
|
||||
String[] parentResult = beanNamesForTypeIncludingAncestors(
|
||||
(ListableBeanFactory) hbf.getParentBeanFactory(), type);
|
||||
List<String> resultList = new ArrayList<String>();
|
||||
resultList.addAll(Arrays.asList(result));
|
||||
for (String beanName : parentResult) {
|
||||
if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) {
|
||||
resultList.add(beanName);
|
||||
}
|
||||
}
|
||||
result = StringUtils.toStringArray(resultList);
|
||||
result = mergeNamesWithParent(result, parentResult, hbf);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -180,14 +173,7 @@ public abstract class BeanFactoryUtils {
|
||||
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
|
||||
String[] parentResult = beanNamesForTypeIncludingAncestors(
|
||||
(ListableBeanFactory) hbf.getParentBeanFactory(), type);
|
||||
List<String> resultList = new ArrayList<String>();
|
||||
resultList.addAll(Arrays.asList(result));
|
||||
for (String beanName : parentResult) {
|
||||
if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) {
|
||||
resultList.add(beanName);
|
||||
}
|
||||
}
|
||||
result = StringUtils.toStringArray(resultList);
|
||||
result = mergeNamesWithParent(result, parentResult, hbf);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -223,14 +209,7 @@ public abstract class BeanFactoryUtils {
|
||||
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
|
||||
String[] parentResult = beanNamesForTypeIncludingAncestors(
|
||||
(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
|
||||
List<String> resultList = new ArrayList<String>();
|
||||
resultList.addAll(Arrays.asList(result));
|
||||
for (String beanName : parentResult) {
|
||||
if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) {
|
||||
resultList.add(beanName);
|
||||
}
|
||||
}
|
||||
result = StringUtils.toStringArray(resultList);
|
||||
result = mergeNamesWithParent(result, parentResult, hbf);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -446,6 +425,29 @@ public abstract class BeanFactoryUtils {
|
||||
return uniqueBean(type, beansOfType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Merge the given bean names result with the given parent result.
|
||||
* @param result the local bean name result
|
||||
* @param parentResult the parent bean name result (possibly empty)
|
||||
* @param hbf the local bean factory
|
||||
* @return the merged result (possibly the local result as-is)
|
||||
* @since 4.3.15
|
||||
*/
|
||||
private static String[] mergeNamesWithParent(String[] result, String[] parentResult, HierarchicalBeanFactory hbf) {
|
||||
if (parentResult.length == 0) {
|
||||
return result;
|
||||
}
|
||||
List<String> merged = new ArrayList<String>(result.length + parentResult.length);
|
||||
merged.addAll(Arrays.asList(result));
|
||||
for (String beanName : parentResult) {
|
||||
if (!merged.contains(beanName) && !hbf.containsLocalBean(beanName)) {
|
||||
merged.add(beanName);
|
||||
}
|
||||
}
|
||||
return StringUtils.toStringArray(merged);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a unique bean for the given type from the given Map of matching beans.
|
||||
* @param type type of bean to match
|
||||
@@ -455,11 +457,11 @@ public abstract class BeanFactoryUtils {
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
*/
|
||||
private static <T> T uniqueBean(Class<T> type, Map<String, T> matchingBeans) {
|
||||
int nrFound = matchingBeans.size();
|
||||
if (nrFound == 1) {
|
||||
int count = matchingBeans.size();
|
||||
if (count == 1) {
|
||||
return matchingBeans.values().iterator().next();
|
||||
}
|
||||
else if (nrFound > 1) {
|
||||
else if (count > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
|
||||
}
|
||||
else {
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ public class CannotLoadBeanClassException extends FatalBeanException {
|
||||
public CannotLoadBeanClassException(
|
||||
String resourceDescription, String beanName, String beanClassName, ClassNotFoundException cause) {
|
||||
|
||||
super("Cannot find class [" + String.valueOf(beanClassName) + "] for bean with name '" + beanName + "'" +
|
||||
super("Cannot find class [" + beanClassName + "] for bean with name '" + beanName + "'" +
|
||||
(resourceDescription != null ? " defined in " + resourceDescription : ""), cause);
|
||||
this.resourceDescription = resourceDescription;
|
||||
this.beanName = beanName;
|
||||
@@ -64,7 +64,7 @@ public class CannotLoadBeanClassException extends FatalBeanException {
|
||||
public CannotLoadBeanClassException(
|
||||
String resourceDescription, String beanName, String beanClassName, LinkageError cause) {
|
||||
|
||||
super("Error loading class [" + String.valueOf(beanClassName) + "] for bean with name '" + beanName + "'" +
|
||||
super("Error loading class [" + beanClassName + "] for bean with name '" + beanName + "'" +
|
||||
(resourceDescription != null ? " defined in " + resourceDescription : "") +
|
||||
": problem with class file or dependent class", cause);
|
||||
this.resourceDescription = resourceDescription;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,27 +17,29 @@
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by beans that want to release resources
|
||||
* on destruction. A BeanFactory is supposed to invoke the destroy
|
||||
* method if it disposes a cached singleton. An application context
|
||||
* is supposed to dispose all of its singletons on close.
|
||||
* Interface to be implemented by beans that want to release resources on destruction.
|
||||
* A {@link BeanFactory} will invoke the destroy method on individual destruction of a
|
||||
* scoped bean. An {@link org.springframework.context.ApplicationContext} is supposed
|
||||
* to dispose all of its singletons on shutdown, driven by the application lifecycle.
|
||||
*
|
||||
* <p>An alternative to implementing DisposableBean is specifying a custom
|
||||
* destroy-method, for example in an XML bean definition.
|
||||
* For a list of all bean lifecycle methods, see the BeanFactory javadocs.
|
||||
* <p>A Spring-managed bean may also implement Java's {@link AutoCloseable} interface
|
||||
* for the same purpose. An alternative to implementing an interface is specifying a
|
||||
* custom destroy method, for example in an XML bean definition. For a list of all
|
||||
* bean lifecycle methods, see the {@link BeanFactory BeanFactory javadocs}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 12.08.2003
|
||||
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
|
||||
* @see org.springframework.context.ConfigurableApplicationContext#close
|
||||
* @see InitializingBean
|
||||
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName()
|
||||
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
|
||||
* @see org.springframework.context.ConfigurableApplicationContext#close()
|
||||
*/
|
||||
public interface DisposableBean {
|
||||
|
||||
/**
|
||||
* Invoked by a BeanFactory on destruction of a singleton.
|
||||
* @throws Exception in case of shutdown errors.
|
||||
* Exceptions will get logged but not rethrown to allow
|
||||
* other beans to release their resources too.
|
||||
* Invoked by the containing {@code BeanFactory} on destruction of a bean.
|
||||
* @throws Exception in case of shutdown errors. Exceptions will get logged
|
||||
* but not rethrown to allow other beans to release their resources as well.
|
||||
*/
|
||||
void destroy() throws Exception;
|
||||
|
||||
|
||||
+17
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,31 +17,29 @@
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by beans that need to react once all their
|
||||
* properties have been set by a BeanFactory: for example, to perform custom
|
||||
* initialization, or merely to check that all mandatory properties have been set.
|
||||
* Interface to be implemented by beans that need to react once all their properties
|
||||
* have been set by a {@link BeanFactory}: e.g. to perform custom initialization,
|
||||
* or merely to check that all mandatory properties have been set.
|
||||
*
|
||||
* <p>An alternative to implementing InitializingBean is specifying a custom
|
||||
* init-method, for example in an XML bean definition.
|
||||
* For a list of all bean lifecycle methods, see the BeanFactory javadocs.
|
||||
* <p>An alternative to implementing {@code InitializingBean} is specifying a custom
|
||||
* init method, for example in an XML bean definition. For a list of all bean
|
||||
* lifecycle methods, see the {@link BeanFactory BeanFactory javadocs}.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see BeanNameAware
|
||||
* @see BeanFactoryAware
|
||||
* @see BeanFactory
|
||||
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
|
||||
* @see org.springframework.context.ApplicationContextAware
|
||||
* @author Juergen Hoeller
|
||||
* @see DisposableBean
|
||||
* @see org.springframework.beans.factory.config.BeanDefinition#getPropertyValues()
|
||||
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getInitMethodName()
|
||||
*/
|
||||
public interface InitializingBean {
|
||||
|
||||
/**
|
||||
* Invoked by a BeanFactory after it has set all bean properties supplied
|
||||
* (and satisfied BeanFactoryAware and ApplicationContextAware).
|
||||
* <p>This method allows the bean instance to perform initialization only
|
||||
* possible when all bean properties have been set and to throw an
|
||||
* exception in the event of misconfiguration.
|
||||
* @throws Exception in the event of misconfiguration (such
|
||||
* as failure to set an essential property) or if initialization fails.
|
||||
* Invoked by the containing {@code BeanFactory} after it has set all bean properties
|
||||
* and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
|
||||
* <p>This method allows the bean instance to perform validation of its overall
|
||||
* configuration and final initialization when all bean properties have been set.
|
||||
* @throws Exception in the event of misconfiguration (such as failure to set an
|
||||
* essential property) or if initialization fails for any other reason
|
||||
*/
|
||||
void afterPropertiesSet() throws Exception;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author 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 interface ObjectFactory<T> {
|
||||
/**
|
||||
* Return an instance (possibly shared or independent)
|
||||
* of the object managed by this factory.
|
||||
* @return an instance of the bean (should never be {@code null})
|
||||
* @return the resulting instance
|
||||
* @throws BeansException in case of creation errors
|
||||
*/
|
||||
T getObject() throws BeansException;
|
||||
|
||||
+7
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -120,7 +120,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes =
|
||||
new LinkedHashSet<Class<? extends Annotation>>();
|
||||
new LinkedHashSet<Class<? extends Annotation>>(4);
|
||||
|
||||
private String requiredParameterName = "required";
|
||||
|
||||
@@ -484,7 +484,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
}
|
||||
|
||||
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
|
||||
if (ao.getAnnotations().length > 0) {
|
||||
if (ao.getAnnotations().length > 0) { // autowiring annotations have to be local
|
||||
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
|
||||
if (attributes != null) {
|
||||
@@ -594,11 +594,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
registerDependentBeans(beanName, autowiredBeanNames);
|
||||
if (autowiredBeanNames.size() == 1) {
|
||||
String autowiredBeanName = autowiredBeanNames.iterator().next();
|
||||
if (beanFactory.containsBean(autowiredBeanName)) {
|
||||
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
|
||||
this.cachedFieldValue = new ShortcutDependencyDescriptor(
|
||||
desc, autowiredBeanName, field.getType());
|
||||
}
|
||||
if (beanFactory.containsBean(autowiredBeanName) &&
|
||||
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
|
||||
this.cachedFieldValue = new ShortcutDependencyDescriptor(
|
||||
desc, autowiredBeanName, field.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -80,9 +80,8 @@ public class InjectionMetadata {
|
||||
Collection<InjectedElement> elementsToIterate =
|
||||
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
|
||||
if (!elementsToIterate.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (InjectedElement element : elementsToIterate) {
|
||||
if (debug) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
|
||||
}
|
||||
element.inject(target, beanName, pvs);
|
||||
@@ -109,7 +108,10 @@ public class InjectionMetadata {
|
||||
}
|
||||
|
||||
|
||||
public static abstract class InjectedElement {
|
||||
/**
|
||||
* A single injected element.
|
||||
*/
|
||||
public abstract static class InjectedElement {
|
||||
|
||||
protected final Member member;
|
||||
|
||||
@@ -216,6 +218,7 @@ public class InjectionMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear property skipping for this element.
|
||||
* @since 3.2.13
|
||||
*/
|
||||
protected void clearPropertySkipping(PropertyValues pvs) {
|
||||
|
||||
+7
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -342,10 +342,12 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||
* Determine a suggested value from any of the given candidate annotations.
|
||||
*/
|
||||
protected Object findValue(Annotation[] annotationsToSearch) {
|
||||
AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
|
||||
AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
|
||||
if (attr != null) {
|
||||
return extractValue(attr);
|
||||
if (annotationsToSearch.length > 0) { // qualifier annotations have to be local
|
||||
AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
|
||||
AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
|
||||
if (attr != null) {
|
||||
return extractValue(attr);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,8 +55,8 @@ import org.springframework.util.Assert;
|
||||
* and obviates the need (<b>in part</b>) for a developer to code a method that
|
||||
* simply checks that all required properties have actually been set.
|
||||
*
|
||||
* <p>Please note that an 'init' method may still need to implemented (and may
|
||||
* still be desirable), because all that this class does is enforce that a
|
||||
* <p>Please note that an 'init' method may still need to be implemented (and may
|
||||
* still be desirable), because all that this class does is enforcing that a
|
||||
* 'required' property has actually been configured with a value. It does
|
||||
* <b>not</b> check anything else... In particular, it does not check that a
|
||||
* configured value is not {@code null}.
|
||||
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,6 +33,7 @@ import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.FactoryBeanNotInitializedException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -153,7 +154,7 @@ public abstract class AbstractFactoryBean<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine an 'eager singleton' instance, exposed in case of a
|
||||
* Determine an 'early singleton' instance, exposed in case of a
|
||||
* circular reference. Not called in a non-circular scenario.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -176,9 +177,7 @@ public abstract class AbstractFactoryBean<T>
|
||||
* @throws IllegalStateException if the singleton instance is not initialized
|
||||
*/
|
||||
private T getSingletonInstance() throws IllegalStateException {
|
||||
if (!this.initialized) {
|
||||
throw new IllegalStateException("Singleton instance not initialized yet");
|
||||
}
|
||||
Assert.state(this.initialized, "Singleton instance not initialized yet");
|
||||
return this.singletonInstance;
|
||||
}
|
||||
|
||||
@@ -218,7 +217,7 @@ public abstract class AbstractFactoryBean<T>
|
||||
* FactoryBean is supposed to implement, for use with an 'early singleton
|
||||
* proxy' that will be exposed in case of a circular reference.
|
||||
* <p>The default implementation returns this FactoryBean's object type,
|
||||
* provided that it is an interface, or {@code null} else. The latter
|
||||
* provided that it is an interface, or {@code null} otherwise. The latter
|
||||
* indicates that early singleton access is not supported by this FactoryBean.
|
||||
* This will lead to a FactoryBeanNotInitializedException getting thrown.
|
||||
* @return the interfaces to use for 'early singletons',
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -253,7 +253,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
/**
|
||||
* Return whether a fallback match is allowed.
|
||||
* <p>This is {@code false} by default but may be overridden to return {@code true} in order
|
||||
* to suggest to a {@link org.springframework.beans.factory.support.AutowireCandidateResolver}
|
||||
* to suggest to an {@link org.springframework.beans.factory.support.AutowireCandidateResolver}
|
||||
* that a fallback match is acceptable as well.
|
||||
* @since 4.0
|
||||
*/
|
||||
@@ -308,7 +308,6 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
||||
Type[] args = ((ParameterizedType) type).getActualTypeArguments();
|
||||
type = args[args.length - 1];
|
||||
}
|
||||
// TODO: Object.class if unresolvable
|
||||
}
|
||||
if (type instanceof Class) {
|
||||
return (Class<?>) type;
|
||||
|
||||
+8
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,16 +30,16 @@ import org.springframework.beans.BeansException;
|
||||
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
|
||||
|
||||
/**
|
||||
* Apply this BeanPostProcessor to the given bean instance before
|
||||
* its destruction. Can invoke custom destruction callbacks.
|
||||
* <p>Like DisposableBean's {@code destroy} and a custom destroy method,
|
||||
* this callback just applies to singleton beans in the factory (including
|
||||
* inner beans).
|
||||
* Apply this BeanPostProcessor to the given bean instance before its
|
||||
* destruction, e.g. invoking custom destruction callbacks.
|
||||
* <p>Like DisposableBean's {@code destroy} and a custom destroy method, this
|
||||
* callback will only apply to beans which the container fully manages the
|
||||
* lifecycle for. This is usually the case for singletons and scoped beans.
|
||||
* @param bean the bean instance to be destroyed
|
||||
* @param beanName the name of the bean
|
||||
* @throws org.springframework.beans.BeansException in case of errors
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#setDestroyMethodName
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#setDestroyMethodName(String)
|
||||
*/
|
||||
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
|
||||
|
||||
|
||||
+9
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,6 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -77,15 +76,16 @@ public abstract class YamlProcessor {
|
||||
* name: My Cool App
|
||||
* </pre>
|
||||
* when mapped with
|
||||
* <code>documentMatchers = YamlProcessor.mapMatcher({"environment": "prod"})</code>
|
||||
* <pre class="code">
|
||||
* setDocumentMatchers(properties ->
|
||||
* ("prod".equals(properties.getProperty("environment")) ? MatchStatus.FOUND : MatchStatus.NOT_FOUND));
|
||||
* </pre>
|
||||
* would end up as
|
||||
* <pre class="code">
|
||||
* environment=prod
|
||||
* url=http://foo.bar.com
|
||||
* name=My Cool App
|
||||
* url=http://dev.bar.com
|
||||
* </pre>
|
||||
* @param matchers a map of keys to value patterns (regular expressions)
|
||||
*/
|
||||
public void setDocumentMatchers(DocumentMatcher... matchers) {
|
||||
this.documentMatchers = Arrays.asList(matchers);
|
||||
@@ -94,8 +94,7 @@ public abstract class YamlProcessor {
|
||||
/**
|
||||
* Flag indicating that a document for which all the
|
||||
* {@link #setDocumentMatchers(DocumentMatcher...) document matchers} abstain will
|
||||
* nevertheless match.
|
||||
* @param matchDefault the flag to set (default true)
|
||||
* nevertheless match. Default is {@code true}.
|
||||
*/
|
||||
public void setMatchDefault(boolean matchDefault) {
|
||||
this.matchDefault = matchDefault;
|
||||
@@ -104,9 +103,7 @@ public abstract class YamlProcessor {
|
||||
/**
|
||||
* Method to use for resolving resources. Each resource will be converted to a Map,
|
||||
* so this property is used to decide which map entries to keep in the final output
|
||||
* from this factory.
|
||||
* @param resolutionMethod the resolution method to set (defaults to
|
||||
* {@link ResolutionMethod#OVERRIDE}).
|
||||
* from this factory. Default is {@link ResolutionMethod#OVERRIDE}.
|
||||
*/
|
||||
public void setResolutionMethod(ResolutionMethod resolutionMethod) {
|
||||
Assert.notNull(resolutionMethod, "ResolutionMethod must not be null");
|
||||
@@ -201,7 +198,7 @@ public abstract class YamlProcessor {
|
||||
}
|
||||
|
||||
Map<Object, Object> map = (Map<Object, Object>) object;
|
||||
for (Entry<Object, Object> entry : map.entrySet()) {
|
||||
for (Map.Entry<Object, Object> entry : map.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Map) {
|
||||
value = asMap(value);
|
||||
@@ -273,7 +270,7 @@ public abstract class YamlProcessor {
|
||||
}
|
||||
|
||||
private void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) {
|
||||
for (Entry<String, Object> entry : source.entrySet()) {
|
||||
for (Map.Entry<String, Object> entry : source.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (StringUtils.hasText(path)) {
|
||||
if (key.startsWith("[")) {
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ import org.springframework.beans.factory.config.BeanReference;
|
||||
* all {@link BeanReference BeanReferences} that are required to validate the configuration of the
|
||||
* overall logical entity as well as those required to provide full user visualisation of the configuration.
|
||||
* It is expected that certain {@link BeanReference BeanReferences} will not be important to
|
||||
* validation or to the user view of the configuration and as such these may be ommitted. A tool may wish to
|
||||
* validation or to the user view of the configuration and as such these may be omitted. A tool may wish to
|
||||
* display any additional {@link BeanReference BeanReferences} sourced through the supplied
|
||||
* {@link BeanDefinition BeanDefinitions} but this is not considered to be a typical case.
|
||||
*
|
||||
|
||||
+57
-42
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,9 +31,7 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -146,7 +144,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();
|
||||
|
||||
/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
|
||||
private final Map<String, BeanWrapper> factoryBeanInstanceCache =
|
||||
private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache =
|
||||
new ConcurrentHashMap<String, BeanWrapper>(16);
|
||||
|
||||
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
|
||||
@@ -405,8 +403,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
throws BeansException {
|
||||
|
||||
Object result = existingBean;
|
||||
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
|
||||
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
|
||||
for (BeanPostProcessor processor : getBeanPostProcessors()) {
|
||||
result = processor.postProcessBeforeInitialization(result, beanName);
|
||||
if (result == null) {
|
||||
return result;
|
||||
}
|
||||
@@ -419,8 +417,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
throws BeansException {
|
||||
|
||||
Object result = existingBean;
|
||||
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
|
||||
result = beanProcessor.postProcessAfterInitialization(result, beanName);
|
||||
for (BeanPostProcessor processor : getBeanPostProcessors()) {
|
||||
result = processor.postProcessAfterInitialization(result, beanName);
|
||||
if (result == null) {
|
||||
return result;
|
||||
}
|
||||
@@ -695,19 +693,18 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
Method uniqueCandidate = null;
|
||||
int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount();
|
||||
Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass);
|
||||
for (Method factoryMethod : candidates) {
|
||||
if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic &&
|
||||
factoryMethod.getName().equals(mbd.getFactoryMethodName()) &&
|
||||
factoryMethod.getParameterTypes().length >= minNrOfArgs) {
|
||||
for (Method candidate : candidates) {
|
||||
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate) &&
|
||||
candidate.getParameterTypes().length >= minNrOfArgs) {
|
||||
// Declared type variables to inspect?
|
||||
if (factoryMethod.getTypeParameters().length > 0) {
|
||||
if (candidate.getTypeParameters().length > 0) {
|
||||
try {
|
||||
// Fully resolve parameter names and argument values.
|
||||
Class<?>[] paramTypes = factoryMethod.getParameterTypes();
|
||||
Class<?>[] paramTypes = candidate.getParameterTypes();
|
||||
String[] paramNames = null;
|
||||
ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
|
||||
if (pnd != null) {
|
||||
paramNames = pnd.getParameterNames(factoryMethod);
|
||||
paramNames = pnd.getParameterNames(candidate);
|
||||
}
|
||||
ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
|
||||
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
|
||||
@@ -725,9 +722,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
}
|
||||
Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod(
|
||||
factoryMethod, args, getBeanClassLoader());
|
||||
candidate, args, getBeanClassLoader());
|
||||
if (returnType != null) {
|
||||
uniqueCandidate = (commonType == null ? factoryMethod : null);
|
||||
uniqueCandidate = (commonType == null && returnType == candidate.getReturnType() ?
|
||||
candidate : null);
|
||||
commonType = ClassUtils.determineCommonAncestor(returnType, commonType);
|
||||
if (commonType == null) {
|
||||
// Ambiguous return types found: return null to indicate "not determinable".
|
||||
@@ -742,8 +740,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
}
|
||||
else {
|
||||
uniqueCandidate = (commonType == null ? factoryMethod : null);
|
||||
commonType = ClassUtils.determineCommonAncestor(factoryMethod.getReturnType(), commonType);
|
||||
uniqueCandidate = (commonType == null ? candidate : null);
|
||||
commonType = ClassUtils.determineCommonAncestor(candidate.getReturnType(), commonType);
|
||||
if (commonType == null) {
|
||||
// Ambiguous return types found: return null to indicate "not determinable".
|
||||
return null;
|
||||
@@ -752,12 +750,15 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
}
|
||||
|
||||
if (commonType != null) {
|
||||
// Clear return type found: all factory methods return same type.
|
||||
mbd.factoryMethodReturnType = (uniqueCandidate != null ?
|
||||
ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType));
|
||||
if (commonType == null) {
|
||||
return null;
|
||||
}
|
||||
return commonType;
|
||||
// Common return type found: all factory methods return same type. For a non-parameterized
|
||||
// unique candidate, cache the full type declaration context of the target factory method.
|
||||
cachedReturnType = (uniqueCandidate != null ?
|
||||
ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType));
|
||||
mbd.factoryMethodReturnType = cachedReturnType;
|
||||
return cachedReturnType.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -908,12 +909,16 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (bw != null) {
|
||||
return (FactoryBean<?>) bw.getWrappedInstance();
|
||||
}
|
||||
Object beanInstance = getSingleton(beanName, false);
|
||||
if (beanInstance instanceof FactoryBean) {
|
||||
return (FactoryBean<?>) beanInstance;
|
||||
}
|
||||
if (isSingletonCurrentlyInCreation(beanName) ||
|
||||
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object instance = null;
|
||||
Object instance;
|
||||
try {
|
||||
// Mark this bean as currently in creation, even if just partially.
|
||||
beforeSingletonCreation(beanName);
|
||||
@@ -1049,7 +1054,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @param args explicit arguments to use for constructor or factory method invocation
|
||||
* @return BeanWrapper for the new instance
|
||||
* @return a BeanWrapper for the new instance
|
||||
* @see #instantiateUsingFactoryMethod
|
||||
* @see #autowireConstructor
|
||||
* @see #instantiateBean
|
||||
@@ -1129,7 +1134,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* Instantiate the given bean using its default constructor.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @return BeanWrapper for the new instance
|
||||
* @return a BeanWrapper for the new instance
|
||||
*/
|
||||
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
|
||||
try {
|
||||
@@ -1164,7 +1169,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param mbd the bean definition for the bean
|
||||
* @param explicitArgs argument values passed in programmatically via the getBean method,
|
||||
* or {@code null} if none (-> use constructor argument values from bean definition)
|
||||
* @return BeanWrapper for the new instance
|
||||
* @return a BeanWrapper for the new instance
|
||||
* @see #getBean(String, Object[])
|
||||
*/
|
||||
protected BeanWrapper instantiateUsingFactoryMethod(
|
||||
@@ -1185,7 +1190,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param ctors the chosen candidate constructors
|
||||
* @param explicitArgs argument values passed in programmatically via the getBean method,
|
||||
* or {@code null} if none (-> use constructor argument values from bean definition)
|
||||
* @return BeanWrapper for the new instance
|
||||
* @return a BeanWrapper for the new instance
|
||||
*/
|
||||
protected BeanWrapper autowireConstructor(
|
||||
String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
|
||||
@@ -1198,7 +1203,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* from the bean definition.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the bean definition for the bean
|
||||
* @param bw BeanWrapper with bean instance
|
||||
* @param bw the BeanWrapper with bean instance
|
||||
*/
|
||||
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
|
||||
PropertyValues pvs = mbd.getPropertyValues();
|
||||
@@ -1282,7 +1287,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* @param beanName the name of the bean we're wiring up.
|
||||
* Useful for debugging messages; not used functionally.
|
||||
* @param mbd bean definition to update through autowiring
|
||||
* @param bw BeanWrapper from which we can obtain information about the bean
|
||||
* @param bw the BeanWrapper from which we can obtain information about the bean
|
||||
* @param pvs the PropertyValues to register wired objects with
|
||||
*/
|
||||
protected void autowireByName(
|
||||
@@ -1316,7 +1321,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
* behavior for bigger applications.
|
||||
* @param beanName the name of the bean to autowire by type
|
||||
* @param mbd the merged bean definition to update through autowiring
|
||||
* @param bw BeanWrapper from which we can obtain information about the bean
|
||||
* @param bw the BeanWrapper from which we can obtain information about the bean
|
||||
* @param pvs the PropertyValues to register wired objects with
|
||||
*/
|
||||
protected void autowireByType(
|
||||
@@ -1415,7 +1420,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
*/
|
||||
protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) {
|
||||
List<PropertyDescriptor> pds =
|
||||
new LinkedList<PropertyDescriptor>(Arrays.asList(bw.getPropertyDescriptors()));
|
||||
new ArrayList<PropertyDescriptor>(Arrays.asList(bw.getPropertyDescriptors()));
|
||||
for (Iterator<PropertyDescriptor> it = pds.iterator(); it.hasNext();) {
|
||||
PropertyDescriptor pd = it.next();
|
||||
if (isExcludedFromDependencyCheck(pd)) {
|
||||
@@ -1484,15 +1489,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
return;
|
||||
}
|
||||
|
||||
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
|
||||
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
|
||||
}
|
||||
|
||||
MutablePropertyValues mpvs = null;
|
||||
List<PropertyValue> original;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
if (bw instanceof BeanWrapperImpl) {
|
||||
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
|
||||
}
|
||||
}
|
||||
|
||||
if (pvs instanceof MutablePropertyValues) {
|
||||
mpvs = (MutablePropertyValues) pvs;
|
||||
if (mpvs.isConverted()) {
|
||||
@@ -1628,7 +1631,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
(mbd != null ? mbd.getResourceDescription() : null),
|
||||
beanName, "Invocation of init method failed", ex);
|
||||
}
|
||||
|
||||
if (mbd == null || !mbd.isSynthetic()) {
|
||||
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
|
||||
}
|
||||
@@ -1780,8 +1782,21 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
*/
|
||||
@Override
|
||||
protected void removeSingleton(String beanName) {
|
||||
super.removeSingleton(beanName);
|
||||
this.factoryBeanInstanceCache.remove(beanName);
|
||||
synchronized (getSingletonMutex()) {
|
||||
super.removeSingleton(beanName);
|
||||
this.factoryBeanInstanceCache.remove(beanName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to clear FactoryBean instance cache as well.
|
||||
*/
|
||||
@Override
|
||||
protected void clearSingletonCache() {
|
||||
synchronized (getSingletonMutex()) {
|
||||
super.clearSingletonCache();
|
||||
this.factoryBeanInstanceCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+11
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -293,7 +293,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
|
||||
}
|
||||
registerDependentBean(dep, beanName);
|
||||
getBean(dep);
|
||||
try {
|
||||
getBean(dep);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1384,8 +1390,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
|
||||
}
|
||||
catch (LinkageError ex) {
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
|
||||
catch (LinkageError err) {
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1509,7 +1515,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
return getTypeForFactoryBean(factoryBean);
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
if (ex instanceof BeanCurrentlyInCreationException) {
|
||||
if (ex.contains(BeanCurrentlyInCreationException.class)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Bean currently in creation on FactoryBean type check: " + ex);
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import org.springframework.util.Assert;
|
||||
@SuppressWarnings("serial")
|
||||
public class AutowireCandidateQualifier extends BeanMetadataAttributeAccessor {
|
||||
|
||||
public static String VALUE_KEY = "value";
|
||||
public static final String VALUE_KEY = "value";
|
||||
|
||||
private final String typeName;
|
||||
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,6 +55,7 @@ public interface BeanDefinitionRegistry extends AliasRegistry {
|
||||
* @throws BeanDefinitionStoreException if the BeanDefinition is invalid
|
||||
* or if there is already a BeanDefinition for the specified bean name
|
||||
* (and we are not allowed to override it)
|
||||
* @see GenericBeanDefinition
|
||||
* @see RootBeanDefinition
|
||||
* @see ChildBeanDefinition
|
||||
*/
|
||||
|
||||
+3
-3
@@ -855,11 +855,11 @@ class ConstructorResolver {
|
||||
*/
|
||||
private static class ArgumentsHolder {
|
||||
|
||||
public final Object rawArguments[];
|
||||
public final Object[] rawArguments;
|
||||
|
||||
public final Object arguments[];
|
||||
public final Object[] arguments;
|
||||
|
||||
public final Object preparedArguments[];
|
||||
public final Object[] preparedArguments;
|
||||
|
||||
public boolean resolveNecessary = false;
|
||||
|
||||
|
||||
+83
-79
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -80,19 +80,17 @@ import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of the
|
||||
* {@link org.springframework.beans.factory.ListableBeanFactory} and
|
||||
* {@link BeanDefinitionRegistry} interfaces: a full-fledged bean factory
|
||||
* based on bean definition objects.
|
||||
* Spring's default implementation of the {@link ConfigurableListableBeanFactory}
|
||||
* and {@link BeanDefinitionRegistry} interfaces: a full-fledged bean factory
|
||||
* based on bean definition metadata, extensible through post-processors.
|
||||
*
|
||||
* <p>Typical usage is registering all bean definitions first (possibly read
|
||||
* from a bean definition file), before accessing beans. Bean definition lookup
|
||||
* from a bean definition file), before accessing beans. Bean lookup by name
|
||||
* is therefore an inexpensive operation in a local bean definition table,
|
||||
* operating on pre-built bean definition metadata objects.
|
||||
* operating on pre-resolved bean definition metadata objects.
|
||||
*
|
||||
* <p>Can be used as a standalone bean factory, or as a superclass for custom
|
||||
* bean factories. Note that readers for specific bean definition formats are
|
||||
* typically implemented separately rather than as bean factory subclasses:
|
||||
* <p>Note that readers for specific bean definition formats are typically
|
||||
* implemented separately rather than as bean factory subclasses:
|
||||
* see for example {@link PropertiesBeanDefinitionReader} and
|
||||
* {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
|
||||
*
|
||||
@@ -109,9 +107,10 @@ import org.springframework.util.StringUtils;
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @since 16 April 2001
|
||||
* @see StaticListableBeanFactory
|
||||
* @see PropertiesBeanDefinitionReader
|
||||
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
|
||||
* @see #registerBeanDefinition
|
||||
* @see #addBeanPostProcessor
|
||||
* @see #getBean
|
||||
* @see #resolveDependency
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
|
||||
@@ -371,8 +370,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
@Override
|
||||
public String[] getBeanDefinitionNames() {
|
||||
if (this.frozenBeanDefinitionNames != null) {
|
||||
return this.frozenBeanDefinitionNames.clone();
|
||||
String[] frozenNames = this.frozenBeanDefinitionNames;
|
||||
if (frozenNames != null) {
|
||||
return frozenNames.clone();
|
||||
}
|
||||
else {
|
||||
return StringUtils.toStringArray(this.beanDefinitionNames);
|
||||
@@ -419,7 +419,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
// Only check bean definition if it is complete.
|
||||
if (!mbd.isAbstract() && (allowEagerInit ||
|
||||
((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
|
||||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
|
||||
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
|
||||
// In case of FactoryBean, match object created by FactoryBean.
|
||||
boolean isFactoryBean = isFactoryBean(beanName, mbd);
|
||||
@@ -444,9 +444,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (allowEagerInit) {
|
||||
throw ex;
|
||||
}
|
||||
// Probably contains a placeholder: let's ignore it for type matching purposes.
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Ignoring bean class loading failure for bean '" + beanName + "'", ex);
|
||||
// Probably a class name with a placeholder: let's ignore it for type matching purposes.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring bean class loading failure for bean '" + beanName + "'", ex);
|
||||
}
|
||||
onSuppressedException(ex);
|
||||
}
|
||||
@@ -454,9 +454,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (allowEagerInit) {
|
||||
throw ex;
|
||||
}
|
||||
// Probably contains a placeholder: let's ignore it for type matching purposes.
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Ignoring unresolvable metadata in bean definition '" + beanName + "'", ex);
|
||||
// Probably some metadata with a placeholder: let's ignore it for type matching purposes.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring unresolvable metadata in bean definition '" + beanName + "'", ex);
|
||||
}
|
||||
onSuppressedException(ex);
|
||||
}
|
||||
@@ -523,8 +523,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (rootCause instanceof BeanCurrentlyInCreationException) {
|
||||
BeanCreationException bce = (BeanCreationException) rootCause;
|
||||
if (isCurrentlyInCreation(bce.getBeanName())) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Ignoring match to currently created bean '" + beanName + "': " +
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring match to currently created bean '" + beanName + "': " +
|
||||
ex.getMessage());
|
||||
}
|
||||
onSuppressedException(ex);
|
||||
@@ -541,29 +541,29 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
@Override
|
||||
public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
|
||||
List<String> results = new ArrayList<String>();
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (String beanName : this.beanDefinitionNames) {
|
||||
BeanDefinition beanDefinition = getBeanDefinition(beanName);
|
||||
if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) {
|
||||
results.add(beanName);
|
||||
result.add(beanName);
|
||||
}
|
||||
}
|
||||
for (String beanName : this.manualSingletonNames) {
|
||||
if (!results.contains(beanName) && findAnnotationOnBean(beanName, annotationType) != null) {
|
||||
results.add(beanName);
|
||||
if (!result.contains(beanName) && findAnnotationOnBean(beanName, annotationType) != null) {
|
||||
result.add(beanName);
|
||||
}
|
||||
}
|
||||
return results.toArray(new String[results.size()]);
|
||||
return StringUtils.toStringArray(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
|
||||
String[] beanNames = getBeanNamesForAnnotation(annotationType);
|
||||
Map<String, Object> results = new LinkedHashMap<String, Object>(beanNames.length);
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>(beanNames.length);
|
||||
for (String beanName : beanNames) {
|
||||
results.put(beanName, getBean(beanName));
|
||||
result.put(beanName, getBean(beanName));
|
||||
}
|
||||
return results;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -681,8 +681,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
|
||||
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
|
||||
if (bd == null) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
this.logger.trace("No bean named '" + beanName + "' found in " + this);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("No bean named '" + beanName + "' found in " + this);
|
||||
}
|
||||
throw new NoSuchBeanDefinitionException(beanName);
|
||||
}
|
||||
@@ -726,8 +726,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
@Override
|
||||
public void preInstantiateSingletons() throws BeansException {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Pre-instantiating singletons in " + this);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Pre-instantiating singletons in " + this);
|
||||
}
|
||||
|
||||
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
|
||||
@@ -806,34 +806,32 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
|
||||
BeanDefinition oldBeanDefinition;
|
||||
|
||||
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
|
||||
if (oldBeanDefinition != null) {
|
||||
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
|
||||
if (existingDefinition != null) {
|
||||
if (!isAllowBeanDefinitionOverriding()) {
|
||||
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
|
||||
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
|
||||
"': There is already [" + oldBeanDefinition + "] bound.");
|
||||
"': There is already [" + existingDefinition + "] bound.");
|
||||
}
|
||||
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
|
||||
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
|
||||
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Overriding user-defined bean definition for bean '" + beanName +
|
||||
"' with a framework-generated bean definition: replacing [" +
|
||||
oldBeanDefinition + "] with [" + beanDefinition + "]");
|
||||
existingDefinition + "] with [" + beanDefinition + "]");
|
||||
}
|
||||
}
|
||||
else if (!beanDefinition.equals(oldBeanDefinition)) {
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("Overriding bean definition for bean '" + beanName +
|
||||
"' with a different definition: replacing [" + oldBeanDefinition +
|
||||
else if (!beanDefinition.equals(existingDefinition)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Overriding bean definition for bean '" + beanName +
|
||||
"' with a different definition: replacing [" + existingDefinition +
|
||||
"] with [" + beanDefinition + "]");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Overriding bean definition for bean '" + beanName +
|
||||
"' with an equivalent definition: replacing [" + oldBeanDefinition +
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Overriding bean definition for bean '" + beanName +
|
||||
"' with an equivalent definition: replacing [" + existingDefinition +
|
||||
"] with [" + beanDefinition + "]");
|
||||
}
|
||||
}
|
||||
@@ -864,7 +862,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
this.frozenBeanDefinitionNames = null;
|
||||
}
|
||||
|
||||
if (oldBeanDefinition != null || containsSingleton(beanName)) {
|
||||
if (existingDefinition != null || containsSingleton(beanName)) {
|
||||
resetBeanDefinition(beanName);
|
||||
}
|
||||
}
|
||||
@@ -875,8 +873,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
BeanDefinition bd = this.beanDefinitionMap.remove(beanName);
|
||||
if (bd == null) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
this.logger.trace("No bean named '" + beanName + "' found in " + this);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("No bean named '" + beanName + "' found in " + this);
|
||||
}
|
||||
throw new NoSuchBeanDefinitionException(beanName);
|
||||
}
|
||||
@@ -1009,7 +1007,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
if (!autowireCandidates.isEmpty()) {
|
||||
candidateNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
|
||||
candidateNames = StringUtils.toStringArray(autowireCandidates);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1240,7 +1238,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
|
||||
private FactoryAwareOrderSourceProvider createFactoryAwareOrderSourceProvider(Map<String, Object> beans) {
|
||||
private OrderComparator.OrderSourceProvider createFactoryAwareOrderSourceProvider(Map<String, Object> beans) {
|
||||
IdentityHashMap<Object, String> instancesToBeanNames = new IdentityHashMap<Object, String>();
|
||||
for (Map.Entry<String, Object> entry : beans.entrySet()) {
|
||||
instancesToBeanNames.put(entry.getValue(), entry.getKey());
|
||||
@@ -1581,6 +1579,29 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A dependency descriptor marker for nested elements.
|
||||
*/
|
||||
private static class NestedDependencyDescriptor extends DependencyDescriptor {
|
||||
|
||||
public NestedDependencyDescriptor(DependencyDescriptor original) {
|
||||
super(original);
|
||||
increaseNestingLevel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A dependency descriptor marker for multiple elements.
|
||||
*/
|
||||
private static class MultiElementDescriptor extends NestedDependencyDescriptor {
|
||||
|
||||
public MultiElementDescriptor(DependencyDescriptor original) {
|
||||
super(original);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Separate inner class for avoiding a hard dependency on the {@code javax.inject} API.
|
||||
*/
|
||||
@@ -1637,7 +1658,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName, args);
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
||||
@Override
|
||||
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
|
||||
return ((AbstractBeanFactory) beanFactory).getBean(beanName, requiredType, args);
|
||||
@@ -1653,7 +1674,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName);
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
@@ -1665,7 +1686,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
@Override
|
||||
public Object getIfUnique() throws BeansException {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
@@ -1686,7 +1707,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
|
||||
/**
|
||||
* Serializable ObjectFactory for lazy resolution of a dependency.
|
||||
* A {@code javax.inject.Provider} implementation for lazy resolution of a dependency.
|
||||
*/
|
||||
private class Jsr330DependencyProvider extends DependencyObjectProvider implements Provider<Object> {
|
||||
|
||||
@@ -1742,7 +1763,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (targetType != null && targetType != obj.getClass()) {
|
||||
sources.add(targetType);
|
||||
}
|
||||
return sources.toArray(new Object[sources.size()]);
|
||||
return sources.toArray();
|
||||
}
|
||||
|
||||
private RootBeanDefinition getRootBeanDefinition(String beanName) {
|
||||
@@ -1756,21 +1777,4 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class NestedDependencyDescriptor extends DependencyDescriptor {
|
||||
|
||||
public NestedDependencyDescriptor(DependencyDescriptor original) {
|
||||
super(original);
|
||||
increaseNestingLevel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class MultiElementDescriptor extends NestedDependencyDescriptor {
|
||||
|
||||
public MultiElementDescriptor(DependencyDescriptor original) {
|
||||
super(original);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+30
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -386,15 +386,8 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* @see #registerDependentBean
|
||||
*/
|
||||
public void registerContainedBean(String containedBeanName, String containingBeanName) {
|
||||
// A quick check for an existing entry upfront, avoiding synchronization...
|
||||
Set<String> containedBeans = this.containedBeanMap.get(containingBeanName);
|
||||
if (containedBeans != null && containedBeans.contains(containedBeanName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No entry yet -> fully synchronized manipulation of the containedBeans Set
|
||||
synchronized (this.containedBeanMap) {
|
||||
containedBeans = this.containedBeanMap.get(containingBeanName);
|
||||
Set<String> containedBeans = this.containedBeanMap.get(containingBeanName);
|
||||
if (containedBeans == null) {
|
||||
containedBeans = new LinkedHashSet<String>(8);
|
||||
this.containedBeanMap.put(containingBeanName, containedBeans);
|
||||
@@ -411,16 +404,10 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* @param dependentBeanName the name of the dependent bean
|
||||
*/
|
||||
public void registerDependentBean(String beanName, String dependentBeanName) {
|
||||
// A quick check for an existing entry upfront, avoiding synchronization...
|
||||
String canonicalName = canonicalName(beanName);
|
||||
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
|
||||
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No entry yet -> fully synchronized manipulation of the dependentBeans Set
|
||||
synchronized (this.dependentBeanMap) {
|
||||
dependentBeans = this.dependentBeanMap.get(canonicalName);
|
||||
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
|
||||
if (dependentBeans == null) {
|
||||
dependentBeans = new LinkedHashSet<String>(8);
|
||||
this.dependentBeanMap.put(canonicalName, dependentBeans);
|
||||
@@ -445,7 +432,9 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
* @since 4.0
|
||||
*/
|
||||
protected boolean isDependent(String beanName, String dependentBeanName) {
|
||||
return isDependent(beanName, dependentBeanName, null);
|
||||
synchronized (this.dependentBeanMap) {
|
||||
return isDependent(beanName, dependentBeanName, null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
|
||||
@@ -490,7 +479,9 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
if (dependentBeans == null) {
|
||||
return new String[0];
|
||||
}
|
||||
return StringUtils.toStringArray(dependentBeans);
|
||||
synchronized (this.dependentBeanMap) {
|
||||
return StringUtils.toStringArray(dependentBeans);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -504,7 +495,9 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
if (dependenciesForBean == null) {
|
||||
return new String[0];
|
||||
}
|
||||
return dependenciesForBean.toArray(new String[dependenciesForBean.size()]);
|
||||
synchronized (this.dependenciesForBeanMap) {
|
||||
return StringUtils.toStringArray(dependenciesForBean);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroySingletons() {
|
||||
@@ -527,6 +520,14 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
this.dependentBeanMap.clear();
|
||||
this.dependenciesForBeanMap.clear();
|
||||
|
||||
clearSingletonCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cached singleton instances in this registry.
|
||||
* @since 4.3.15
|
||||
*/
|
||||
protected void clearSingletonCache() {
|
||||
synchronized (this.singletonObjects) {
|
||||
this.singletonObjects.clear();
|
||||
this.singletonFactories.clear();
|
||||
@@ -562,7 +563,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
*/
|
||||
protected void destroyBean(String beanName, DisposableBean bean) {
|
||||
// Trigger destruction of dependent beans first...
|
||||
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
|
||||
Set<String> dependencies;
|
||||
synchronized (this.dependentBeanMap) {
|
||||
// Within full synchronization in order to guarantee a disconnected Set
|
||||
dependencies = this.dependentBeanMap.remove(beanName);
|
||||
}
|
||||
if (dependencies != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
|
||||
@@ -583,7 +588,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
}
|
||||
|
||||
// Trigger destruction of contained beans...
|
||||
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
|
||||
Set<String> containedBeans;
|
||||
synchronized (this.containedBeanMap) {
|
||||
// Within full synchronization in order to guarantee a disconnected Set
|
||||
containedBeans = this.containedBeanMap.remove(beanName);
|
||||
}
|
||||
if (containedBeans != null) {
|
||||
for (String containedBeanName : containedBeans) {
|
||||
destroySingleton(containedBeanName);
|
||||
|
||||
+21
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -109,6 +109,11 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
}
|
||||
else {
|
||||
if (object != null && shouldPostProcess) {
|
||||
if (isSingletonCurrentlyInCreation(beanName)) {
|
||||
// Temporarily return non-post-processed object, not storing it yet..
|
||||
return object;
|
||||
}
|
||||
beforeSingletonCreation(beanName);
|
||||
try {
|
||||
object = postProcessObjectFromFactoryBean(object, beanName);
|
||||
}
|
||||
@@ -116,8 +121,13 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
throw new BeanCreationException(beanName,
|
||||
"Post-processing of FactoryBean's singleton object failed", ex);
|
||||
}
|
||||
finally {
|
||||
afterSingletonCreation(beanName);
|
||||
}
|
||||
}
|
||||
if (containsSingleton(beanName)) {
|
||||
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
|
||||
}
|
||||
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
|
||||
}
|
||||
}
|
||||
return (object != NULL_OBJECT ? object : null);
|
||||
@@ -218,17 +228,21 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
||||
*/
|
||||
@Override
|
||||
protected void removeSingleton(String beanName) {
|
||||
super.removeSingleton(beanName);
|
||||
this.factoryBeanObjectCache.remove(beanName);
|
||||
synchronized (getSingletonMutex()) {
|
||||
super.removeSingleton(beanName);
|
||||
this.factoryBeanObjectCache.remove(beanName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to clear the FactoryBean object cache as well.
|
||||
*/
|
||||
@Override
|
||||
public void destroySingletons() {
|
||||
super.destroySingletons();
|
||||
this.factoryBeanObjectCache.clear();
|
||||
protected void clearSingletonCache() {
|
||||
synchronized (getSingletonMutex()) {
|
||||
super.clearSingletonCache();
|
||||
this.factoryBeanObjectCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -333,7 +333,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
results.add(beanName);
|
||||
}
|
||||
}
|
||||
return results.toArray(new String[results.size()]);
|
||||
return StringUtils.toStringArray(results);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -402,8 +402,8 @@ public class BeanDefinitionParserDelegate {
|
||||
public BeanDefinitionDefaults getBeanDefinitionDefaults() {
|
||||
BeanDefinitionDefaults bdd = new BeanDefinitionDefaults();
|
||||
bdd.setLazyInit("TRUE".equalsIgnoreCase(this.defaults.getLazyInit()));
|
||||
bdd.setDependencyCheck(this.getDependencyCheck(DEFAULT_VALUE));
|
||||
bdd.setAutowireMode(this.getAutowireMode(DEFAULT_VALUE));
|
||||
bdd.setDependencyCheck(getDependencyCheck(DEFAULT_VALUE));
|
||||
bdd.setAutowireMode(getAutowireMode(DEFAULT_VALUE));
|
||||
bdd.setInitMethodName(this.defaults.getInitMethod());
|
||||
bdd.setDestroyMethodName(this.defaults.getDestroyMethod());
|
||||
return bdd;
|
||||
@@ -1255,7 +1255,7 @@ public class BeanDefinitionParserDelegate {
|
||||
boolean hasKeyAttribute = entryEle.hasAttribute(KEY_ATTRIBUTE);
|
||||
boolean hasKeyRefAttribute = entryEle.hasAttribute(KEY_REF_ATTRIBUTE);
|
||||
if ((hasKeyAttribute && hasKeyRefAttribute) ||
|
||||
((hasKeyAttribute || hasKeyRefAttribute)) && keyEle != null) {
|
||||
(hasKeyAttribute || hasKeyRefAttribute) && keyEle != null) {
|
||||
error("<entry> element is only allowed to contain either " +
|
||||
"a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element", entryEle);
|
||||
}
|
||||
@@ -1284,7 +1284,7 @@ public class BeanDefinitionParserDelegate {
|
||||
boolean hasValueRefAttribute = entryEle.hasAttribute(VALUE_REF_ATTRIBUTE);
|
||||
boolean hasValueTypeAttribute = entryEle.hasAttribute(VALUE_TYPE_ATTRIBUTE);
|
||||
if ((hasValueAttribute && hasValueRefAttribute) ||
|
||||
((hasValueAttribute || hasValueRefAttribute)) && valueEle != null) {
|
||||
(hasValueAttribute || hasValueRefAttribute) && valueEle != null) {
|
||||
error("<entry> element is only allowed to contain either " +
|
||||
"'value' attribute OR 'value-ref' attribute OR <value> sub-element", entryEle);
|
||||
}
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ public class BeansDtdResolver implements EntityResolver {
|
||||
"] and system ID [" + systemId + "]");
|
||||
}
|
||||
if (systemId != null && systemId.endsWith(DTD_EXTENSION)) {
|
||||
int lastPathSeparator = systemId.lastIndexOf("/");
|
||||
int lastPathSeparator = systemId.lastIndexOf('/');
|
||||
int dtdNameStart = systemId.indexOf(DTD_NAME, lastPathSeparator);
|
||||
if (dtdNameStart != -1) {
|
||||
String dtdFile = DTD_FILENAME + DTD_EXTENSION;
|
||||
|
||||
+10
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -147,16 +147,21 @@ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver
|
||||
* Load the specified NamespaceHandler mappings lazily.
|
||||
*/
|
||||
private Map<String, Object> getHandlerMappings() {
|
||||
if (this.handlerMappings == null) {
|
||||
Map<String, Object> handlerMappings = this.handlerMappings;
|
||||
if (handlerMappings == null) {
|
||||
synchronized (this) {
|
||||
if (this.handlerMappings == null) {
|
||||
handlerMappings = this.handlerMappings;
|
||||
if (handlerMappings == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loading NamespaceHandler mappings from [" + this.handlerMappingsLocation + "]");
|
||||
}
|
||||
try {
|
||||
Properties mappings =
|
||||
PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loaded NamespaceHandler mappings: " + mappings);
|
||||
}
|
||||
Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>(mappings.size());
|
||||
handlerMappings = new ConcurrentHashMap<String, Object>(mappings.size());
|
||||
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
|
||||
this.handlerMappings = handlerMappings;
|
||||
}
|
||||
@@ -167,7 +172,7 @@ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.handlerMappings;
|
||||
return handlerMappings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ public final class ParserContext {
|
||||
|
||||
private BeanDefinition containingBeanDefinition;
|
||||
|
||||
private final Stack<ComponentDefinition> containingComponents = new Stack<ComponentDefinition>();
|
||||
private final Stack<CompositeComponentDefinition> containingComponents = new Stack<CompositeComponentDefinition>();
|
||||
|
||||
|
||||
public ParserContext(XmlReaderContext readerContext, BeanDefinitionParserDelegate delegate) {
|
||||
@@ -90,8 +90,7 @@ public final class ParserContext {
|
||||
}
|
||||
|
||||
public CompositeComponentDefinition getContainingComponent() {
|
||||
return (!this.containingComponents.isEmpty() ?
|
||||
(CompositeComponentDefinition) this.containingComponents.lastElement() : null);
|
||||
return (!this.containingComponents.isEmpty() ? this.containingComponents.lastElement() : null);
|
||||
}
|
||||
|
||||
public void pushContainingComponent(CompositeComponentDefinition containingComponent) {
|
||||
@@ -99,7 +98,7 @@ public final class ParserContext {
|
||||
}
|
||||
|
||||
public CompositeComponentDefinition popContainingComponent() {
|
||||
return (CompositeComponentDefinition) this.containingComponents.pop();
|
||||
return this.containingComponents.pop();
|
||||
}
|
||||
|
||||
public void popAndRegisterContainingComponent() {
|
||||
|
||||
+8
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -122,7 +122,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
}
|
||||
catch (FileNotFoundException ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Couldn't find XML schema [" + systemId + "]: " + resource, ex);
|
||||
logger.debug("Could not find XML schema [" + systemId + "]: " + resource, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,9 +134,11 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
* Load the specified schema mappings lazily.
|
||||
*/
|
||||
private Map<String, String> getSchemaMappings() {
|
||||
if (this.schemaMappings == null) {
|
||||
Map<String, String> schemaMappings = this.schemaMappings;
|
||||
if (schemaMappings == null) {
|
||||
synchronized (this) {
|
||||
if (this.schemaMappings == null) {
|
||||
schemaMappings = this.schemaMappings;
|
||||
if (schemaMappings == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loading schema mappings from [" + this.schemaMappingsLocation + "]");
|
||||
}
|
||||
@@ -146,7 +148,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loaded schema mappings: " + mappings);
|
||||
}
|
||||
Map<String, String> schemaMappings = new ConcurrentHashMap<String, String>(mappings.size());
|
||||
schemaMappings = new ConcurrentHashMap<String, String>(mappings.size());
|
||||
CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
|
||||
this.schemaMappings = schemaMappings;
|
||||
}
|
||||
@@ -157,7 +159,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.schemaMappings;
|
||||
return schemaMappings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ public class UtilNamespaceHandler extends NamespaceHandlerSupport {
|
||||
parserContext.getReaderContext().error("Attribute 'path' must not be empty", element);
|
||||
return;
|
||||
}
|
||||
int dotIndex = path.indexOf(".");
|
||||
int dotIndex = path.indexOf('.');
|
||||
if (dotIndex == -1) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Attribute 'path' must follow pattern 'beanName.propertyName'", element);
|
||||
|
||||
+9
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -314,7 +314,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
|
||||
Assert.notNull(encodedResource, "EncodedResource must not be null");
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
|
||||
logger.info("Loading XML bean definitions from " + encodedResource);
|
||||
}
|
||||
|
||||
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
|
||||
@@ -430,13 +430,13 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
getValidationModeForResource(resource), isNamespaceAware());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the validation mode for the specified {@link Resource}. If no explicit
|
||||
* validation mode has been configured then the validation mode is
|
||||
* {@link #detectValidationMode detected}.
|
||||
* Determine the validation mode for the specified {@link Resource}.
|
||||
* If no explicit validation mode has been configured, then the validation
|
||||
* mode gets {@link #detectValidationMode detected} from the given resource.
|
||||
* <p>Override this method if you would like full control over the validation
|
||||
* mode, even when something other than {@link #VALIDATION_AUTO} was set.
|
||||
* @see #detectValidationMode
|
||||
*/
|
||||
protected int getValidationModeForResource(Resource resource) {
|
||||
int validationModeToUse = getValidationMode();
|
||||
@@ -454,7 +454,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects which kind of validation to perform on the XML file identified
|
||||
* Detect which kind of validation to perform on the XML file identified
|
||||
* by the supplied {@link Resource}. If the file has a {@code DOCTYPE}
|
||||
* definition then DTD validation is used otherwise XSD validation is assumed.
|
||||
* <p>Override this method if you would like to customize resolution
|
||||
@@ -540,7 +540,8 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
|
||||
|
||||
/**
|
||||
* Create the default implementation of {@link NamespaceHandlerResolver} used if none is specified.
|
||||
* Default implementation returns an instance of {@link DefaultNamespaceHandlerResolver}.
|
||||
* <p>The default implementation returns an instance of {@link DefaultNamespaceHandlerResolver}.
|
||||
* @see DefaultNamespaceHandlerResolver#DefaultNamespaceHandlerResolver(ClassLoader)
|
||||
*/
|
||||
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
|
||||
return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader());
|
||||
|
||||
+8
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -67,6 +67,7 @@ public class URIEditor extends PropertyEditorSupport {
|
||||
* Create a new URIEditor, converting "classpath:" locations into
|
||||
* standard URIs (not trying to resolve them into physical resources).
|
||||
* @param encode indicates whether Strings will be encoded or not
|
||||
* @since 3.0
|
||||
*/
|
||||
public URIEditor(boolean encode) {
|
||||
this.classLoader = null;
|
||||
@@ -89,6 +90,7 @@ public class URIEditor extends PropertyEditorSupport {
|
||||
* @param classLoader the ClassLoader to use for resolving "classpath:" locations
|
||||
* (may be {@code null} to indicate the default ClassLoader)
|
||||
* @param encode indicates whether Strings will be encoded or not
|
||||
* @since 3.0
|
||||
*/
|
||||
public URIEditor(ClassLoader classLoader, boolean encode) {
|
||||
this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
|
||||
@@ -101,18 +103,14 @@ public class URIEditor extends PropertyEditorSupport {
|
||||
if (StringUtils.hasText(text)) {
|
||||
String uri = text.trim();
|
||||
if (this.classLoader != null && uri.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) {
|
||||
ClassPathResource resource =
|
||||
new ClassPathResource(uri.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length()), this.classLoader);
|
||||
ClassPathResource resource = new ClassPathResource(
|
||||
uri.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length()), this.classLoader);
|
||||
try {
|
||||
String url = resource.getURL().toString();
|
||||
setValue(createURI(url));
|
||||
setValue(resource.getURI());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalArgumentException("Could not retrieve URI for " + resource + ": " + ex.getMessage());
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalArgumentException("Invalid URI syntax: " + ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
@@ -129,9 +127,8 @@ public class URIEditor extends PropertyEditorSupport {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a URI instance for the given (resolved) String value.
|
||||
* <p>The default implementation encodes the value into a RFC
|
||||
* 2396 compliant URI.
|
||||
* Create a URI instance for the given user-specified String value.
|
||||
* <p>The default implementation encodes the value into a RFC-2396 compliant URI.
|
||||
* @param value the value to convert into a URI instance
|
||||
* @return the URI instance
|
||||
* @throws java.net.URISyntaxException if URI conversion failed
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,7 +27,7 @@ import org.springframework.util.Assert;
|
||||
* PagedListHolder is a simple state holder for handling lists of objects,
|
||||
* separating them into pages. Page numbering starts with 0.
|
||||
*
|
||||
* <p>This is mainly targetted at usage in web UIs. Typically, an instance will be
|
||||
* <p>This is mainly targeted at usage in web UIs. Typically, an instance will be
|
||||
* instantiated with a list of beans, put into the session, and exported as model.
|
||||
* The properties can all be set/get programmatically, but the most common way will
|
||||
* be data binding, i.e. populating the bean from request parameters. The getters
|
||||
@@ -50,8 +50,14 @@ import org.springframework.util.Assert;
|
||||
@SuppressWarnings("serial")
|
||||
public class PagedListHolder<E> implements Serializable {
|
||||
|
||||
/**
|
||||
* The default page size.
|
||||
*/
|
||||
public static final int DEFAULT_PAGE_SIZE = 10;
|
||||
|
||||
/**
|
||||
* The default maximum number of page links.
|
||||
*/
|
||||
public static final int DEFAULT_MAX_LINKED_PAGES = 10;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,7 +42,7 @@ import static org.junit.Assert.*;
|
||||
* @author Chris Beams
|
||||
* @since 19.05.2003
|
||||
*/
|
||||
public final class BeanUtilsTests {
|
||||
public class BeanUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testInstantiateClass() {
|
||||
@@ -193,7 +193,7 @@ public final class BeanUtilsTests {
|
||||
source.setFlag2(true);
|
||||
InvalidProperty target = new InvalidProperty();
|
||||
BeanUtils.copyProperties(source, target);
|
||||
assertEquals(target.getName(), "name");
|
||||
assertEquals("name", target.getName());
|
||||
assertTrue(target.getFlag1());
|
||||
assertTrue(target.getFlag2());
|
||||
}
|
||||
@@ -226,14 +226,14 @@ public final class BeanUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testResolveWithAndWithoutArgList() throws Exception {
|
||||
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingElse", new Class[]{String.class, int.class});
|
||||
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingElse", String.class, int.class);
|
||||
assertSignatureEquals(desiredMethod, "doSomethingElse");
|
||||
assertNull(BeanUtils.resolveSignature("doSomethingElse()", MethodSignatureBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveTypedSignature() throws Exception {
|
||||
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingElse", new Class[]{String.class, int.class});
|
||||
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingElse", String.class, int.class);
|
||||
assertSignatureEquals(desiredMethod, "doSomethingElse(java.lang.String, int)");
|
||||
}
|
||||
|
||||
@@ -244,20 +244,20 @@ public final class BeanUtilsTests {
|
||||
assertSignatureEquals(desiredMethod, "overloaded()");
|
||||
|
||||
// resolve with single arg
|
||||
desiredMethod = MethodSignatureBean.class.getMethod("overloaded", new Class[]{String.class});
|
||||
desiredMethod = MethodSignatureBean.class.getMethod("overloaded", String.class);
|
||||
assertSignatureEquals(desiredMethod, "overloaded(java.lang.String)");
|
||||
|
||||
// resolve with two args
|
||||
desiredMethod = MethodSignatureBean.class.getMethod("overloaded", new Class[]{String.class, BeanFactory.class});
|
||||
desiredMethod = MethodSignatureBean.class.getMethod("overloaded", String.class, BeanFactory.class);
|
||||
assertSignatureEquals(desiredMethod, "overloaded(java.lang.String, org.springframework.beans.factory.BeanFactory)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveSignatureWithArray() throws Exception {
|
||||
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingWithAnArray", new Class[]{String[].class});
|
||||
Method desiredMethod = MethodSignatureBean.class.getMethod("doSomethingWithAnArray", String[].class);
|
||||
assertSignatureEquals(desiredMethod, "doSomethingWithAnArray(java.lang.String[])");
|
||||
|
||||
desiredMethod = MethodSignatureBean.class.getMethod("doSomethingWithAMultiDimensionalArray", new Class[]{String[][].class});
|
||||
desiredMethod = MethodSignatureBean.class.getMethod("doSomethingWithAMultiDimensionalArray", String[][].class);
|
||||
assertSignatureEquals(desiredMethod, "doSomethingWithAMultiDimensionalArray(java.lang.String[][])");
|
||||
}
|
||||
|
||||
@@ -444,5 +444,18 @@ public final class BeanUtilsTests {
|
||||
value = aValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static class BeanWithSingleNonDefaultConstructor {
|
||||
|
||||
private final String name;
|
||||
|
||||
public BeanWithSingleNonDefaultConstructor(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2018 the original author 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,11 +31,11 @@ import static org.junit.Assert.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class BeanWrapperEnumTests {
|
||||
public class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnum() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnum", "VALUE_1");
|
||||
assertEquals(CustomEnum.VALUE_1, gb.getCustomEnum());
|
||||
@@ -43,7 +43,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumWithNull() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnum", null);
|
||||
assertEquals(null, gb.getCustomEnum());
|
||||
@@ -51,7 +51,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumWithEmptyString() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnum", "");
|
||||
assertEquals(null, gb.getCustomEnum());
|
||||
@@ -59,7 +59,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumArrayWithSingleValue() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumArray", "VALUE_1");
|
||||
assertEquals(1, gb.getCustomEnumArray().length);
|
||||
@@ -68,7 +68,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumArrayWithMultipleValues() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumArray", new String[] {"VALUE_1", "VALUE_2"});
|
||||
assertEquals(2, gb.getCustomEnumArray().length);
|
||||
@@ -78,7 +78,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumArrayWithMultipleValuesAsCsv() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumArray", "VALUE_1,VALUE_2");
|
||||
assertEquals(2, gb.getCustomEnumArray().length);
|
||||
@@ -88,7 +88,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumSetWithSingleValue() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumSet", "VALUE_1");
|
||||
assertEquals(1, gb.getCustomEnumSet().size());
|
||||
@@ -97,7 +97,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumSetWithMultipleValues() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumSet", new String[] {"VALUE_1", "VALUE_2"});
|
||||
assertEquals(2, gb.getCustomEnumSet().size());
|
||||
@@ -107,7 +107,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumSetWithMultipleValuesAsCsv() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumSet", "VALUE_1,VALUE_2");
|
||||
assertEquals(2, gb.getCustomEnumSet().size());
|
||||
@@ -117,7 +117,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testCustomEnumSetWithGetterSetterMismatch() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setPropertyValue("customEnumSetMismatch", new String[] {"VALUE_1", "VALUE_2"});
|
||||
assertEquals(2, gb.getCustomEnumSet().size());
|
||||
@@ -127,7 +127,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testStandardEnumSetWithMultipleValues() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setConversionService(new DefaultConversionService());
|
||||
assertNull(gb.getStandardEnumSet());
|
||||
@@ -139,7 +139,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testStandardEnumSetWithAutoGrowing() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setAutoGrowNestedPaths(true);
|
||||
assertNull(gb.getStandardEnumSet());
|
||||
@@ -149,11 +149,11 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testStandardEnumMapWithMultipleValues() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setConversionService(new DefaultConversionService());
|
||||
assertNull(gb.getStandardEnumMap());
|
||||
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
|
||||
Map<String, Integer> map = new LinkedHashMap<>();
|
||||
map.put("VALUE_1", 1);
|
||||
map.put("VALUE_2", 2);
|
||||
bw.setPropertyValue("standardEnumMap", map);
|
||||
@@ -164,7 +164,7 @@ public final class BeanWrapperEnumTests {
|
||||
|
||||
@Test
|
||||
public void testStandardEnumMapWithAutoGrowing() {
|
||||
GenericBean<?> gb = new GenericBean<Object>();
|
||||
GenericBean<?> gb = new GenericBean<>();
|
||||
BeanWrapper bw = new BeanWrapperImpl(gb);
|
||||
bw.setAutoGrowNestedPaths(true);
|
||||
assertNull(gb.getStandardEnumMap());
|
||||
@@ -173,4 +173,32 @@ public final class BeanWrapperEnumTests {
|
||||
assertEquals(new Integer(1), gb.getStandardEnumMap().get(CustomEnum.VALUE_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonPublicEnum() {
|
||||
NonPublicEnumHolder holder = new NonPublicEnumHolder();
|
||||
BeanWrapper bw = new BeanWrapperImpl(holder);
|
||||
bw.setPropertyValue("nonPublicEnum", "VALUE_1");
|
||||
assertEquals(NonPublicEnum.VALUE_1, holder.getNonPublicEnum());
|
||||
}
|
||||
|
||||
|
||||
enum NonPublicEnum {
|
||||
|
||||
VALUE_1, VALUE_2;
|
||||
}
|
||||
|
||||
|
||||
static class NonPublicEnumHolder {
|
||||
|
||||
private NonPublicEnum nonPublicEnum;
|
||||
|
||||
public NonPublicEnum getNonPublicEnum() {
|
||||
return nonPublicEnum;
|
||||
}
|
||||
|
||||
public void setNonPublicEnum(NonPublicEnum nonPublicEnum) {
|
||||
this.nonPublicEnum = nonPublicEnum;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+31
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -2735,6 +2735,16 @@ public class DefaultListableBeanFactoryTests {
|
||||
assertSame(Optional.empty(), bf.getBean(Optional.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonPublicEnum() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd = new RootBeanDefinition(NonPublicEnumHolder.class);
|
||||
bd.getConstructorArgumentValues().addGenericArgumentValue("VALUE_1");
|
||||
bf.registerBeanDefinition("holderBean", bd);
|
||||
NonPublicEnumHolder holder = (NonPublicEnumHolder) bf.getBean("holderBean");
|
||||
assertEquals(NonPublicEnum.VALUE_1, holder.getNonPublicEnum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that by-type bean lookup caching is working effectively by searching for a
|
||||
* bean of type B 10K times within a container having 1K additional beans of type A.
|
||||
@@ -3262,4 +3272,24 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum NonPublicEnum {
|
||||
|
||||
VALUE_1, VALUE_2;
|
||||
}
|
||||
|
||||
|
||||
static class NonPublicEnumHolder {
|
||||
|
||||
final NonPublicEnum nonPublicEnum;
|
||||
|
||||
public NonPublicEnumHolder(NonPublicEnum nonPublicEnum) {
|
||||
this.nonPublicEnum = nonPublicEnum;
|
||||
}
|
||||
|
||||
public NonPublicEnum getNonPublicEnum() {
|
||||
return nonPublicEnum;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,7 +45,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor}
|
||||
* processing the JSR-303 {@link javax.inject.Inject} annotation.
|
||||
* processing the JSR-330 {@link javax.inject.Inject} annotation.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
@@ -548,11 +548,9 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that a dependency on a {@link org.springframework.beans.factory.FactoryBean} can be autowired via
|
||||
* {@link org.springframework.beans.factory.annotation.Autowired @Inject}, specifically addressing the JIRA issue
|
||||
* raised in <a
|
||||
* href="http://opensource.atlassian.com/projects/spring/browse/SPR-4040"
|
||||
* target="_blank">SPR-4040</a>.
|
||||
* Verifies that a dependency on a {@link org.springframework.beans.factory.FactoryBean}
|
||||
* can be autowired via {@link org.springframework.beans.factory.annotation.Autowired @Inject},
|
||||
* specifically addressing SPR-4040.
|
||||
*/
|
||||
@Test
|
||||
public void testBeanAutowiredWithFactoryBean() {
|
||||
@@ -1259,7 +1257,7 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
public static class StringFactoryBean implements FactoryBean<String> {
|
||||
|
||||
@Override
|
||||
public String getObject() throws Exception {
|
||||
public String getObject() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -1291,8 +1289,8 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
private Optional<TestBean> testBean;
|
||||
|
||||
@Inject
|
||||
public void setTestBean(Optional<TestBean> testBeanFactory) {
|
||||
this.testBean = testBeanFactory;
|
||||
public void setTestBean(Optional<TestBean> testBean) {
|
||||
this.testBean = testBean;
|
||||
}
|
||||
|
||||
public Optional<TestBean> getTestBean() {
|
||||
@@ -1317,8 +1315,8 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
private Optional<List<TestBean>> testBean;
|
||||
|
||||
@Inject
|
||||
public void setTestBean(Optional<List<TestBean>> testBeanFactory) {
|
||||
this.testBean = testBeanFactory;
|
||||
public void setTestBean(Optional<List<TestBean>> testBean) {
|
||||
this.testBean = testBean;
|
||||
}
|
||||
|
||||
public Optional<List<TestBean>> getTestBean() {
|
||||
@@ -1343,8 +1341,8 @@ public class InjectAnnotationBeanPostProcessorTests {
|
||||
private Provider<Optional<TestBean>> testBean;
|
||||
|
||||
@Inject
|
||||
public void setTestBean(Provider<Optional<TestBean>> testBeanFactory) {
|
||||
this.testBean = testBeanFactory;
|
||||
public void setTestBean(Provider<Optional<TestBean>> testBean) {
|
||||
this.testBean = testBean;
|
||||
}
|
||||
|
||||
public Optional<TestBean> getTestBean() {
|
||||
|
||||
+21
-25
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.beans.factory.config;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
@@ -34,27 +33,24 @@ import static org.mockito.BDDMockito.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class CustomScopeConfigurerTests {
|
||||
public class CustomScopeConfigurerTests {
|
||||
|
||||
private static final String FOO_SCOPE = "fooScope";
|
||||
private ConfigurableListableBeanFactory factory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
factory = new DefaultListableBeanFactory();
|
||||
}
|
||||
private final ConfigurableListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
|
||||
|
||||
@Test
|
||||
public void testWithNoScopes() throws Exception {
|
||||
public void testWithNoScopes() {
|
||||
CustomScopeConfigurer figurer = new CustomScopeConfigurer();
|
||||
figurer.postProcessBeanFactory(factory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSunnyDayWithBonaFideScopeInstance() throws Exception {
|
||||
public void testSunnyDayWithBonaFideScopeInstance() {
|
||||
Scope scope = mock(Scope.class);
|
||||
factory.registerScope(FOO_SCOPE, scope);
|
||||
Map<String, Object> scopes = new HashMap<String, Object>();
|
||||
Map<String, Object> scopes = new HashMap<>();
|
||||
scopes.put(FOO_SCOPE, scope);
|
||||
CustomScopeConfigurer figurer = new CustomScopeConfigurer();
|
||||
figurer.setScopes(scopes);
|
||||
@@ -62,8 +58,8 @@ public final class CustomScopeConfigurerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSunnyDayWithBonaFideScopeClass() throws Exception {
|
||||
Map<String, Object> scopes = new HashMap<String, Object>();
|
||||
public void testSunnyDayWithBonaFideScopeClass() {
|
||||
Map<String, Object> scopes = new HashMap<>();
|
||||
scopes.put(FOO_SCOPE, NoOpScope.class);
|
||||
CustomScopeConfigurer figurer = new CustomScopeConfigurer();
|
||||
figurer.setScopes(scopes);
|
||||
@@ -72,8 +68,8 @@ public final class CustomScopeConfigurerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSunnyDayWithBonaFideScopeClassname() throws Exception {
|
||||
Map<String, Object> scopes = new HashMap<String, Object>();
|
||||
public void testSunnyDayWithBonaFideScopeClassName() {
|
||||
Map<String, Object> scopes = new HashMap<>();
|
||||
scopes.put(FOO_SCOPE, NoOpScope.class.getName());
|
||||
CustomScopeConfigurer figurer = new CustomScopeConfigurer();
|
||||
figurer.setScopes(scopes);
|
||||
@@ -81,29 +77,29 @@ public final class CustomScopeConfigurerTests {
|
||||
assertTrue(factory.getRegisteredScope(FOO_SCOPE) instanceof NoOpScope);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testWhereScopeMapHasNullScopeValueInEntrySet() throws Exception {
|
||||
Map<String, Object> scopes = new HashMap<String, Object>();
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testWhereScopeMapHasNullScopeValueInEntrySet() {
|
||||
Map<String, Object> scopes = new HashMap<>();
|
||||
scopes.put(FOO_SCOPE, null);
|
||||
CustomScopeConfigurer figurer = new CustomScopeConfigurer();
|
||||
figurer.setScopes(scopes);
|
||||
figurer.postProcessBeanFactory(factory);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testWhereScopeMapHasNonScopeInstanceInEntrySet() throws Exception {
|
||||
Map<String, Object> scopes = new HashMap<String, Object>();
|
||||
scopes.put(FOO_SCOPE, this); // <-- not a valid value...
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testWhereScopeMapHasNonScopeInstanceInEntrySet() {
|
||||
Map<String, Object> scopes = new HashMap<>();
|
||||
scopes.put(FOO_SCOPE, this); // <-- not a valid value...
|
||||
CustomScopeConfigurer figurer = new CustomScopeConfigurer();
|
||||
figurer.setScopes(scopes);
|
||||
figurer.postProcessBeanFactory(factory);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected=ClassCastException.class)
|
||||
public void testWhereScopeMapHasNonStringTypedScopeNameInKeySet() throws Exception {
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void testWhereScopeMapHasNonStringTypedScopeNameInKeySet() {
|
||||
Map scopes = new HashMap();
|
||||
scopes.put(this, new NoOpScope()); // <-- not a valid value (the key)...
|
||||
scopes.put(this, new NoOpScope()); // <-- not a valid value (the key)...
|
||||
CustomScopeConfigurer figurer = new CustomScopeConfigurer();
|
||||
figurer.setScopes(scopes);
|
||||
figurer.postProcessBeanFactory(factory);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user