mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
64 Commits
v7.0.8
...
v4.2.5.RELEASE
| Author | SHA1 | Date | |
|---|---|---|---|
| dd42a21f39 | |||
| cafb99a33d | |||
| 9c5cabf4ba | |||
| 97b017781a | |||
| 9f2b3ca8b8 | |||
| 3f795e64c6 | |||
| 99dc7769a6 | |||
| a620770470 | |||
| 167ba8387a | |||
| 4320161172 | |||
| 659e44146c | |||
| 08f2ab942c | |||
| d2b9dbf181 | |||
| 09db26af2b | |||
| 19c5462b13 | |||
| 5047e90625 | |||
| cf3e460a8b | |||
| c960d9733d | |||
| 9e7f6ba0b1 | |||
| d8a7b6f0f8 | |||
| 6ef2d827c6 | |||
| b1a46ccbd9 | |||
| f053cdec51 | |||
| 39c05c56c4 | |||
| 4418331429 | |||
| e48315549e | |||
| 484dd96606 | |||
| bb12e0ea70 | |||
| 30ef893c28 | |||
| a58eee6ad1 | |||
| 0866aa923a | |||
| d152259673 | |||
| 14babb78b4 | |||
| 4fc6ead548 | |||
| c1f233c787 | |||
| 77b8f4d6af | |||
| 8516de62e3 | |||
| bcebc9db7e | |||
| fc34b0c592 | |||
| a4cb3cf900 | |||
| 33112df237 | |||
| e159086201 | |||
| ab16adab2e | |||
| 29692fcc21 | |||
| 73df50db3c | |||
| 3af62bd0dd | |||
| 1581597092 | |||
| 84e5234eb5 | |||
| 24e58c1ac3 | |||
| 15da48eba5 | |||
| 342d760f70 | |||
| acecda7153 | |||
| 4a863c9066 | |||
| 35b8696523 | |||
| e1bdf5577e | |||
| deae872912 | |||
| 36940e003d | |||
| 935d714333 | |||
| 9021f8fd71 | |||
| 6f2f3595e9 | |||
| d59a97c101 | |||
| 7344dd259c | |||
| f3ac64153e | |||
| 7b35103135 |
+17
-17
@@ -27,54 +27,54 @@ configure(allprojects) { project ->
|
||||
group = "org.springframework"
|
||||
version = qualifyVersionIfNecessary(version)
|
||||
|
||||
ext.aspectjVersion = "1.8.7"
|
||||
ext.aspectjVersion = "1.8.8"
|
||||
ext.eclipselinkVersion = "2.4.2"
|
||||
ext.ehcacheVersion = "2.10.1"
|
||||
ext.ehcachejcacheVersion = "1.0.1"
|
||||
ext.ehcache3Version = "3.0.0.m4"
|
||||
ext.ehcache3Version = "3.0.0.m5"
|
||||
ext.ejbApiVersion = "3.0"
|
||||
ext.fileuploadVersion = "1.3.1"
|
||||
ext.freemarkerVersion = "2.3.23"
|
||||
ext.groovyVersion = "2.4.5"
|
||||
ext.gsonVersion = "2.5"
|
||||
ext.groovyVersion = "2.4.6"
|
||||
ext.gsonVersion = "2.6.1"
|
||||
ext.guavaVersion = "19.0"
|
||||
ext.hamcrestVersion = "1.3"
|
||||
ext.hibernate3Version = "3.6.10.Final"
|
||||
ext.hibernate4Version = "4.3.11.Final"
|
||||
ext.hibernate5Version = "5.0.5.Final"
|
||||
ext.hibernate5Version = "5.0.8.Final"
|
||||
ext.hibval4Version = "4.3.2.Final"
|
||||
ext.hibval5Version = "5.2.2.Final"
|
||||
ext.hibval5Version = "5.2.4.Final"
|
||||
ext.hsqldbVersion = "2.3.3"
|
||||
ext.htmlunitVersion = "2.19"
|
||||
ext.httpasyncVersion = "4.1.1"
|
||||
ext.httpclientVersion = "4.5.1"
|
||||
ext.jackson2Version = "2.6.4"
|
||||
ext.jackson2Version = "2.6.5"
|
||||
ext.jasperreportsVersion = "6.2.0"
|
||||
ext.javamailVersion = "1.5.4"
|
||||
ext.jettyVersion = "9.3.6.v20151106"
|
||||
ext.jodaVersion = "2.9.1"
|
||||
ext.javamailVersion = "1.5.5"
|
||||
ext.jettyVersion = "9.3.7.v20160115"
|
||||
ext.jodaVersion = "2.9.2"
|
||||
ext.jrubyVersion = "1.7.23" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
|
||||
ext.jsonassertVersion = "1.2.3"
|
||||
ext.jsonpathVersion = "2.1.0"
|
||||
ext.jtaVersion = "1.2"
|
||||
ext.junitVersion = "4.12"
|
||||
ext.nettyVersion = "4.0.33.Final"
|
||||
ext.okhttpVersion = "2.7.0"
|
||||
ext.nettyVersion = "4.0.34.Final"
|
||||
ext.okhttpVersion = "2.7.4"
|
||||
ext.openjpaVersion = "2.4.0"
|
||||
ext.poiVersion = "3.13"
|
||||
ext.protobufVersion = "2.6.1"
|
||||
ext.reactorVersion = "2.0.7.RELEASE"
|
||||
ext.romeVersion = "1.5.1"
|
||||
ext.seleniumVersion = "2.48.2"
|
||||
ext.slf4jVersion = "1.7.13"
|
||||
ext.snakeyamlVersion = "1.16"
|
||||
ext.slf4jVersion = "1.7.16"
|
||||
ext.snakeyamlVersion = "1.17"
|
||||
ext.snifferVersion = "1.14"
|
||||
ext.testngVersion = "6.9.10"
|
||||
ext.tiles2Version = "2.2.2"
|
||||
ext.tiles3Version = "3.0.5"
|
||||
ext.tomcatVersion = "8.0.30"
|
||||
ext.tomcatVersion = "8.0.32"
|
||||
ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support
|
||||
ext.undertowVersion = "1.3.10.Final"
|
||||
ext.undertowVersion = "1.3.18.Final"
|
||||
ext.woodstoxVersion = "5.0.1"
|
||||
ext.xmlunitVersion = "1.6"
|
||||
ext.xstreamVersion = "1.4.8"
|
||||
@@ -1080,7 +1080,7 @@ project("spring-aspects") {
|
||||
|
||||
dependencies {
|
||||
aspects(project(":spring-orm"))
|
||||
ajc("org.aspectj:aspectjtools:1.9.0.BETA-2") // for the ability to build on JDK 9, not exposed in the POMs yet
|
||||
ajc("org.aspectj:aspectjtools:1.9.0.BETA-3") // for the ability to build on JDK 9, not exposed in the POMs yet
|
||||
rt("org.aspectj:aspectjrt:${aspectjVersion}") // regular AspectJ version here, to be exposed in the POMs
|
||||
compile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
provided("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version=4.2.4.BUILD-SNAPSHOT
|
||||
version=4.2.5.RELEASE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -86,7 +86,7 @@ public interface MethodMatcher {
|
||||
* @return whether there's a runtime match
|
||||
* @see MethodMatcher#matches(Method, Class)
|
||||
*/
|
||||
boolean matches(Method method, Class<?> targetClass, Object[] args);
|
||||
boolean matches(Method method, Class<?> targetClass, Object... args);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,12 +29,14 @@ class TrueMethodMatcher implements MethodMatcher, Serializable {
|
||||
|
||||
public static final TrueMethodMatcher INSTANCE = new TrueMethodMatcher();
|
||||
|
||||
|
||||
/**
|
||||
* Enforce Singleton pattern.
|
||||
*/
|
||||
private TrueMethodMatcher() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isRuntime() {
|
||||
return false;
|
||||
@@ -46,11 +48,17 @@ class TrueMethodMatcher implements MethodMatcher, Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
// Should never be invoked as isRuntime returns false.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MethodMatcher.TRUE";
|
||||
}
|
||||
|
||||
/**
|
||||
* Required to support serialization. Replaces with canonical
|
||||
* instance on deserialization, protecting Singleton pattern.
|
||||
@@ -60,9 +68,4 @@ class TrueMethodMatcher implements MethodMatcher, Serializable {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MethodMatcher.TRUE";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+17
-18
@@ -135,7 +135,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
*/
|
||||
private int joinPointStaticPartArgumentIndex = -1;
|
||||
|
||||
private Map<String, Integer> argumentBindings = null;
|
||||
private Map<String, Integer> argumentBindings;
|
||||
|
||||
private boolean argumentsIntrospected = false;
|
||||
|
||||
@@ -250,17 +250,17 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
this.argumentNames[i] + "' that is not a valid Java identifier");
|
||||
}
|
||||
}
|
||||
if (argumentNames != null) {
|
||||
if (aspectJAdviceMethod.getParameterTypes().length == argumentNames.length + 1) {
|
||||
if (this.argumentNames != null) {
|
||||
if (this.aspectJAdviceMethod.getParameterTypes().length == this.argumentNames.length + 1) {
|
||||
// May need to add implicit join point arg name...
|
||||
Class<?> firstArgType = aspectJAdviceMethod.getParameterTypes()[0];
|
||||
Class<?> firstArgType = this.aspectJAdviceMethod.getParameterTypes()[0];
|
||||
if (firstArgType == JoinPoint.class ||
|
||||
firstArgType == ProceedingJoinPoint.class ||
|
||||
firstArgType == JoinPoint.StaticPart.class) {
|
||||
String[] oldNames = argumentNames;
|
||||
argumentNames = new String[oldNames.length + 1];
|
||||
argumentNames[0] = "THIS_JOIN_POINT";
|
||||
System.arraycopy(oldNames, 0, argumentNames, 1, oldNames.length);
|
||||
String[] oldNames = this.argumentNames;
|
||||
this.argumentNames = new String[oldNames.length + 1];
|
||||
this.argumentNames[0] = "THIS_JOIN_POINT";
|
||||
System.arraycopy(oldNames, 0, this.argumentNames, 1, oldNames.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -456,8 +456,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
|
||||
int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterTypes().length;
|
||||
if (this.argumentNames.length != numExpectedArgumentNames) {
|
||||
throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames
|
||||
+ " arguments to bind by name in advice, but actually found " +
|
||||
throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames +
|
||||
" arguments to bind by name in advice, but actually found " +
|
||||
this.argumentNames.length + " arguments.");
|
||||
}
|
||||
|
||||
@@ -471,8 +471,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
// specified, and find the discovered argument types.
|
||||
if (this.returningName != null) {
|
||||
if (!this.argumentBindings.containsKey(this.returningName)) {
|
||||
throw new IllegalStateException("Returning argument name '"
|
||||
+ this.returningName + "' was not bound in advice arguments");
|
||||
throw new IllegalStateException("Returning argument name '" + this.returningName +
|
||||
"' was not bound in advice arguments");
|
||||
}
|
||||
else {
|
||||
Integer index = this.argumentBindings.get(this.returningName);
|
||||
@@ -482,8 +482,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
if (this.throwingName != null) {
|
||||
if (!this.argumentBindings.containsKey(this.throwingName)) {
|
||||
throw new IllegalStateException("Throwing argument name '"
|
||||
+ this.throwingName + "' was not bound in advice arguments");
|
||||
throw new IllegalStateException("Throwing argument name '" + this.throwingName +
|
||||
"' was not bound in advice arguments");
|
||||
}
|
||||
else {
|
||||
Integer index = this.argumentBindings.get(this.throwingName);
|
||||
@@ -581,10 +581,9 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
|
||||
if (numBound != this.adviceInvocationArgumentCount) {
|
||||
throw new IllegalStateException("Required to bind " + this.adviceInvocationArgumentCount
|
||||
+ " arguments, but only bound " + numBound + " (JoinPointMatch " +
|
||||
(jpMatch == null ? "was NOT" : "WAS") +
|
||||
" bound in invocation)");
|
||||
throw new IllegalStateException("Required to bind " + this.adviceInvocationArgumentCount +
|
||||
" arguments, but only bound " + numBound + " (JoinPointMatch " +
|
||||
(jpMatch == null ? "was NOT" : "WAS") + " bound in invocation)");
|
||||
}
|
||||
|
||||
return adviceInvocationArgs;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,6 +37,7 @@ public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodI
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
|
||||
+2
@@ -40,6 +40,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
@@ -62,6 +63,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Following AspectJ semantics, if a returning clause was specified, then the
|
||||
* advice is only invoked if the returned value is an instance of the given
|
||||
|
||||
+8
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,6 +37,7 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
@@ -57,11 +58,11 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
try {
|
||||
return mi.proceed();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (shouldInvokeOnThrowing(t)) {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, t);
|
||||
catch (Throwable ex) {
|
||||
if (shouldInvokeOnThrowing(ex)) {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, ex);
|
||||
}
|
||||
throw t;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +70,8 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
||||
* In AspectJ semantics, after throwing advice that specifies a throwing clause
|
||||
* is only invoked if the thrown exception is a subtype of the given throwing type.
|
||||
*/
|
||||
private boolean shouldInvokeOnThrowing(Throwable t) {
|
||||
return getDiscoveredThrowingType().isAssignableFrom(t.getClass());
|
||||
private boolean shouldInvokeOnThrowing(Throwable ex) {
|
||||
return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,6 +41,7 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
||||
super(aspectJAroundAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
@@ -56,7 +57,6 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
if (!(mi instanceof ProxyMethodInvocation)) {
|
||||
|
||||
+1
-1
@@ -305,7 +305,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
checkReadyToMatch();
|
||||
ShadowMatch shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method);
|
||||
ShadowMatch originalShadowMatch = getShadowMatch(method, method);
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,6 +35,7 @@ public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements
|
||||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void before(Method method, Object[] args, Object target) throws Throwable {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, null);
|
||||
|
||||
+31
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -61,34 +61,6 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
private static final String AJC_MAGIC = "ajc$";
|
||||
|
||||
|
||||
/**
|
||||
* Find and return the first AspectJ annotation on the given method
|
||||
* (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);
|
||||
if (foundAnnotation != null) {
|
||||
return foundAnnotation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
|
||||
A result = AnnotationUtils.findAnnotation(method, toLookFor);
|
||||
if (result != null) {
|
||||
return new AspectJAnnotation<A>(result);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@@ -181,6 +153,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
throw new IllegalStateException("Expecting at least " + argNames.length +
|
||||
" arguments in the advice declaration, but only found " + paramTypes.length);
|
||||
}
|
||||
|
||||
// Make the simplifying assumption for now that all of the JoinPoint based arguments
|
||||
// come first in the advice declaration.
|
||||
int typeOffset = paramTypes.length - argNames.length;
|
||||
@@ -191,7 +164,36 @@ 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...)
|
||||
*/
|
||||
@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);
|
||||
if (foundAnnotation != null) {
|
||||
return foundAnnotation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
|
||||
A result = AnnotationUtils.findAnnotation(method, toLookFor);
|
||||
if (result != null) {
|
||||
return new AspectJAnnotation<A>(result);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected enum AspectJAnnotationType {
|
||||
|
||||
AtPointcut,
|
||||
AtBefore,
|
||||
AtAfter,
|
||||
|
||||
+13
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -63,31 +63,31 @@ public interface AspectJAdvisorFactory {
|
||||
/**
|
||||
* Build Spring AOP Advisors for all annotated At-AspectJ methods
|
||||
* on the specified aspect instance.
|
||||
* @param aif the aspect instance factory (not the aspect instance itself
|
||||
* in order to avoid eager instantiation)
|
||||
* @param aspectInstanceFactory the aspect instance factory
|
||||
* (not the aspect instance itself in order to avoid eager instantiation)
|
||||
* @return a list of advisors for this class
|
||||
*/
|
||||
List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aif);
|
||||
List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);
|
||||
|
||||
/**
|
||||
* Build a Spring AOP Advisor for the given AspectJ advice method.
|
||||
* @param candidateAdviceMethod the candidate advice method
|
||||
* @param aif the aspect instance factory
|
||||
* @param declarationOrderInAspect the declaration order within the aspect
|
||||
* @param aspectInstanceFactory the aspect instance factory
|
||||
* @param declarationOrder the declaration order within the aspect
|
||||
* @param aspectName the name of the aspect
|
||||
* @return {@code null} if the method is not an AspectJ advice method
|
||||
* or if it is a pointcut that will be used by other advice but will not
|
||||
* create a Spring advice in its own right
|
||||
*/
|
||||
Advisor getAdvisor(Method candidateAdviceMethod,
|
||||
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName);
|
||||
Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
|
||||
int declarationOrder, String aspectName);
|
||||
|
||||
/**
|
||||
* Build a Spring AOP Advice for the given AspectJ advice method.
|
||||
* @param candidateAdviceMethod the candidate advice method
|
||||
* @param pointcut the corresponding AspectJ expression pointcut
|
||||
* @param aif the aspect instance factory
|
||||
* @param declarationOrderInAspect the declaration order within the aspect
|
||||
* @param expressionPointcut the AspectJ expression pointcut
|
||||
* @param aspectInstanceFactory the aspect instance factory
|
||||
* @param declarationOrder the declaration order within the aspect
|
||||
* @param aspectName the name of the aspect
|
||||
* @return {@code null} if the method is not an AspectJ advice method
|
||||
* or if it is a pointcut that will be used by other advice but will not
|
||||
@@ -98,7 +98,7 @@ public interface AspectJAdvisorFactory {
|
||||
* @see org.springframework.aop.aspectj.AspectJAfterReturningAdvice
|
||||
* @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice
|
||||
*/
|
||||
Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut pointcut,
|
||||
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName);
|
||||
Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
|
||||
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName);
|
||||
|
||||
}
|
||||
|
||||
+9
-9
@@ -42,6 +42,13 @@ import org.springframework.aop.support.ComposablePointcut;
|
||||
*/
|
||||
public class AspectMetadata {
|
||||
|
||||
/**
|
||||
* The name of this aspect as defined to Spring (the bean name) -
|
||||
* allows us to determine if two pieces of advice come from the
|
||||
* same aspect and hence their relative precedence.
|
||||
*/
|
||||
private final String aspectName;
|
||||
|
||||
/**
|
||||
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
|
||||
*/
|
||||
@@ -54,13 +61,6 @@ public class AspectMetadata {
|
||||
*/
|
||||
private final Pointcut perClausePointcut;
|
||||
|
||||
/**
|
||||
* The name of this aspect as defined to Spring (the bean name) -
|
||||
* allows us to determine if two pieces of advice come from the
|
||||
* same aspect and hence their relative precedence.
|
||||
*/
|
||||
private String aspectName;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AspectMetadata instance for the given aspect class.
|
||||
@@ -83,10 +83,10 @@ public class AspectMetadata {
|
||||
if (ajType == null) {
|
||||
throw new IllegalArgumentException("Class '" + aspectClass.getName() + "' is not an @AspectJ aspect");
|
||||
}
|
||||
this.ajType = ajType;
|
||||
if (this.ajType.getDeclarePrecedence().length > 0) {
|
||||
if (ajType.getDeclarePrecedence().length > 0) {
|
||||
throw new IllegalArgumentException("DeclarePrecendence not presently supported in Spring AOP");
|
||||
}
|
||||
this.ajType = ajType;
|
||||
|
||||
switch (this.ajType.getPerClause().getKind()) {
|
||||
case SINGLETON :
|
||||
|
||||
+29
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,53 +42,55 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
private final AspectJExpressionPointcut declaredPointcut;
|
||||
|
||||
private Pointcut pointcut;
|
||||
private final Method aspectJAdviceMethod;
|
||||
|
||||
private final AspectJAdvisorFactory aspectJAdvisorFactory;
|
||||
|
||||
private final MetadataAwareAspectInstanceFactory aspectInstanceFactory;
|
||||
|
||||
private final Method method;
|
||||
private final int declarationOrder;
|
||||
|
||||
private final String aspectName;
|
||||
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private final boolean lazy;
|
||||
|
||||
private final AspectJAdvisorFactory atAspectJAdvisorFactory;
|
||||
|
||||
private Advice instantiatedAdvice;
|
||||
|
||||
private int declarationOrder;
|
||||
|
||||
private String aspectName;
|
||||
|
||||
private Boolean isBeforeAdvice;
|
||||
|
||||
private Boolean isAfterAdvice;
|
||||
|
||||
|
||||
public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp,
|
||||
MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
|
||||
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
|
||||
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
|
||||
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
|
||||
|
||||
this.declaredPointcut = ajexp;
|
||||
this.method = method;
|
||||
this.atAspectJAdvisorFactory = af;
|
||||
this.aspectInstanceFactory = aif;
|
||||
this.declarationOrder = declarationOrderInAspect;
|
||||
this.declaredPointcut = declaredPointcut;
|
||||
this.aspectJAdviceMethod = aspectJAdviceMethod;
|
||||
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
|
||||
this.aspectInstanceFactory = aspectInstanceFactory;
|
||||
this.declarationOrder = declarationOrder;
|
||||
this.aspectName = aspectName;
|
||||
|
||||
if (aif.getAspectMetadata().isLazilyInstantiated()) {
|
||||
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
|
||||
// Static part of the pointcut is a lazy type.
|
||||
Pointcut preInstantiationPointcut =
|
||||
Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
|
||||
Pointcut preInstantiationPointcut = Pointcuts.union(
|
||||
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
|
||||
|
||||
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
|
||||
// If it's not a dynamic pointcut, it may be optimized out
|
||||
// by the Spring AOP infrastructure after the first evaluation.
|
||||
this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif);
|
||||
this.pointcut = new PerTargetInstantiationModelPointcut(
|
||||
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
|
||||
this.lazy = true;
|
||||
}
|
||||
else {
|
||||
// A singleton aspect.
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
this.pointcut = declaredPointcut;
|
||||
this.pointcut = this.declaredPointcut;
|
||||
this.lazy = false;
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +144,8 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
|
||||
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
|
||||
return this.atAspectJAdvisorFactory.getAdvice(
|
||||
this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
|
||||
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
|
||||
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
|
||||
}
|
||||
|
||||
public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() {
|
||||
@@ -191,7 +193,7 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
*/
|
||||
private void determineAdviceType() {
|
||||
AspectJAnnotation<?> aspectJAnnotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.method);
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.aspectJAdviceMethod);
|
||||
if (aspectJAnnotation == null) {
|
||||
this.isBeforeAdvice = false;
|
||||
this.isAfterAdvice = false;
|
||||
@@ -220,7 +222,7 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
|
||||
"]; advice method [" + this.method + "]; perClauseKind=" +
|
||||
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
|
||||
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
|
||||
|
||||
}
|
||||
@@ -256,7 +258,7 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
// This can match only on declared pointcut.
|
||||
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass));
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,8 +19,8 @@ package org.springframework.aop.aspectj.annotation;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
/**
|
||||
* AspectInstanceFactory backed by a BeanFactory-provided prototype,
|
||||
* enforcing prototype semantics.
|
||||
* {@link org.springframework.aop.aspectj.AspectInstanceFactory} backed by a
|
||||
* {@link BeanFactory}-provided prototype, enforcing prototype semantics.
|
||||
*
|
||||
* <p>Note that this may instantiate multiple times, which probably won't give the
|
||||
* semantics you expect. Use a {@link LazySingletonAspectInstanceFactoryDecorator}
|
||||
|
||||
+35
-26
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -77,8 +77,9 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
new Converter<Method, Annotation>() {
|
||||
@Override
|
||||
public Annotation convert(Method method) {
|
||||
AspectJAnnotation<?> annotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return annotation == null ? null : annotation.getAnnotation();
|
||||
AspectJAnnotation<?> annotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
|
||||
return (annotation != null ? annotation.getAnnotation() : null);
|
||||
}
|
||||
}));
|
||||
comparator.addComparator(new ConvertingComparator<Method, String>(
|
||||
@@ -93,17 +94,17 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
|
||||
@Override
|
||||
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
|
||||
final Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
|
||||
final String aspectName = maaif.getAspectMetadata().getAspectName();
|
||||
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
|
||||
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
|
||||
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
|
||||
validate(aspectClass);
|
||||
|
||||
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
|
||||
// so that it will only instantiate once.
|
||||
final MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
|
||||
new LazySingletonAspectInstanceFactoryDecorator(maaif);
|
||||
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
|
||||
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
|
||||
|
||||
final List<Advisor> advisors = new LinkedList<Advisor>();
|
||||
List<Advisor> advisors = new LinkedList<Advisor>();
|
||||
for (Method method : getAdvisorMethods(aspectClass)) {
|
||||
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
|
||||
if (advisor != null) {
|
||||
@@ -169,18 +170,19 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
|
||||
@Override
|
||||
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif,
|
||||
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
|
||||
int declarationOrderInAspect, String aspectName) {
|
||||
|
||||
validate(aif.getAspectMetadata().getAspectClass());
|
||||
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
|
||||
|
||||
AspectJExpressionPointcut ajexp =
|
||||
getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
|
||||
if (ajexp == null) {
|
||||
AspectJExpressionPointcut expressionPointcut = getPointcut(
|
||||
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
|
||||
if (expressionPointcut == null) {
|
||||
return null;
|
||||
}
|
||||
return new InstantiationModelAwarePointcutAdvisorImpl(
|
||||
this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
|
||||
|
||||
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
|
||||
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
|
||||
}
|
||||
|
||||
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
|
||||
@@ -189,6 +191,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
if (aspectJAnnotation == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AspectJExpressionPointcut ajexp =
|
||||
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
|
||||
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
|
||||
@@ -197,10 +200,10 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
|
||||
@Override
|
||||
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp,
|
||||
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
|
||||
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
|
||||
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
|
||||
|
||||
Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass();
|
||||
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
|
||||
validate(candidateAspectClass);
|
||||
|
||||
AspectJAnnotation<?> aspectJAnnotation =
|
||||
@@ -225,27 +228,32 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
|
||||
switch (aspectJAnnotation.getAnnotationType()) {
|
||||
case AtBefore:
|
||||
springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJMethodBeforeAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
break;
|
||||
case AtAfter:
|
||||
springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJAfterAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
break;
|
||||
case AtAfterReturning:
|
||||
springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJAfterReturningAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
|
||||
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
|
||||
springAdvice.setReturningName(afterReturningAnnotation.returning());
|
||||
}
|
||||
break;
|
||||
case AtAfterThrowing:
|
||||
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJAfterThrowingAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
|
||||
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
|
||||
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
|
||||
}
|
||||
break;
|
||||
case AtAround:
|
||||
springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
|
||||
springAdvice = new AspectJAroundAdvice(
|
||||
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
|
||||
break;
|
||||
case AtPointcut:
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -254,12 +262,12 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
return null;
|
||||
default:
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported advice type on method " + candidateAdviceMethod);
|
||||
"Unsupported advice type on method: " + candidateAdviceMethod);
|
||||
}
|
||||
|
||||
// Now to configure the advice...
|
||||
springAdvice.setAspectName(aspectName);
|
||||
springAdvice.setDeclarationOrder(declarationOrderInAspect);
|
||||
springAdvice.setDeclarationOrder(declarationOrder);
|
||||
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
|
||||
if (argNames != null) {
|
||||
springAdvice.setArgumentNamesFromStringArray(argNames);
|
||||
@@ -268,6 +276,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
return springAdvice;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Synthetic advisor that instantiates the aspect.
|
||||
* Triggered by per-clause pointcut on non-singleton aspect.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -113,7 +113,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
* Create a AdvisedSupport instance with the given parameters.
|
||||
* @param interfaces the proxied interfaces
|
||||
*/
|
||||
public AdvisedSupport(Class<?>[] interfaces) {
|
||||
public AdvisedSupport(Class<?>... interfaces) {
|
||||
this();
|
||||
setInterfaces(interfaces);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -91,17 +91,17 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
++this.evaluations;
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
this.evaluations++;
|
||||
ControlFlow cflow = ControlFlowFactory.createControlFlow();
|
||||
return (this.methodName != null) ? cflow.under(this.clazz, this.methodName) : cflow.under(this.clazz);
|
||||
return (this.methodName != null ? cflow.under(this.clazz, this.methodName) : cflow.under(this.clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* It's useful to know how many times we've fired, for optimization.
|
||||
*/
|
||||
public int getEvaluations() {
|
||||
return evaluations;
|
||||
return this.evaluations;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -138,7 +138,7 @@ public abstract class MethodMatchers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
return this.mm1.matches(method, targetClass, args) || this.mm2.matches(method, targetClass, args);
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ public abstract class MethodMatchers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
// Because a dynamic intersection may be composed of a static and dynamic part,
|
||||
// we must avoid calling the 3-arg matches method on a dynamic matcher, as
|
||||
// it will probably be an unsupported operation.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -71,7 +71,7 @@ public abstract class Pointcuts {
|
||||
* @param args arguments to the method
|
||||
* @return whether there's a runtime match
|
||||
*/
|
||||
public static boolean matches(Pointcut pointcut, Method method, Class<?> targetClass, Object[] args) {
|
||||
public static boolean matches(Pointcut pointcut, Method method, Class<?> targetClass, Object... args) {
|
||||
Assert.notNull(pointcut, "Pointcut must not be null");
|
||||
if (pointcut == Pointcut.TRUE) {
|
||||
return true;
|
||||
@@ -98,9 +98,9 @@ public abstract class Pointcuts {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return method.getName().startsWith("set") &&
|
||||
method.getParameterTypes().length == 1 &&
|
||||
method.getReturnType() == Void.TYPE;
|
||||
return (method.getName().startsWith("set") &&
|
||||
method.getParameterTypes().length == 1 &&
|
||||
method.getReturnType() == Void.TYPE);
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
@@ -119,8 +119,8 @@ public abstract class Pointcuts {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return method.getName().startsWith("get") &&
|
||||
method.getParameterTypes().length == 0;
|
||||
return (method.getName().startsWith("get") &&
|
||||
method.getParameterTypes().length == 0);
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ public abstract class StaticMethodMatcher implements MethodMatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean matches(Method method, Class<?> targetClass, Object[] args) {
|
||||
public final boolean matches(Method method, Class<?> targetClass, Object... args) {
|
||||
// should never be invoked because isRuntime() returns false
|
||||
throw new UnsupportedOperationException("Illegal MethodMatcher usage");
|
||||
}
|
||||
|
||||
+25
-37
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,17 +53,15 @@ public final class AspectJExpressionPointcutTests {
|
||||
|
||||
private Method setSomeNumber;
|
||||
|
||||
private Method isPostProcessed;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws NoSuchMethodException {
|
||||
getAge = TestBean.class.getMethod("getAge", (Class<?>[])null);
|
||||
setAge = TestBean.class.getMethod("setAge", new Class[]{int.class});
|
||||
setSomeNumber = TestBean.class.getMethod("setSomeNumber", new Class[]{Number.class});
|
||||
isPostProcessed = TestBean.class.getMethod("isPostProcessed", (Class[]) null);
|
||||
getAge = TestBean.class.getMethod("getAge");
|
||||
setAge = TestBean.class.getMethod("setAge", int.class);
|
||||
setSomeNumber = TestBean.class.getMethod("setSomeNumber", Number.class);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMatchExplicit() {
|
||||
String expression = "execution(int org.springframework.tests.sample.beans.TestBean.getAge())";
|
||||
@@ -111,21 +109,9 @@ public final class AspectJExpressionPointcutTests {
|
||||
testThisOrTarget("target");
|
||||
}
|
||||
|
||||
public static class OtherIOther implements IOther {
|
||||
|
||||
@Override
|
||||
public void absquatulate() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This and target are equivalent. Really instanceof pointcuts.
|
||||
* @param which this or target
|
||||
* @throws Exception
|
||||
* @throws NoSuchMethodException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
private void testThisOrTarget(String which) throws SecurityException, NoSuchMethodException {
|
||||
String matchesTestBean = which + "(org.springframework.tests.sample.beans.TestBean)";
|
||||
@@ -138,11 +124,8 @@ public final class AspectJExpressionPointcutTests {
|
||||
|
||||
assertTrue(testBeanPc.matches(TestBean.class));
|
||||
assertTrue(testBeanPc.matches(getAge, TestBean.class));
|
||||
assertTrue(iOtherPc.matches(OtherIOther.class.getMethod("absquatulate", (Class<?>[])null),
|
||||
OtherIOther.class));
|
||||
|
||||
assertFalse(testBeanPc.matches(OtherIOther.class.getMethod("absquatulate", (Class<?>[])null),
|
||||
OtherIOther.class));
|
||||
assertTrue(iOtherPc.matches(OtherIOther.class.getMethod("absquatulate"), OtherIOther.class));
|
||||
assertFalse(testBeanPc.matches(OtherIOther.class.getMethod("absquatulate"), OtherIOther.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -171,8 +154,7 @@ public final class AspectJExpressionPointcutTests {
|
||||
assertEquals(matchSubpackages, withinBeansPc.matches(
|
||||
DeepBean.class.getMethod("aMethod", String.class), DeepBean.class));
|
||||
assertFalse(withinBeansPc.matches(String.class));
|
||||
assertFalse(withinBeansPc.matches(OtherIOther.class.getMethod("absquatulate", (Class<?>[])null),
|
||||
OtherIOther.class));
|
||||
assertFalse(withinBeansPc.matches(OtherIOther.class.getMethod("absquatulate"), OtherIOther.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,7 +165,7 @@ public final class AspectJExpressionPointcutTests {
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("expression") != -1);
|
||||
assertTrue(ex.getMessage().contains("expression"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +177,7 @@ public final class AspectJExpressionPointcutTests {
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("expression") != -1);
|
||||
assertTrue(ex.getMessage().contains("expression"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +189,7 @@ public final class AspectJExpressionPointcutTests {
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("expression") != -1);
|
||||
assertTrue(ex.getMessage().contains("expression"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,10 +208,10 @@ public final class AspectJExpressionPointcutTests {
|
||||
//assertDoesNotMatchStringClass(classFilter);
|
||||
|
||||
assertTrue("Should match with setSomeNumber with Double input",
|
||||
methodMatcher.matches(setSomeNumber, TestBean.class, new Object[]{new Double(12)}));
|
||||
methodMatcher.matches(setSomeNumber, TestBean.class, new Double(12)));
|
||||
assertFalse("Should not match setSomeNumber with Integer input",
|
||||
methodMatcher.matches(setSomeNumber, TestBean.class, new Object[]{new Integer(11)}));
|
||||
assertFalse("Should not match getAge", methodMatcher.matches(getAge, TestBean.class, null));
|
||||
methodMatcher.matches(setSomeNumber, TestBean.class, new Integer(11)));
|
||||
assertFalse("Should not match getAge", methodMatcher.matches(getAge, TestBean.class));
|
||||
assertTrue("Should be a runtime match", methodMatcher.isRuntime());
|
||||
}
|
||||
|
||||
@@ -281,7 +263,6 @@ public final class AspectJExpressionPointcutTests {
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
assertTrue(true);
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,16 +307,14 @@ public final class AspectJExpressionPointcutTests {
|
||||
@Test
|
||||
public void testAndSubstitution() {
|
||||
Pointcut pc = getPointcut("execution(* *(..)) and args(String)");
|
||||
PointcutExpression expr =
|
||||
((AspectJExpressionPointcut) pc).getPointcutExpression();
|
||||
PointcutExpression expr = ((AspectJExpressionPointcut) pc).getPointcutExpression();
|
||||
assertEquals("execution(* *(..)) && args(String)",expr.getPointcutExpression());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleAndSubstitutions() {
|
||||
Pointcut pc = getPointcut("execution(* *(..)) and args(String) and this(Object)");
|
||||
PointcutExpression expr =
|
||||
((AspectJExpressionPointcut) pc).getPointcutExpression();
|
||||
PointcutExpression expr = ((AspectJExpressionPointcut) pc).getPointcutExpression();
|
||||
assertEquals("execution(* *(..)) && args(String) && this(Object)",expr.getPointcutExpression());
|
||||
}
|
||||
|
||||
@@ -344,6 +323,15 @@ public final class AspectJExpressionPointcutTests {
|
||||
pointcut.setExpression(expression);
|
||||
return pointcut;
|
||||
}
|
||||
|
||||
|
||||
public static class OtherIOther implements IOther {
|
||||
|
||||
@Override
|
||||
public void absquatulate() {
|
||||
// Empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+29
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,7 +36,7 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class TigerAspectJExpressionPointcutTests {
|
||||
public class TigerAspectJExpressionPointcutTests {
|
||||
|
||||
// TODO factor into static in AspectJExpressionPointcut
|
||||
private Method getAge;
|
||||
@@ -46,7 +46,7 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
|
||||
@Before
|
||||
public void setUp() throws NoSuchMethodException {
|
||||
getAge = TestBean.class.getMethod("getAge", (Class[]) null);
|
||||
getAge = TestBean.class.getMethod("getAge");
|
||||
// Assumes no overloading
|
||||
for (Method m : HasGeneric.class.getMethods()) {
|
||||
methodsOnHasGeneric.put(m.getName(), m);
|
||||
@@ -54,18 +54,6 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
}
|
||||
|
||||
|
||||
public static class HasGeneric {
|
||||
|
||||
public void setFriends(List<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> numbers) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchGenericArgument() {
|
||||
String expression = "execution(* set*(java.util.List<org.springframework.tests.sample.beans.TestBean>) )";
|
||||
@@ -132,15 +120,12 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
public void testMatchAnnotationOnClassWithSubpackageWildcard() throws SecurityException, NoSuchMethodException {
|
||||
String expression = "within(@(test.annotation..*) *)";
|
||||
AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertFalse(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class),
|
||||
TestBean.class));
|
||||
assertTrue(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo", (Class[]) null),
|
||||
SpringAnnotated.class));
|
||||
assertFalse(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class));
|
||||
assertTrue(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class));
|
||||
|
||||
expression = "within(@(test.annotation.transaction..*) *)";
|
||||
AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression);
|
||||
assertFalse(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo", (Class[]) null),
|
||||
SpringAnnotated.class));
|
||||
assertFalse(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -154,7 +139,7 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertFalse(ajexp.matches(getAge, TestBean.class));
|
||||
assertTrue(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertTrue(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertTrue(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertTrue(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class));
|
||||
assertFalse(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
@@ -168,10 +153,10 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
ajexp.setExpression(expression);
|
||||
|
||||
assertFalse(ajexp.matches(getAge, TestBean.class));
|
||||
assertFalse(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertFalse(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertFalse(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertFalse(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
assertTrue(ajexp.matches(BeanA.class.getMethod("getAge", (Class[]) null), BeanA.class));
|
||||
assertTrue(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class));
|
||||
assertFalse(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
}
|
||||
|
||||
@@ -182,10 +167,10 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
anySpringMethodAnnotation.setExpression(expression);
|
||||
|
||||
assertFalse(anySpringMethodAnnotation.matches(getAge, TestBean.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
assertTrue(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge", (Class[]) null), BeanA.class));
|
||||
assertTrue(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class));
|
||||
assertFalse(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
}
|
||||
|
||||
@@ -196,10 +181,10 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge", (Class[]) null), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
|
||||
assertTrue(takesSpringAnnotatedArgument2.matches(
|
||||
@@ -213,8 +198,7 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(
|
||||
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
|
||||
ProcessesSpringAnnotatedParameters.class,
|
||||
new Object[] { new TestBean(), new BeanA()})
|
||||
ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -225,10 +209,10 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
takesSpringAnnotatedArgument2.setExpression(expression);
|
||||
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("foo", (Class[]) null), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge", (Class[]) null), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class));
|
||||
assertFalse(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class));
|
||||
|
||||
assertTrue(takesSpringAnnotatedArgument2.matches(
|
||||
@@ -240,6 +224,19 @@ public final class TigerAspectJExpressionPointcutTests {
|
||||
}
|
||||
|
||||
|
||||
public static class HasGeneric {
|
||||
|
||||
public void setFriends(List<TestBean> friends) {
|
||||
}
|
||||
public void setEnemies(List<TestBean> enemies) {
|
||||
}
|
||||
public void setPartners(List<?> partners) {
|
||||
}
|
||||
public void setPhoneNumbers(List<String> numbers) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ProcessesSpringAnnotatedParameters {
|
||||
|
||||
public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) {
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -961,7 +962,7 @@ abstract class AbstractMakeModifiable {
|
||||
private Method getGetterFromSetter(Method setter) {
|
||||
String getterName = setter.getName().replaceFirst("set", "get");
|
||||
try {
|
||||
return setter.getDeclaringClass().getMethod(getterName, (Class[]) null);
|
||||
return setter.getDeclaringClass().getMethod(getterName);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
// must be write only
|
||||
|
||||
+19
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,18 +31,21 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AspectJPointcutAdvisorTests {
|
||||
public class AspectJPointcutAdvisorTests {
|
||||
|
||||
private final AspectJAdvisorFactory af = new ReflectiveAspectJAdvisorFactory();
|
||||
|
||||
private AspectJAdvisorFactory af = new ReflectiveAspectJAdvisorFactory();
|
||||
|
||||
@Test
|
||||
public void testSingleton() throws SecurityException, NoSuchMethodException {
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(AspectJExpressionPointcutTests.MATCH_ALL_METHODS);
|
||||
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(af, ajexp,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new AbstractAspectJAdvisorFactoryTests.ExceptionAspect(null),"someBean"),
|
||||
TestBean.class.getMethod("getAge", (Class[]) null),1,"someBean");
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(
|
||||
ajexp, TestBean.class.getMethod("getAge"), af,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new AbstractAspectJAdvisorFactoryTests.ExceptionAspect(null), "someBean"),
|
||||
1, "someBean");
|
||||
|
||||
assertSame(Pointcut.TRUE, ajpa.getAspectMetadata().getPerClausePointcut());
|
||||
assertFalse(ajpa.isPerInstance());
|
||||
}
|
||||
@@ -52,34 +55,35 @@ public final class AspectJPointcutAdvisorTests {
|
||||
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
|
||||
ajexp.setExpression(AspectJExpressionPointcutTests.MATCH_ALL_METHODS);
|
||||
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(af, ajexp,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(),"someBean"), null, 1, "someBean");
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(
|
||||
ajexp, TestBean.class.getMethod("getAge"), af,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(), "someBean"),
|
||||
1, "someBean");
|
||||
|
||||
assertNotSame(Pointcut.TRUE, ajpa.getAspectMetadata().getPerClausePointcut());
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut() instanceof AspectJExpressionPointcut);
|
||||
assertTrue(ajpa.isPerInstance());
|
||||
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut().getClassFilter().matches(TestBean.class));
|
||||
assertFalse(ajpa.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(
|
||||
TestBean.class.getMethod("getAge", (Class[]) null),
|
||||
TestBean.class));
|
||||
TestBean.class.getMethod("getAge"), TestBean.class));
|
||||
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(
|
||||
TestBean.class.getMethod("getSpouse", (Class[]) null),
|
||||
TestBean.class));
|
||||
TestBean.class.getMethod("getSpouse"), TestBean.class));
|
||||
}
|
||||
|
||||
@Test(expected=AopConfigException.class)
|
||||
@Test(expected = AopConfigException.class)
|
||||
public void testPerCflowTarget() {
|
||||
testIllegalInstantiationModel(AbstractAspectJAdvisorFactoryTests.PerCflowAspect.class);
|
||||
}
|
||||
|
||||
@Test(expected=AopConfigException.class)
|
||||
@Test(expected = AopConfigException.class)
|
||||
public void testPerCflowBelowTarget() {
|
||||
testIllegalInstantiationModel(AbstractAspectJAdvisorFactoryTests.PerCflowBelowAspect.class);
|
||||
}
|
||||
|
||||
private void testIllegalInstantiationModel(Class<?> c) throws AopConfigException {
|
||||
new AspectMetadata(c,"someBean");
|
||||
new AspectMetadata(c, "someBean");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,7 @@ public final class MethodInvocationTests {
|
||||
|
||||
@Test
|
||||
public void testValidInvocation() throws Throwable {
|
||||
Method m = Object.class.getMethod("hashCode", (Class[]) null);
|
||||
Method m = Object.class.getMethod("hashCode");
|
||||
Object proxy = new Object();
|
||||
final Object returnValue = new Object();
|
||||
List<Object> is = new LinkedList<Object>();
|
||||
@@ -67,7 +67,7 @@ public final class MethodInvocationTests {
|
||||
};
|
||||
List<Object> is = new LinkedList<Object>();
|
||||
|
||||
Method m = Object.class.getMethod("hashCode", (Class[]) null);
|
||||
Method m = Object.class.getMethod("hashCode");
|
||||
Object proxy = new Object();
|
||||
ReflectiveMethodInvocation invocation =
|
||||
new ReflectiveMethodInvocation(proxy, target, m, null, null, is);
|
||||
|
||||
+5
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -78,7 +78,7 @@ public final class ThrowsAdviceInterceptorTests {
|
||||
ThrowsAdviceInterceptor ti = new ThrowsAdviceInterceptor(th);
|
||||
FileNotFoundException ex = new FileNotFoundException();
|
||||
MethodInvocation mi = mock(MethodInvocation.class);
|
||||
given(mi.getMethod()).willReturn(Object.class.getMethod("hashCode", (Class[]) null));
|
||||
given(mi.getMethod()).willReturn(Object.class.getMethod("hashCode"));
|
||||
given(mi.getThis()).willReturn(new Object());
|
||||
given(mi.proceed()).willThrow(ex);
|
||||
try {
|
||||
@@ -140,12 +140,15 @@ public final class ThrowsAdviceInterceptorTests {
|
||||
assertEquals(1, th.getCalls("remoteException"));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class MyThrowsHandler extends MethodCounter implements ThrowsAdvice {
|
||||
|
||||
// Full method signature
|
||||
public void afterThrowing(Method m, Object[] args, Object target, IOException ex) {
|
||||
count("ioException");
|
||||
}
|
||||
|
||||
public void afterThrowing(RemoteException ex) throws Throwable {
|
||||
count("remoteException");
|
||||
}
|
||||
|
||||
+14
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,8 +54,8 @@ public abstract class AbstractRegexpMethodPointcutTests {
|
||||
}
|
||||
|
||||
protected void noPatternSuppliedTests(AbstractRegexpMethodPointcut rpc) throws Exception {
|
||||
assertFalse(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), String.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait", (Class[]) null), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("hashCode"), String.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait"), Object.class));
|
||||
assertEquals(0, rpc.getPatterns().length);
|
||||
}
|
||||
|
||||
@@ -69,38 +69,38 @@ public abstract class AbstractRegexpMethodPointcutTests {
|
||||
|
||||
protected void exactMatchTests(AbstractRegexpMethodPointcut rpc) throws Exception {
|
||||
// assumes rpc.setPattern("java.lang.Object.hashCode");
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait", (Class[]) null), Object.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait"), Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecificMatch() throws Exception {
|
||||
rpc.setPattern("java.lang.String.hashCode");
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), String.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), Object.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), String.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("hashCode"), Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildcard() throws Exception {
|
||||
rpc.setPattern(".*Object.hashCode");
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait", (Class[]) null), Object.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), Object.class));
|
||||
assertFalse(rpc.matches(Object.class.getMethod("wait"), Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildcardForOneClass() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.*");
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode", (Class[]) null), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("wait", (Class[]) null), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("hashCode"), String.class));
|
||||
assertTrue(rpc.matches(Object.class.getMethod("wait"), String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchesObjectClass() throws Exception {
|
||||
rpc.setPattern("java.lang.Object.*");
|
||||
assertTrue(rpc.matches(Exception.class.getMethod("hashCode", (Class[]) null), IOException.class));
|
||||
assertTrue(rpc.matches(Exception.class.getMethod("hashCode"), IOException.class));
|
||||
// Doesn't match a method from Throwable
|
||||
assertFalse(rpc.matches(Exception.class.getMethod("getMessage", (Class[]) null), Exception.class));
|
||||
assertFalse(rpc.matches(Exception.class.getMethod("getMessage"), Exception.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+18
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class ComposablePointcutTests {
|
||||
public class ComposablePointcutTests {
|
||||
|
||||
public static MethodMatcher GETTER_METHOD_MATCHER = new StaticMethodMatcher() {
|
||||
@Override
|
||||
@@ -62,11 +62,12 @@ public final class ComposablePointcutTests {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Test
|
||||
public void testMatchAll() throws NoSuchMethodException {
|
||||
Pointcut pc = new ComposablePointcut();
|
||||
assertTrue(pc.getClassFilter().matches(Object.class));
|
||||
assertTrue(pc.getMethodMatcher().matches(Object.class.getMethod("hashCode", (Class[]) null), Exception.class));
|
||||
assertTrue(pc.getMethodMatcher().matches(Object.class.getMethod("hashCode"), Exception.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,23 +94,23 @@ public final class ComposablePointcutTests {
|
||||
public void testUnionMethodMatcher() {
|
||||
// Matches the getAge() method in any class
|
||||
ComposablePointcut pc = new ComposablePointcut(ClassFilter.TRUE, GET_AGE_METHOD_MATCHER);
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
|
||||
pc.union(GETTER_METHOD_MATCHER);
|
||||
// Should now match all getter methods
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
|
||||
pc.union(ABSQUATULATE_METHOD_MATCHER);
|
||||
// Should now match absquatulate() as well
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
// But it doesn't match everything
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_SET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_SET_AGE, TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -124,9 +125,9 @@ public final class ComposablePointcutTests {
|
||||
assertTrue(pc.getMethodMatcher().matches(PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
pc.intersection(GET_AGE_METHOD_MATCHER);
|
||||
// Use the Pointcuts matches method
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(pc, PointcutsTests.TEST_BEAN_GET_NAME, TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -153,4 +154,5 @@ public final class ComposablePointcutTests {
|
||||
assertEquals(pc1, pc2);
|
||||
assertEquals(pc1.hashCode(), pc2.hashCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import static org.junit.Assert.*;
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class MethodMatchersTests {
|
||||
public class MethodMatchersTests {
|
||||
|
||||
private final Method EXCEPTION_GETMESSAGE;
|
||||
|
||||
@@ -44,10 +44,10 @@ public final class MethodMatchersTests {
|
||||
|
||||
|
||||
public MethodMatchersTests() throws Exception {
|
||||
EXCEPTION_GETMESSAGE = Exception.class.getMethod("getMessage", (Class[]) null);
|
||||
ITESTBEAN_GETAGE = ITestBean.class.getMethod("getAge", (Class[]) null);
|
||||
ITESTBEAN_SETAGE = ITestBean.class.getMethod("setAge", new Class[] { int.class });
|
||||
IOTHER_ABSQUATULATE = IOther.class.getMethod("absquatulate", (Class[]) null);
|
||||
EXCEPTION_GETMESSAGE = Exception.class.getMethod("getMessage");
|
||||
ITESTBEAN_GETAGE = ITestBean.class.getMethod("getAge");
|
||||
ITESTBEAN_SETAGE = ITestBean.class.getMethod("setAge", int.class);
|
||||
IOTHER_ABSQUATULATE = IOther.class.getMethod("absquatulate");
|
||||
}
|
||||
|
||||
|
||||
@@ -82,12 +82,12 @@ public final class MethodMatchersTests {
|
||||
MethodMatcher intersection = MethodMatchers.intersection(mm1, mm2);
|
||||
assertTrue("Intersection is a dynamic matcher", intersection.isRuntime());
|
||||
assertTrue("2Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class));
|
||||
assertTrue("3Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class, new Object[] { new Integer(5) }));
|
||||
assertTrue("3Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class, new Integer(5)));
|
||||
// Knock out dynamic part
|
||||
intersection = MethodMatchers.intersection(intersection, new TestDynamicMethodMatcherWhichDoesNotMatch());
|
||||
assertTrue("Intersection is a dynamic matcher", intersection.isRuntime());
|
||||
assertTrue("2Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class));
|
||||
assertFalse("3 - not Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class, new Object[] { new Integer(5) }));
|
||||
assertFalse("3 - not Matched setAge method", intersection.matches(ITESTBEAN_SETAGE, TestBean.class, new Integer(5)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,18 +125,20 @@ public final class MethodMatchersTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class TestDynamicMethodMatcherWhichMatches extends DynamicMethodMatcher {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method m, Class<?> targetClass, Object... args) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class TestDynamicMethodMatcherWhichDoesNotMatch extends DynamicMethodMatcher {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method m, Class<?> targetClass, Object... args) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class PointcutsTests {
|
||||
public class PointcutsTests {
|
||||
|
||||
public static Method TEST_BEAN_SET_AGE;
|
||||
public static Method TEST_BEAN_GET_AGE;
|
||||
@@ -39,10 +39,10 @@ public final class PointcutsTests {
|
||||
|
||||
static {
|
||||
try {
|
||||
TEST_BEAN_SET_AGE = TestBean.class.getMethod("setAge", new Class[] { int.class });
|
||||
TEST_BEAN_GET_AGE = TestBean.class.getMethod("getAge", (Class[]) null);
|
||||
TEST_BEAN_GET_NAME = TestBean.class.getMethod("getName", (Class[]) null);
|
||||
TEST_BEAN_ABSQUATULATE = TestBean.class.getMethod("absquatulate", (Class[]) null);
|
||||
TEST_BEAN_SET_AGE = TestBean.class.getMethod("setAge", int.class);
|
||||
TEST_BEAN_GET_AGE = TestBean.class.getMethod("getAge");
|
||||
TEST_BEAN_GET_NAME = TestBean.class.getMethod("getName");
|
||||
TEST_BEAN_ABSQUATULATE = TestBean.class.getMethod("absquatulate");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException("Shouldn't happen: error in test suite");
|
||||
@@ -125,22 +125,22 @@ public final class PointcutsTests {
|
||||
|
||||
@Test
|
||||
public void testTrue() {
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(Pointcut.TRUE, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatches() {
|
||||
assertTrue(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertFalse(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertFalse(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassSetterPointcut, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassGetterPointcut, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,29 +149,29 @@ public final class PointcutsTests {
|
||||
@Test
|
||||
public void testUnionOfSettersAndGetters() {
|
||||
Pointcut union = Pointcuts.union(allClassGetterPointcut, allClassSetterPointcut);
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnionOfSpecificGetters() {
|
||||
Pointcut union = Pointcuts.union(allClassGetAgePointcut, allClassGetNamePointcut);
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
|
||||
// Union with all setters
|
||||
union = Pointcuts.union(union, allClassSetterPointcut);
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,16 +180,16 @@ public final class PointcutsTests {
|
||||
*/
|
||||
@Test
|
||||
public void testUnionOfAllSettersAndSubclassSetters() {
|
||||
assertFalse(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_SET_AGE, MyTestBean.class, new Object[] { new Integer(6)}));
|
||||
assertFalse(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertTrue(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_SET_AGE, MyTestBean.class, new Integer(6)));
|
||||
assertFalse(Pointcuts.matches(myTestBeanSetterPointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
|
||||
Pointcut union = Pointcuts.union(myTestBeanSetterPointcut, allClassGetterPointcut);
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
// Still doesn't match superclass setter
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, MyTestBean.class, new Object[] { new Integer(6)}));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_SET_AGE, MyTestBean.class, new Integer(6)));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,44 +198,44 @@ public final class PointcutsTests {
|
||||
*/
|
||||
@Test
|
||||
public void testIntersectionOfSpecificGettersAndSubclassGetters() {
|
||||
assertTrue(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_NAME, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(allClassGetAgePointcut, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
assertFalse(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_NAME, MyTestBean.class));
|
||||
assertTrue(Pointcuts.matches(myTestBeanGetterPointcut, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
|
||||
Pointcut intersection = Pointcuts.intersection(allClassGetAgePointcut, myTestBeanGetterPointcut);
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBean.class));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
// Matches subclass of MyTestBean
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class, null));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class));
|
||||
|
||||
// Now intersection with MyTestBeanSubclass getters should eliminate MyTestBean target
|
||||
intersection = Pointcuts.intersection(intersection, myTestBeanSubclassGetterPointcut);
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
// Still matches subclass of MyTestBean
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class, null));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class));
|
||||
assertTrue(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class));
|
||||
|
||||
// Now union with all TestBean methods
|
||||
Pointcut union = Pointcuts.union(intersection, allTestBeanMethodsPointcut);
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_NAME, MyTestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_NAME, TestBean.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_NAME, MyTestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBean.class));
|
||||
// Still matches subclass of MyTestBean
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_GET_NAME, MyTestBeanSubclass.class));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_GET_AGE, MyTestBeanSubclass.class));
|
||||
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, MyTestBean.class, null));
|
||||
assertTrue(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(union, TEST_BEAN_ABSQUATULATE, MyTestBean.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -245,9 +245,9 @@ public final class PointcutsTests {
|
||||
@Test
|
||||
public void testSimpleIntersection() {
|
||||
Pointcut intersection = Pointcuts.intersection(allClassGetterPointcut, allClassSetterPointcut);
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_SET_AGE, TestBean.class, new Object[] { new Integer(6)}));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_ABSQUATULATE, TestBean.class, null));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_SET_AGE, TestBean.class, new Integer(6)));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_GET_AGE, TestBean.class));
|
||||
assertFalse(Pointcuts.matches(intersection, TEST_BEAN_ABSQUATULATE, TestBean.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-2
@@ -24,9 +24,7 @@ import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
|
||||
import org.springframework.aop.interceptor.AsyncExecutionAspectSupport;
|
||||
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Abstract aspect that routes selected methods asynchronously.
|
||||
|
||||
+6
-6
@@ -31,7 +31,6 @@ import groovy.lang.GroovyObjectSupport;
|
||||
import groovy.lang.GroovyShell;
|
||||
import groovy.lang.GroovySystem;
|
||||
import groovy.lang.MetaClass;
|
||||
|
||||
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
|
||||
import org.codehaus.groovy.runtime.InvokerHelper;
|
||||
|
||||
@@ -337,8 +336,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("Namespace definition must supply a non-null URI");
|
||||
}
|
||||
NamespaceHandler namespaceHandler = this.groovyDslXmlBeanDefinitionReader.getNamespaceHandlerResolver().resolve(
|
||||
uri);
|
||||
NamespaceHandler namespaceHandler =
|
||||
this.groovyDslXmlBeanDefinitionReader.getNamespaceHandlerResolver().resolve(uri);
|
||||
if (namespaceHandler == null) {
|
||||
throw new BeanDefinitionParsingException(new Problem("No namespace handler found for URI: " + uri,
|
||||
new Location(new DescriptiveResource(("Groovy")))));
|
||||
@@ -375,7 +374,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
throw new IllegalArgumentException("Argument to ref() is not a valid bean or was not found");
|
||||
|
||||
if (args[0] instanceof RuntimeBeanReference) {
|
||||
refName = ((RuntimeBeanReference)args[0]).getBeanName();
|
||||
refName = ((RuntimeBeanReference) args[0]).getBeanName();
|
||||
}
|
||||
else {
|
||||
refName = args[0].toString();
|
||||
@@ -388,7 +387,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
}
|
||||
return new RuntimeBeanReference(refName, parentRef);
|
||||
}
|
||||
else if (this.namespaces.containsKey(name) && args.length > 0 && (args[0] instanceof Closure)) {
|
||||
else if (this.namespaces.containsKey(name) && args.length > 0 && args[0] instanceof Closure) {
|
||||
GroovyDynamicElementReader reader = createDynamicElementReader(name);
|
||||
reader.invokeMethod("doCall", args);
|
||||
}
|
||||
@@ -396,7 +395,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||
// abstract bean definition
|
||||
return invokeBeanDefiningMethod(name, args);
|
||||
}
|
||||
else if (args.length > 0 && (args[0] instanceof Class || args[0] instanceof RuntimeBeanReference || args[0] instanceof Map)) {
|
||||
else if (args.length > 0 &&
|
||||
(args[0] instanceof Class || args[0] instanceof RuntimeBeanReference || args[0] instanceof Map)) {
|
||||
return invokeBeanDefiningMethod(name, args);
|
||||
}
|
||||
else if (args.length > 1 && args[args.length -1] instanceof Closure) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -278,8 +278,12 @@ public abstract class BeanUtils {
|
||||
targetMethod = method;
|
||||
numMethodsFoundWithCurrentMinimumArgs = 1;
|
||||
}
|
||||
else {
|
||||
if (targetMethod.getParameterTypes().length == numParams) {
|
||||
else if (!method.isBridge() && targetMethod.getParameterTypes().length == numParams) {
|
||||
if (targetMethod.isBridge()) {
|
||||
// Prefer regular method over bridge...
|
||||
targetMethod = method;
|
||||
}
|
||||
else {
|
||||
// Additional candidate with same length
|
||||
numMethodsFoundWithCurrentMinimumArgs++;
|
||||
}
|
||||
@@ -289,7 +293,7 @@ public abstract class BeanUtils {
|
||||
if (numMethodsFoundWithCurrentMinimumArgs > 1) {
|
||||
throw new IllegalArgumentException("Cannot resolve method '" + methodName +
|
||||
"' to a unique method. Attempted to resolve to overloaded method with " +
|
||||
"the least number of parameters, but there were " +
|
||||
"the least number of parameters but there were " +
|
||||
numMethodsFoundWithCurrentMinimumArgs + " candidates.");
|
||||
}
|
||||
return targetMethod;
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,7 +56,7 @@ public class UnsatisfiedDependencyException extends BeanCreationException {
|
||||
public UnsatisfiedDependencyException(
|
||||
String resourceDescription, String beanName, String propertyName, BeansException ex) {
|
||||
|
||||
this(resourceDescription, beanName, propertyName, (ex != null ? ": " + ex.getMessage() : ""));
|
||||
this(resourceDescription, beanName, propertyName, (ex != null ? ex.getMessage() : ""));
|
||||
initCause(ex);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public class UnsatisfiedDependencyException extends BeanCreationException {
|
||||
public UnsatisfiedDependencyException(
|
||||
String resourceDescription, String beanName, int ctorArgIndex, Class<?> ctorArgType, BeansException ex) {
|
||||
|
||||
this(resourceDescription, beanName, ctorArgIndex, ctorArgType, (ex != null ? ": " + ex.getMessage() : ""));
|
||||
this(resourceDescription, beanName, ctorArgIndex, ctorArgType, (ex != null ? ex.getMessage() : ""));
|
||||
initCause(ex);
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -196,6 +196,7 @@ public class DependencyDescriptor implements Serializable {
|
||||
* Optionally set the concrete class that contains this dependency.
|
||||
* This may differ from the class that declares the parameter/field in that
|
||||
* it may be a subclass thereof, potentially substituting type variables.
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setContainingClass(Class<?> containingClass) {
|
||||
this.containingClass = containingClass;
|
||||
@@ -206,6 +207,7 @@ public class DependencyDescriptor implements Serializable {
|
||||
|
||||
/**
|
||||
* Build a ResolvableType object for the wrapped parameter/field.
|
||||
* @since 4.0
|
||||
*/
|
||||
public ResolvableType getResolvableType() {
|
||||
return (this.field != null ? ResolvableType.forField(this.field, this.nestingLevel, this.containingClass) :
|
||||
@@ -217,6 +219,7 @@ public class DependencyDescriptor implements Serializable {
|
||||
* <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}
|
||||
* that a fallback match is acceptable as well.
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean fallbackMatchAllowed() {
|
||||
return false;
|
||||
@@ -224,6 +227,7 @@ public class DependencyDescriptor implements Serializable {
|
||||
|
||||
/**
|
||||
* Return a variant of this descriptor that is intended for a fallback match.
|
||||
* @since 4.0
|
||||
* @see #fallbackMatchAllowed()
|
||||
*/
|
||||
public DependencyDescriptor forFallbackMatch() {
|
||||
|
||||
+6
-1
@@ -1475,9 +1475,14 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
logger.debug("Bean currently in creation on FactoryBean type check: " + ex);
|
||||
}
|
||||
}
|
||||
else if (mbd.isLazyInit()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Bean creation exception on lazy FactoryBean type check: " + ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Bean creation exception on FactoryBean type check: " + ex);
|
||||
logger.warn("Bean creation exception on non-lazy FactoryBean type check: " + ex);
|
||||
}
|
||||
}
|
||||
onSuppressedException(ex);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -300,7 +300,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new BeanDefinitionValidationException("Couldn't find a unique destroy method on bean with name '" +
|
||||
throw new BeanDefinitionValidationException("Could not find unique destroy method on bean with name '" +
|
||||
this.beanName + ": " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -17,7 +17,6 @@
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
+21
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,14 +24,13 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link java.beans.PropertyEditor} implementation for
|
||||
* {@link java.beans.PropertyEditor} implementation for standard JDK
|
||||
* {@link java.util.ResourceBundle ResourceBundles}.
|
||||
*
|
||||
* <p>Only supports conversion <i>from</i> a String, but not
|
||||
* <i>to</i> a String.
|
||||
* <p>Only supports conversion <i>from</i> a String, but not <i>to</i> a String.
|
||||
*
|
||||
* Find below some examples of using this class in a
|
||||
* (properly configured) Spring container using XML-based metadata:
|
||||
* Find below some examples of using this class in a (properly configured)
|
||||
* Spring container using XML-based metadata:
|
||||
*
|
||||
* <pre class="code"> <bean id="errorDialog" class="...">
|
||||
* <!--
|
||||
@@ -62,19 +61,20 @@ import org.springframework.util.StringUtils;
|
||||
* </property>
|
||||
* </bean></pre>
|
||||
*
|
||||
* <p>Please note that this {@link java.beans.PropertyEditor} is
|
||||
* <b>not</b> registered by default with any of the Spring infrastructure.
|
||||
* <p>Please note that this {@link java.beans.PropertyEditor} is <b>not</b>
|
||||
* registered by default with any of the Spring infrastructure.
|
||||
*
|
||||
* <p>Thanks to David Leal Valmana for the suggestion and initial prototype.
|
||||
*
|
||||
* @author Rick Evans
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ResourceBundleEditor extends PropertyEditorSupport {
|
||||
|
||||
/**
|
||||
* The separator used to distinguish between the base name and the
|
||||
* locale (if any) when {@link #setAsText(String) converting from a String}.
|
||||
* The separator used to distinguish between the base name and the locale
|
||||
* (if any) when {@link #setAsText(String) converting from a String}.
|
||||
*/
|
||||
public static final String BASE_NAME_SEPARATOR = "_";
|
||||
|
||||
@@ -82,25 +82,23 @@ public class ResourceBundleEditor extends PropertyEditorSupport {
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
Assert.hasText(text, "'text' must not be empty");
|
||||
ResourceBundle bundle;
|
||||
String rawBaseName = text.trim();
|
||||
int indexOfBaseNameSeparator = rawBaseName.indexOf(BASE_NAME_SEPARATOR);
|
||||
if (indexOfBaseNameSeparator == -1) {
|
||||
bundle = ResourceBundle.getBundle(rawBaseName);
|
||||
String name = text.trim();
|
||||
|
||||
int separator = name.indexOf(BASE_NAME_SEPARATOR);
|
||||
if (separator == -1) {
|
||||
setValue(ResourceBundle.getBundle(name));
|
||||
}
|
||||
else {
|
||||
// it potentially has locale information
|
||||
String baseName = rawBaseName.substring(0, indexOfBaseNameSeparator);
|
||||
// The name potentially contains locale information
|
||||
String baseName = name.substring(0, separator);
|
||||
if (!StringUtils.hasText(baseName)) {
|
||||
throw new IllegalArgumentException("Bad ResourceBundle name : received '" + text + "' as argument to 'setAsText(String value)'.");
|
||||
throw new IllegalArgumentException("Invalid ResourceBundle name: '" + text + "'");
|
||||
}
|
||||
String localeString = rawBaseName.substring(indexOfBaseNameSeparator + 1);
|
||||
String localeString = name.substring(separator + 1);
|
||||
Locale locale = StringUtils.parseLocaleString(localeString);
|
||||
bundle = (StringUtils.hasText(localeString))
|
||||
? ResourceBundle.getBundle(baseName, locale)
|
||||
: ResourceBundle.getBundle(baseName);
|
||||
setValue((StringUtils.hasText(localeString)) ? ResourceBundle.getBundle(baseName, locale) :
|
||||
ResourceBundle.getBundle(baseName));
|
||||
}
|
||||
setValue(bundle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -2890,7 +2890,13 @@ public class DefaultListableBeanFactoryTests {
|
||||
}
|
||||
|
||||
|
||||
public static class BeanWithDestroyMethod {
|
||||
public static abstract class BaseClassWithDestroyMethod {
|
||||
|
||||
public abstract BaseClassWithDestroyMethod close();
|
||||
}
|
||||
|
||||
|
||||
public static class BeanWithDestroyMethod extends BaseClassWithDestroyMethod {
|
||||
|
||||
private static int closeCount = 0;
|
||||
|
||||
@@ -2900,8 +2906,10 @@ public class DefaultListableBeanFactoryTests {
|
||||
this.inner = inner;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
@Override
|
||||
public BeanWithDestroyMethod close() {
|
||||
closeCount++;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,9 +28,10 @@ import static org.junit.Assert.*;
|
||||
* @author Rick Evans
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class ResourceBundleEditorTests {
|
||||
public class ResourceBundleEditorTests {
|
||||
|
||||
private static final String BASE_NAME = ResourceBundleEditorTests.class.getName();
|
||||
|
||||
private static final String MESSAGE_KEY = "punk";
|
||||
|
||||
|
||||
@@ -40,7 +41,8 @@ public final class ResourceBundleEditorTests {
|
||||
editor.setAsText(BASE_NAME);
|
||||
Object value = editor.getValue();
|
||||
assertNotNull("Returned ResourceBundle was null (must not be for valid setAsText(..) call).", value);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).", value instanceof ResourceBundle);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).",
|
||||
value instanceof ResourceBundle);
|
||||
ResourceBundle bundle = (ResourceBundle) value;
|
||||
String string = bundle.getString(MESSAGE_KEY);
|
||||
assertEquals(MESSAGE_KEY, string);
|
||||
@@ -52,7 +54,8 @@ public final class ResourceBundleEditorTests {
|
||||
editor.setAsText(BASE_NAME + "_");
|
||||
Object value = editor.getValue();
|
||||
assertNotNull("Returned ResourceBundle was null (must not be for valid setAsText(..) call).", value);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).", value instanceof ResourceBundle);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).",
|
||||
value instanceof ResourceBundle);
|
||||
ResourceBundle bundle = (ResourceBundle) value;
|
||||
String string = bundle.getString(MESSAGE_KEY);
|
||||
assertEquals(MESSAGE_KEY, string);
|
||||
@@ -64,7 +67,8 @@ public final class ResourceBundleEditorTests {
|
||||
editor.setAsText(BASE_NAME + "Lang" + "_en");
|
||||
Object value = editor.getValue();
|
||||
assertNotNull("Returned ResourceBundle was null (must not be for valid setAsText(..) call).", value);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).", value instanceof ResourceBundle);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).",
|
||||
value instanceof ResourceBundle);
|
||||
ResourceBundle bundle = (ResourceBundle) value;
|
||||
String string = bundle.getString(MESSAGE_KEY);
|
||||
assertEquals("yob", string);
|
||||
@@ -76,7 +80,8 @@ public final class ResourceBundleEditorTests {
|
||||
editor.setAsText(BASE_NAME + "LangCountry" + "_en_GB");
|
||||
Object value = editor.getValue();
|
||||
assertNotNull("Returned ResourceBundle was null (must not be for valid setAsText(..) call).", value);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).", value instanceof ResourceBundle);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).",
|
||||
value instanceof ResourceBundle);
|
||||
ResourceBundle bundle = (ResourceBundle) value;
|
||||
String string = bundle.getString(MESSAGE_KEY);
|
||||
assertEquals("chav", string);
|
||||
@@ -88,31 +93,32 @@ public final class ResourceBundleEditorTests {
|
||||
editor.setAsText(BASE_NAME + "LangCountryDialect" + "_en_GB_GLASGOW");
|
||||
Object value = editor.getValue();
|
||||
assertNotNull("Returned ResourceBundle was null (must not be for valid setAsText(..) call).", value);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).", value instanceof ResourceBundle);
|
||||
assertTrue("Returned object was not a ResourceBundle (must be for valid setAsText(..) call).",
|
||||
value instanceof ResourceBundle);
|
||||
ResourceBundle bundle = (ResourceBundle) value;
|
||||
String string = bundle.getString(MESSAGE_KEY);
|
||||
assertEquals("ned", string);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testSetAsTextWithNull() throws Exception {
|
||||
ResourceBundleEditor editor = new ResourceBundleEditor();
|
||||
editor.setAsText(null);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testSetAsTextWithEmptyString() throws Exception {
|
||||
ResourceBundleEditor editor = new ResourceBundleEditor();
|
||||
editor.setAsText("");
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testSetAsTextWithWhiteSpaceString() throws Exception {
|
||||
ResourceBundleEditor editor = new ResourceBundleEditor();
|
||||
editor.setAsText(" ");
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testSetAsTextWithJustSeparatorString() throws Exception {
|
||||
ResourceBundleEditor editor = new ResourceBundleEditor();
|
||||
editor.setAsText("_");
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -134,7 +134,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
|
||||
|
||||
@Override
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS);
|
||||
return unit.convert(this.timer.getScheduledExecutionTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Vendored
+2
-2
@@ -195,7 +195,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
}
|
||||
|
||||
private <A extends Annotation> Collection<A> getAnnotations(AnnotatedElement ae, Class<A> annotationType) {
|
||||
Collection<A> anns = new ArrayList<A>(2);
|
||||
Collection<A> anns = new ArrayList<A>(1);
|
||||
|
||||
// look at raw annotation
|
||||
A ann = ae.getAnnotation(annotationType);
|
||||
@@ -211,7 +211,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
}
|
||||
}
|
||||
|
||||
return (anns.isEmpty() ? null : anns);
|
||||
return (!anns.isEmpty() ? anns : null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+6
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,17 +29,18 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||
class BeanAnnotationHelper {
|
||||
|
||||
/**
|
||||
* Return whether the given method is annotated directly or indirectly with @Bean.
|
||||
* Return whether the given method is directly or indirectly annotated with
|
||||
* the {@link Bean} annotation.
|
||||
*/
|
||||
public static boolean isBeanAnnotated(Method method) {
|
||||
return AnnotationUtils.findAnnotation(method, Bean.class) != null;
|
||||
return (AnnotationUtils.findAnnotation(method, Bean.class) != null);
|
||||
}
|
||||
|
||||
public static String determineBeanNameFor(Method beanMethod) {
|
||||
// by default the bean name is the name of the @Bean-annotated method
|
||||
// By default, the bean name is the name of the @Bean-annotated method
|
||||
String beanName = beanMethod.getName();
|
||||
|
||||
// check to see if the user has explicitly set the bean name
|
||||
// Check to see if the user has explicitly set a custom bean name...
|
||||
Bean bean = AnnotationUtils.findAnnotation(beanMethod, Bean.class);
|
||||
if (bean != null && bean.name().length > 0) {
|
||||
beanName = bean.name()[0];
|
||||
|
||||
+8
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -125,10 +125,13 @@ public @interface ComponentScan {
|
||||
|
||||
/**
|
||||
* Specifies which types are eligible for component scanning.
|
||||
* <p>Further narrows the set of candidate components from everything in
|
||||
* {@link #basePackages} to everything in the base packages that matches
|
||||
* the given filter or filters.
|
||||
* @see #resourcePattern
|
||||
* <p>Further narrows the set of candidate components from everything in {@link #basePackages}
|
||||
* to everything in the base packages that matches the given filter or filters.
|
||||
* <p>Note that these filters will be applied in addition to the default filters, if specified.
|
||||
* Any type under the specified base packages which matches a given filter will be included,
|
||||
* even if it does not match the default filters (i.e. is not annotated with {@code @Component}).
|
||||
* @see #resourcePattern()
|
||||
* @see #useDefaultFilters()
|
||||
*/
|
||||
Filter[] includeFilters() default {};
|
||||
|
||||
|
||||
+15
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -364,8 +364,20 @@ class ConfigurationClassEnhancer {
|
||||
if (alreadyInCreation) {
|
||||
beanFactory.setCurrentlyInCreation(beanName, false);
|
||||
}
|
||||
Object beanInstance = (!ObjectUtils.isEmpty(beanMethodArgs) ?
|
||||
beanFactory.getBean(beanName, beanMethodArgs) : beanFactory.getBean(beanName));
|
||||
boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
|
||||
if (useArgs && beanFactory.isSingleton(beanName)) {
|
||||
// Stubbed null arguments just for reference purposes,
|
||||
// expecting them to be autowired for regular singleton references?
|
||||
// A safe assumption since @Bean singleton arguments cannot be optional...
|
||||
for (Object arg : beanMethodArgs) {
|
||||
if (arg == null) {
|
||||
useArgs = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
|
||||
beanFactory.getBean(beanName));
|
||||
if (beanInstance != null && !ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
|
||||
String msg = String.format("@Bean method %s.%s called as a bean reference " +
|
||||
"for type [%s] but overridden by non-compatible bean instance of type [%s].",
|
||||
|
||||
+5
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,10 +18,12 @@ package org.springframework.context.annotation;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -30,7 +32,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -622,7 +623,7 @@ class ConfigurationClassParser {
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class ImportStack extends Stack<ConfigurationClass> implements ImportRegistry {
|
||||
private static class ImportStack extends ArrayDeque<ConfigurationClass> implements ImportRegistry {
|
||||
|
||||
private final MultiValueMap<String, AnnotationMetadata> imports = new LinkedMultiValueMap<String, AnnotationMetadata>();
|
||||
|
||||
@@ -647,23 +648,6 @@ class ConfigurationClassParser {
|
||||
return (!CollectionUtils.isEmpty(list) ? list.get(list.size() - 1) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified contains() implementation that tests to see if any {@link ConfigurationClass}
|
||||
* exists within this stack that has the same name as <var>elem</var>. Elem must be of
|
||||
* type ConfigurationClass.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(Object elem) {
|
||||
ConfigurationClass configClass = (ConfigurationClass) elem;
|
||||
Comparator<ConfigurationClass> comparator = new Comparator<ConfigurationClass>() {
|
||||
@Override
|
||||
public int compare(ConfigurationClass first, ConfigurationClass second) {
|
||||
return (first.getMetadata().getClassName().equals(second.getMetadata().getClassName()) ? 0 : 1);
|
||||
}
|
||||
};
|
||||
return (Collections.binarySearch(this, configClass, comparator) != -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a stack containing (in order)
|
||||
* <ul>
|
||||
@@ -883,7 +867,7 @@ class ConfigurationClassParser {
|
||||
*/
|
||||
private static class CircularImportProblem extends Problem {
|
||||
|
||||
public CircularImportProblem(ConfigurationClass attemptedImport, Stack<ConfigurationClass> importStack) {
|
||||
public CircularImportProblem(ConfigurationClass attemptedImport, Deque<ConfigurationClass> importStack) {
|
||||
super(String.format("A circular @Import has been detected: " +
|
||||
"Illegal attempt by @Configuration class '%s' to import class '%s' as '%s' is " +
|
||||
"already present in the current import stack %s", importStack.peek().getSimpleName(),
|
||||
|
||||
+8
-2
@@ -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.
|
||||
@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
@@ -79,7 +80,12 @@ public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotat
|
||||
}
|
||||
@Override
|
||||
public Object getTarget() {
|
||||
return beanFactory.doResolveDependency(descriptor, beanName, null, null);
|
||||
Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null);
|
||||
if (target == null) {
|
||||
throw new NoSuchBeanDefinitionException(descriptor.getDependencyType(),
|
||||
"Optional dependency not present for lazy injection point");
|
||||
}
|
||||
return target;
|
||||
}
|
||||
@Override
|
||||
public void releaseTarget(Object target) {
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -106,7 +106,7 @@ public class DefaultMessageSourceResolvable implements MessageSourceResolvable,
|
||||
* the last one in the codes array.
|
||||
*/
|
||||
public String getCode() {
|
||||
return (this.codes != null && this.codes.length > 0) ? this.codes[this.codes.length - 1] : null;
|
||||
return (this.codes != null && this.codes.length > 0 ? this.codes[this.codes.length - 1] : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,7 +127,7 @@ public class DefaultMessageSourceResolvable implements MessageSourceResolvable,
|
||||
protected final String resolvableToString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("codes [").append(StringUtils.arrayToDelimitedString(this.codes, ","));
|
||||
result.append("]; arguments [" + StringUtils.arrayToDelimitedString(this.arguments, ","));
|
||||
result.append("]; arguments [").append(StringUtils.arrayToDelimitedString(this.arguments, ","));
|
||||
result.append("]; default message [").append(this.defaultMessage).append(']');
|
||||
return result.toString();
|
||||
}
|
||||
@@ -153,9 +153,9 @@ public class DefaultMessageSourceResolvable implements MessageSourceResolvable,
|
||||
return false;
|
||||
}
|
||||
MessageSourceResolvable otherResolvable = (MessageSourceResolvable) other;
|
||||
return ObjectUtils.nullSafeEquals(getCodes(), otherResolvable.getCodes()) &&
|
||||
return (ObjectUtils.nullSafeEquals(getCodes(), otherResolvable.getCodes()) &&
|
||||
ObjectUtils.nullSafeEquals(getArguments(), otherResolvable.getArguments()) &&
|
||||
ObjectUtils.nullSafeEquals(getDefaultMessage(), otherResolvable.getDefaultMessage());
|
||||
ObjectUtils.nullSafeEquals(getDefaultMessage(), otherResolvable.getDefaultMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -50,29 +50,20 @@ import org.springframework.util.StringUtils;
|
||||
* reloading files based on timestamp changes, but also of loading properties files
|
||||
* with a specific character encoding. It will detect XML property files as well.
|
||||
*
|
||||
* <p>In contrast to {@link ResourceBundleMessageSource}, this class supports
|
||||
* reloading of properties files through the {@link #setCacheSeconds "cacheSeconds"}
|
||||
* setting, and also through programmatically clearing the properties cache.
|
||||
* Since application servers typically cache all files loaded from the classpath,
|
||||
* it is necessary to store resources somewhere else (for example, in the
|
||||
* "WEB-INF" directory of a web app). Otherwise changes of files in the
|
||||
* classpath will <i>not</i> be reflected in the application.
|
||||
*
|
||||
* <p>Note that the base names set as {@link #setBasenames "basenames"} property
|
||||
* <p>Note that the basenames set as {@link #setBasenames "basenames"} property
|
||||
* are treated in a slightly different fashion than the "basenames" property of
|
||||
* {@link ResourceBundleMessageSource}. It follows the basic ResourceBundle rule of not
|
||||
* specifying file extension or language codes, but can refer to any Spring resource
|
||||
* location (instead of being restricted to classpath resources). With a "classpath:"
|
||||
* prefix, resources can still be loaded from the classpath, but "cacheSeconds" values
|
||||
* other than "-1" (caching forever) will not work in this case.
|
||||
*
|
||||
* <p>This MessageSource implementation is usually slightly faster than
|
||||
* {@link ResourceBundleMessageSource}, which builds on {@link java.util.ResourceBundle}
|
||||
* - in the default mode, i.e. when caching forever. With "cacheSeconds" set to 1,
|
||||
* message lookup takes about twice as long - with the benefit that changes in
|
||||
* individual properties files are detected with a maximum delay of 1 second.
|
||||
* Higher "cacheSeconds" values usually <i>do not</i> make a significant difference.
|
||||
* other than "-1" (caching forever) might not work reliably in this case.
|
||||
*
|
||||
* <p>For a typical web application, message files could be placed into {@code WEB-INF}:
|
||||
* e.g. a "WEB-INF/messages" basename would fine a "WEB-INF/messages.properties",
|
||||
* "WEB-INF/messages_en.properties" etc arrangement as well as "WEB-INF/messages.xml",
|
||||
* "WEB-INF/messages_en.xml" etc. Note that message definitions in a <i>previous</i>
|
||||
* resource bundle will override ones in a later bundle, due to sequential lookup.
|
||||
|
||||
* <p>This MessageSource can easily be used outside of an
|
||||
* {@link org.springframework.context.ApplicationContext}: It will use a
|
||||
* {@link org.springframework.core.io.DefaultResourceLoader} as default,
|
||||
@@ -244,6 +235,7 @@ public class ReloadableResourceBundleMessageSource extends AbstractMessageSource
|
||||
* <p>Default is "true": This behavior is new as of Spring Framework 4.1,
|
||||
* minimizing contention between threads. If you prefer the old behavior,
|
||||
* i.e. to fully block on refresh, switch this flag to "false".
|
||||
* @since 4.1
|
||||
* @see #setCacheSeconds
|
||||
*/
|
||||
public void setConcurrentRefresh(boolean concurrentRefresh) {
|
||||
|
||||
+7
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -51,11 +51,11 @@ import org.springframework.util.StringUtils;
|
||||
* base class. The caching provided by this MessageSource is significantly faster
|
||||
* than the built-in caching of the {@code java.util.ResourceBundle} class.
|
||||
*
|
||||
* <p>Unfortunately, {@code java.util.ResourceBundle} caches loaded bundles
|
||||
* forever: Reloading a bundle during VM execution is <i>not</i> possible.
|
||||
* As this MessageSource relies on ResourceBundle, it faces the same limitation.
|
||||
* Consider {@link ReloadableResourceBundleMessageSource} for an alternative
|
||||
* that is capable of refreshing the underlying bundle files.
|
||||
* <p>The basenames follow {@link java.util.ResourceBundle} conventions: essentially,
|
||||
* a fully-qualified classpath location. If it doesn't contain a package qualifier
|
||||
* (such as {@code org.mypackage}), it will be resolved from the classpath root.
|
||||
* Note that the JDK's standard ResourceBundle treats dots as package separators:
|
||||
* This means that "test.theme" is effectively equivalent to "test/theme".
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
@@ -404,8 +404,7 @@ public class ResourceBundleMessageSource extends AbstractMessageSource implement
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + ": basenames=[" +
|
||||
StringUtils.arrayToCommaDelimitedString(this.basenames) + "]";
|
||||
return getClass().getName() + ": basenames=[" + StringUtils.arrayToCommaDelimitedString(this.basenames) + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
-1
@@ -17,7 +17,6 @@
|
||||
package org.springframework.format.datetime.standard;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.time.Period;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -112,9 +112,9 @@ public class FieldError extends ObjectError {
|
||||
return false;
|
||||
}
|
||||
FieldError otherError = (FieldError) other;
|
||||
return getField().equals(otherError.getField()) &&
|
||||
return (getField().equals(otherError.getField()) &&
|
||||
ObjectUtils.nullSafeEquals(getRejectedValue(), otherError.getRejectedValue()) &&
|
||||
isBindingFailure() == otherError.isBindingFailure();
|
||||
isBindingFailure() == otherError.isBindingFailure());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -78,7 +78,7 @@ public class ObjectError extends DefaultMessageSourceResolvable {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (getClass() != other.getClass() || !super.equals(other)) {
|
||||
if (other == null || other.getClass() != getClass() || !super.equals(other)) {
|
||||
return false;
|
||||
}
|
||||
ObjectError otherError = (ObjectError) other;
|
||||
|
||||
+3
@@ -235,6 +235,9 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Controls which eligible types to include for component scanning.
|
||||
Note that these filters will be applied in addition to the default filters, if specified.
|
||||
Any type under the specified base packages which matches a given filter will be included,
|
||||
even if it does not match the default filters (i.e. is not annotated with @Component).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
+41
-37
@@ -31,10 +31,13 @@ import java.util.Map;
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import test.mixin.LockMixin;
|
||||
import test.mixin.LockMixinAdvisor;
|
||||
import test.mixin.Lockable;
|
||||
import test.mixin.LockedException;
|
||||
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.AfterReturningAdvice;
|
||||
@@ -72,11 +75,6 @@ import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.util.SerializationTestUtils;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import test.mixin.LockMixin;
|
||||
import test.mixin.LockMixinAdvisor;
|
||||
import test.mixin.Lockable;
|
||||
import test.mixin.LockedException;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
@@ -123,7 +121,7 @@ public abstract class AbstractAopProxyTests {
|
||||
|
||||
@Test(expected = AopConfigException.class)
|
||||
public void testNoInterceptorsAndNoTarget() {
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] { ITestBean.class });
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
// Add no interceptors
|
||||
AopProxy aop = createAopProxy(pc);
|
||||
aop.getProxy();
|
||||
@@ -408,7 +406,7 @@ public abstract class AbstractAopProxyTests {
|
||||
return s;
|
||||
}
|
||||
};
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
if (context) {
|
||||
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
}
|
||||
@@ -452,7 +450,7 @@ public abstract class AbstractAopProxyTests {
|
||||
throw expectedException;
|
||||
}
|
||||
};
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
pc.addAdvice(mi);
|
||||
|
||||
@@ -487,7 +485,7 @@ public abstract class AbstractAopProxyTests {
|
||||
throw unexpectedException;
|
||||
}
|
||||
};
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
pc.addAdvice(mi);
|
||||
|
||||
@@ -520,7 +518,7 @@ public abstract class AbstractAopProxyTests {
|
||||
throw unexpectedException;
|
||||
}
|
||||
};
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
pc.addAdvice(mi);
|
||||
|
||||
@@ -548,7 +546,7 @@ public abstract class AbstractAopProxyTests {
|
||||
@Test
|
||||
public void testTargetCanGetInvocationEvenIfNoAdviceChain() throws Throwable {
|
||||
NeedsToSeeProxy target = new NeedsToSeeProxy();
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {INeedsToSeeProxy.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(INeedsToSeeProxy.class);
|
||||
pc.setTarget(target);
|
||||
pc.setExposeProxy(true);
|
||||
|
||||
@@ -563,7 +561,7 @@ public abstract class AbstractAopProxyTests {
|
||||
public void testTargetCanGetInvocation() throws Throwable {
|
||||
final InvocationCheckExposedInvocationTestBean expectedTarget = new InvocationCheckExposedInvocationTestBean();
|
||||
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class, IOther.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class, IOther.class);
|
||||
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
TrapTargetInterceptor tii = new TrapTargetInterceptor() {
|
||||
@Override
|
||||
@@ -600,7 +598,8 @@ public abstract class AbstractAopProxyTests {
|
||||
@Test
|
||||
public void testMixinWithIntroductionAdvisor() throws Throwable {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pc = new ProxyFactory(new Class<?>[] {ITestBean.class});
|
||||
ProxyFactory pc = new ProxyFactory();
|
||||
pc.addInterface(ITestBean.class);
|
||||
pc.addAdvisor(new LockMixinAdvisor());
|
||||
pc.setTarget(tb);
|
||||
|
||||
@@ -610,7 +609,8 @@ public abstract class AbstractAopProxyTests {
|
||||
@Test
|
||||
public void testMixinWithIntroductionInfo() throws Throwable {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pc = new ProxyFactory(new Class<?>[] {ITestBean.class});
|
||||
ProxyFactory pc = new ProxyFactory();
|
||||
pc.addInterface(ITestBean.class);
|
||||
// We don't use an IntroductionAdvisor, we can just add an advice that implements IntroductionInfo
|
||||
pc.addAdvice(new LockMixin());
|
||||
pc.setTarget(tb);
|
||||
@@ -648,7 +648,8 @@ public abstract class AbstractAopProxyTests {
|
||||
@Test
|
||||
public void testReplaceArgument() throws Throwable {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pc = new ProxyFactory(new Class<?>[] {ITestBean.class});
|
||||
ProxyFactory pc = new ProxyFactory();
|
||||
pc.addInterface(ITestBean.class);
|
||||
pc.setTarget(tb);
|
||||
pc.addAdvisor(new StringSetterNullReplacementAdvice());
|
||||
|
||||
@@ -825,7 +826,7 @@ public abstract class AbstractAopProxyTests {
|
||||
fail("Shouldn't be able to add introduction advice that introduces a class, rather than an interface");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("interface") > -1);
|
||||
assertTrue(ex.getMessage().contains("interface"));
|
||||
}
|
||||
// Check it still works: proxy factory state shouldn't have been corrupted
|
||||
ITestBean proxied = (ITestBean) createProxy(pc);
|
||||
@@ -873,7 +874,7 @@ public abstract class AbstractAopProxyTests {
|
||||
fail("Shouldn't be able to add Advisor when frozen");
|
||||
}
|
||||
catch (AopConfigException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("frozen") > -1);
|
||||
assertTrue(ex.getMessage().contains("frozen"));
|
||||
}
|
||||
// Check it still works: proxy factory state shouldn't have been corrupted
|
||||
assertEquals(target.getAge(), proxied.getAge());
|
||||
@@ -897,7 +898,7 @@ public abstract class AbstractAopProxyTests {
|
||||
fail("Shouldn't be able to remove Advisor when frozen");
|
||||
}
|
||||
catch (AopConfigException ex) {
|
||||
assertTrue(ex.getMessage().indexOf("frozen") > -1);
|
||||
assertTrue(ex.getMessage().contains("frozen"));
|
||||
}
|
||||
// Didn't get removed
|
||||
assertEquals(1, advised.getAdvisors().length);
|
||||
@@ -938,7 +939,7 @@ public abstract class AbstractAopProxyTests {
|
||||
public void testProxyConfigString() {
|
||||
TestBean target = new TestBean();
|
||||
ProxyFactory pc = new ProxyFactory(target);
|
||||
pc.setInterfaces(new Class<?>[] {ITestBean.class});
|
||||
pc.setInterfaces(ITestBean.class);
|
||||
pc.addAdvice(new NopInterceptor());
|
||||
MethodBeforeAdvice mba = new CountingBeforeAdvice();
|
||||
Advisor advisor = new DefaultPointcutAdvisor(new NameMatchMethodPointcut(), mba);
|
||||
@@ -946,15 +947,15 @@ public abstract class AbstractAopProxyTests {
|
||||
ITestBean proxied = (ITestBean) createProxy(pc);
|
||||
|
||||
String proxyConfigString = ((Advised) proxied).toProxyConfigString();
|
||||
assertTrue(proxyConfigString.indexOf(advisor.toString()) != -1);
|
||||
assertTrue(proxyConfigString.indexOf("1 interface") != -1);
|
||||
assertTrue(proxyConfigString.contains(advisor.toString()));
|
||||
assertTrue(proxyConfigString.contains("1 interface"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanPreventCastToAdvisedUsingOpaque() {
|
||||
TestBean target = new TestBean();
|
||||
ProxyFactory pc = new ProxyFactory(target);
|
||||
pc.setInterfaces(new Class<?>[] {ITestBean.class});
|
||||
pc.setInterfaces(ITestBean.class);
|
||||
pc.addAdvice(new NopInterceptor());
|
||||
CountingBeforeAdvice mba = new CountingBeforeAdvice();
|
||||
Advisor advisor = new DefaultPointcutAdvisor(new NameMatchMethodPointcut().addMethodName("setAge"), mba);
|
||||
@@ -1055,7 +1056,8 @@ public abstract class AbstractAopProxyTests {
|
||||
@Test
|
||||
public void testDynamicMethodPointcutThatAlwaysAppliesStatically() throws Throwable {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pc = new ProxyFactory(new Class<?>[] {ITestBean.class});
|
||||
ProxyFactory pc = new ProxyFactory();
|
||||
pc.addInterface(ITestBean.class);
|
||||
TestDynamicPointcutAdvice dp = new TestDynamicPointcutAdvice(new NopInterceptor(), "getAge");
|
||||
pc.addAdvisor(dp);
|
||||
pc.setTarget(tb);
|
||||
@@ -1071,7 +1073,8 @@ public abstract class AbstractAopProxyTests {
|
||||
@Test
|
||||
public void testDynamicMethodPointcutThatAppliesStaticallyOnlyToSetters() throws Throwable {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pc = new ProxyFactory(new Class<?>[] {ITestBean.class});
|
||||
ProxyFactory pc = new ProxyFactory();
|
||||
pc.addInterface(ITestBean.class);
|
||||
// Could apply dynamically to getAge/setAge but not to getName
|
||||
TestDynamicPointcutForSettersOnly dp = new TestDynamicPointcutForSettersOnly(new NopInterceptor(), "Age");
|
||||
pc.addAdvisor(dp);
|
||||
@@ -1093,7 +1096,8 @@ public abstract class AbstractAopProxyTests {
|
||||
@Test
|
||||
public void testStaticMethodPointcut() throws Throwable {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pc = new ProxyFactory(new Class<?>[] {ITestBean.class});
|
||||
ProxyFactory pc = new ProxyFactory();
|
||||
pc.addInterface(ITestBean.class);
|
||||
NopInterceptor di = new NopInterceptor();
|
||||
TestStaticPointcutAdvice sp = new TestStaticPointcutAdvice(di, "getAge");
|
||||
pc.addAdvisor(sp);
|
||||
@@ -1207,6 +1211,7 @@ public abstract class AbstractAopProxyTests {
|
||||
public void testOverloadedMethodsWithDifferentAdvice() throws Throwable {
|
||||
Overloads target = new Overloads();
|
||||
ProxyFactory pc = new ProxyFactory(target);
|
||||
|
||||
NopInterceptor overLoadVoids = new NopInterceptor();
|
||||
pc.addAdvisor(new StaticMethodMatcherPointcutAdvisor(overLoadVoids) {
|
||||
@Override
|
||||
@@ -1214,12 +1219,13 @@ public abstract class AbstractAopProxyTests {
|
||||
return m.getName().equals("overload") && m.getParameterTypes().length == 0;
|
||||
}
|
||||
});
|
||||
|
||||
NopInterceptor overLoadInts = new NopInterceptor();
|
||||
pc.addAdvisor(new StaticMethodMatcherPointcutAdvisor(overLoadInts) {
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass) {
|
||||
return m.getName().equals("overload") && m.getParameterTypes().length == 1 &&
|
||||
m.getParameterTypes()[0].equals(int.class);
|
||||
m.getParameterTypes()[0].equals(int.class);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1245,24 +1251,22 @@ public abstract class AbstractAopProxyTests {
|
||||
pf.setExposeProxy(true);
|
||||
final ITestBean proxy = (ITestBean) createProxy(pf);
|
||||
Advised config = (Advised) proxy;
|
||||
|
||||
// This class just checks proxy is bound before getTarget() call
|
||||
config.setTargetSource(new TargetSource() {
|
||||
@Override
|
||||
public Class<?> getTargetClass() {
|
||||
return TestBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTarget() throws Exception {
|
||||
assertEquals(proxy, AopContext.currentProxy());
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseTarget(Object target) throws Exception {
|
||||
}
|
||||
@@ -1351,7 +1355,7 @@ public abstract class AbstractAopProxyTests {
|
||||
return invocation.proceed();
|
||||
}
|
||||
};
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
MapAwareMethodInterceptor mami1 = new MapAwareMethodInterceptor(new HashMap<String, String>(), new HashMap<String, String>());
|
||||
Map<String, String> firstValuesToAdd = new HashMap<String, String>();
|
||||
firstValuesToAdd.put("test", "");
|
||||
@@ -1683,7 +1687,7 @@ public abstract class AbstractAopProxyTests {
|
||||
super(cleaner);
|
||||
setPointcut(new DynamicMethodMatcherPointcut() {
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method m, Class<?> targetClass, Object... args) {
|
||||
return args[0] == null;
|
||||
}
|
||||
@Override
|
||||
@@ -1706,8 +1710,8 @@ public abstract class AbstractAopProxyTests {
|
||||
super(mi);
|
||||
setPointcut(new DynamicMethodMatcherPointcut() {
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass, Object[] args) {
|
||||
boolean run = m.getName().indexOf(pattern) != -1;
|
||||
public boolean matches(Method m, Class<?> targetClass, Object... args) {
|
||||
boolean run = m.getName().contains(pattern);
|
||||
if (run) ++count;
|
||||
return run;
|
||||
}
|
||||
@@ -1725,8 +1729,8 @@ public abstract class AbstractAopProxyTests {
|
||||
super(mi);
|
||||
setPointcut(new DynamicMethodMatcherPointcut() {
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass, Object[] args) {
|
||||
boolean run = m.getName().indexOf(pattern) != -1;
|
||||
public boolean matches(Method m, Class<?> targetClass, Object... args) {
|
||||
boolean run = m.getName().contains(pattern);
|
||||
if (run) ++count;
|
||||
return run;
|
||||
}
|
||||
@@ -1750,7 +1754,7 @@ public abstract class AbstractAopProxyTests {
|
||||
}
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass) {
|
||||
return m.getName().indexOf(pattern) != -1;
|
||||
return m.getName().contains(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -81,7 +81,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
|
||||
@Test(expected = AopConfigException.class)
|
||||
public void testNoTarget() {
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] { ITestBean.class });
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
pc.addAdvice(new NopInterceptor());
|
||||
AopProxy aop = createAopProxy(pc);
|
||||
aop.getProxy();
|
||||
@@ -93,7 +93,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
bean.value = "foo";
|
||||
mockTargetSource.setTarget(bean);
|
||||
|
||||
AdvisedSupport as = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport as = new AdvisedSupport();
|
||||
as.setTargetSource(mockTargetSource);
|
||||
as.addAdvice(new NopInterceptor());
|
||||
AopProxy aop = new CglibAopProxy(as);
|
||||
@@ -110,7 +110,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
bean.value = "foo";
|
||||
mockTargetSource.setTarget(bean);
|
||||
|
||||
AdvisedSupport as = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport as = new AdvisedSupport();
|
||||
as.setTargetSource(mockTargetSource);
|
||||
as.addAdvice(new NopInterceptor());
|
||||
AopProxy aop = new CglibAopProxy(as);
|
||||
@@ -130,7 +130,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
bean.value = "foo";
|
||||
mockTargetSource.setTarget(bean);
|
||||
|
||||
AdvisedSupport as = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport as = new AdvisedSupport();
|
||||
as.setTargetSource(mockTargetSource);
|
||||
as.addAdvice(new NopInterceptor());
|
||||
AopProxy aop = new CglibAopProxy(as);
|
||||
@@ -164,7 +164,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
CglibTestBean bean = new CglibTestBean();
|
||||
bean.setName("Rob Harrop");
|
||||
|
||||
AdvisedSupport as = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport as = new AdvisedSupport();
|
||||
as.setTarget(bean);
|
||||
as.addAdvice(new NopInterceptor());
|
||||
AopProxy aop = new CglibAopProxy(as);
|
||||
@@ -178,7 +178,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
CglibTestBean target = new CglibTestBean();
|
||||
target.setName("Rob Harrop");
|
||||
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport pc = new AdvisedSupport();
|
||||
pc.setFrozen(true);
|
||||
pc.setTarget(target);
|
||||
|
||||
@@ -264,7 +264,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
target.reset();
|
||||
|
||||
mockTargetSource.setTarget(target);
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport pc = new AdvisedSupport();
|
||||
pc.setTargetSource(mockTargetSource);
|
||||
CglibAopProxy aop = new CglibAopProxy(pc);
|
||||
aop.setConstructorArguments(new Object[] {"Rob Harrop", 22}, new Class<?>[] {String.class, int.class});
|
||||
@@ -280,7 +280,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
ITestBean target = new TestBean();
|
||||
|
||||
mockTargetSource.setTarget(target);
|
||||
AdvisedSupport as = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport as = new AdvisedSupport();
|
||||
as.setTargetSource(mockTargetSource);
|
||||
as.addAdvice(new NopInterceptor());
|
||||
CglibAopProxy cglib = new CglibAopProxy(as);
|
||||
@@ -301,7 +301,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
ITestBean target = new TestBean();
|
||||
mockTargetSource.setTarget(target);
|
||||
|
||||
AdvisedSupport as = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport as = new AdvisedSupport();
|
||||
as.setTargetSource(mockTargetSource);
|
||||
as.addAdvice(new NopInterceptor());
|
||||
as.addInterface(Serializable.class);
|
||||
@@ -324,7 +324,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
|
||||
ExceptionThrower bean = new ExceptionThrower();
|
||||
mockTargetSource.setTarget(bean);
|
||||
|
||||
AdvisedSupport as = new AdvisedSupport(new Class<?>[]{});
|
||||
AdvisedSupport as = new AdvisedSupport();
|
||||
as.setTargetSource(mockTargetSource);
|
||||
as.addAdvice(new NopInterceptor());
|
||||
AopProxy aop = new CglibAopProxy(as);
|
||||
|
||||
+4
-4
@@ -63,7 +63,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
public void testProxyIsJustInterface() throws Throwable {
|
||||
TestBean raw = new TestBean();
|
||||
raw.setAge(32);
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
pc.setTarget(raw);
|
||||
JdkDynamicAopProxy aop = new JdkDynamicAopProxy(pc);
|
||||
|
||||
@@ -78,7 +78,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
final int age = 25;
|
||||
MethodInterceptor mi = (invocation -> age);
|
||||
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
|
||||
pc.addAdvice(mi);
|
||||
AopProxy aop = createAopProxy(pc);
|
||||
|
||||
@@ -97,7 +97,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
}
|
||||
};
|
||||
|
||||
AdvisedSupport pc = new AdvisedSupport(new Class<?>[] {ITestBean.class, IOther.class});
|
||||
AdvisedSupport pc = new AdvisedSupport(ITestBean.class, IOther.class);
|
||||
pc.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
TrapTargetInterceptor tii = new TrapTargetInterceptor() {
|
||||
@Override
|
||||
@@ -129,7 +129,7 @@ public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Seria
|
||||
|
||||
@Test
|
||||
public void testEqualsAndHashCodeDefined() throws Exception {
|
||||
AdvisedSupport as = new AdvisedSupport(new Class<?>[]{Named.class});
|
||||
AdvisedSupport as = new AdvisedSupport(Named.class);
|
||||
as.setTarget(new Person());
|
||||
JdkDynamicAopProxy aopProxy = new JdkDynamicAopProxy(as);
|
||||
Named proxy = (Named) aopProxy.getProxy();
|
||||
|
||||
+17
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -88,6 +88,7 @@ public final class ProxyFactoryBeanTests {
|
||||
|
||||
private BeanFactory factory;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
|
||||
@@ -97,6 +98,7 @@ public final class ProxyFactoryBeanTests {
|
||||
new ClassPathResource(CONTEXT, getClass()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIsDynamicProxyWhenInterfaceSpecified() {
|
||||
ITestBean test1 = (ITestBean) factory.getBean("test1");
|
||||
@@ -157,7 +159,7 @@ public final class ProxyFactoryBeanTests {
|
||||
catch (BeanCreationException ex) {
|
||||
// Root cause of the problem must be an AOP exception
|
||||
AopConfigException aex = (AopConfigException) ex.getCause();
|
||||
assertTrue(aex.getMessage().indexOf("interceptorNames") != -1);
|
||||
assertTrue(aex.getMessage().contains("interceptorNames"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,13 +334,6 @@ public final class ProxyFactoryBeanTests {
|
||||
}
|
||||
}
|
||||
|
||||
public static class DependsOnITestBean {
|
||||
public final ITestBean tb;
|
||||
public DependsOnITestBean(ITestBean tb) {
|
||||
this.tb = tb;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that inner bean for target means that we can use
|
||||
* autowire without ambiguity from target and proxy
|
||||
@@ -711,6 +706,8 @@ public final class ProxyFactoryBeanTests {
|
||||
ITestBean proxy = (ITestBean) fb.getObject();
|
||||
assertTrue(AopUtils.isJdkDynamicProxy(proxy));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fires only on void methods. Saves list of methods intercepted.
|
||||
*/
|
||||
@@ -733,7 +730,7 @@ public final class ProxyFactoryBeanTests {
|
||||
});
|
||||
setPointcut(new DynamicMethodMatcherPointcut() {
|
||||
@Override
|
||||
public boolean matches(Method m, Class<?> targetClass, Object[] args) {
|
||||
public boolean matches(Method m, Class<?> targetClass, Object... args) {
|
||||
return m.getReturnType() == Void.TYPE;
|
||||
}
|
||||
});
|
||||
@@ -741,10 +738,20 @@ public final class ProxyFactoryBeanTests {
|
||||
}
|
||||
|
||||
|
||||
public static class DependsOnITestBean {
|
||||
|
||||
public final ITestBean tb;
|
||||
|
||||
public DependsOnITestBean(ITestBean tb) {
|
||||
this.tb = tb;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aspect interface
|
||||
*/
|
||||
public interface AddedGlobalInterface {
|
||||
|
||||
int globalsAdded();
|
||||
}
|
||||
|
||||
|
||||
+39
-30
@@ -147,7 +147,7 @@ public class ComponentScanAnnotationIntegrationTests {
|
||||
@Test
|
||||
public void withCustomBeanNameGenerator() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ComponentScanWithBeanNameGenenerator.class);
|
||||
ctx.register(ComponentScanWithBeanNameGenerator.class);
|
||||
ctx.refresh();
|
||||
assertThat(ctx.containsBean("custom_fooServiceImpl"), is(true));
|
||||
assertThat(ctx.containsBean("fooServiceImpl"), is(false));
|
||||
@@ -241,7 +241,8 @@ public class ComponentScanAnnotationIntegrationTests {
|
||||
@ComponentScan
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public static @interface ComposedConfiguration {
|
||||
public @interface ComposedConfiguration {
|
||||
|
||||
String[] basePackages() default {};
|
||||
}
|
||||
|
||||
@@ -253,8 +254,9 @@ public class ComponentScanAnnotationIntegrationTests {
|
||||
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses=example.scannable._package.class)
|
||||
@ComponentScan(basePackageClasses = example.scannable._package.class)
|
||||
class ComponentScanAnnotatedConfig {
|
||||
|
||||
@Bean
|
||||
public TestBean testBean() {
|
||||
return new TestBean();
|
||||
@@ -264,6 +266,7 @@ class ComponentScanAnnotatedConfig {
|
||||
@Configuration
|
||||
@ComponentScan("example.scannable")
|
||||
class ComponentScanAnnotatedConfig_WithValueAttribute {
|
||||
|
||||
@Bean
|
||||
public TestBean testBean() {
|
||||
return new TestBean();
|
||||
@@ -272,13 +275,16 @@ class ComponentScanAnnotatedConfig_WithValueAttribute {
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
class ComponentScanWithNoPackagesConfig {}
|
||||
class ComponentScanWithNoPackagesConfig {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable", nameGenerator=MyBeanNameGenerator.class)
|
||||
class ComponentScanWithBeanNameGenenerator {}
|
||||
@ComponentScan(basePackages = "example.scannable", nameGenerator = MyBeanNameGenerator.class)
|
||||
class ComponentScanWithBeanNameGenerator {
|
||||
}
|
||||
|
||||
class MyBeanNameGenerator extends AnnotationBeanNameGenerator {
|
||||
|
||||
@Override
|
||||
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
|
||||
return "custom_" + super.generateBeanName(definition, registry);
|
||||
@@ -286,10 +292,12 @@ class MyBeanNameGenerator extends AnnotationBeanNameGenerator {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable_scoped", scopeResolver=MyScopeMetadataResolver.class)
|
||||
class ComponentScanWithScopeResolver {}
|
||||
@ComponentScan(basePackages = "example.scannable_scoped", scopeResolver = MyScopeMetadataResolver.class)
|
||||
class ComponentScanWithScopeResolver {
|
||||
}
|
||||
|
||||
class MyScopeMetadataResolver extends AnnotationScopeMetadataResolver {
|
||||
|
||||
MyScopeMetadataResolver() {
|
||||
this.scopeAnnotationType = MyScope.class;
|
||||
}
|
||||
@@ -297,13 +305,14 @@ class MyScopeMetadataResolver extends AnnotationScopeMetadataResolver {
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(
|
||||
basePackages="org.springframework.context.annotation",
|
||||
useDefaultFilters=false,
|
||||
basePackages = "org.springframework.context.annotation",
|
||||
useDefaultFilters = false,
|
||||
includeFilters = @Filter(type = FilterType.CUSTOM, classes = ComponentScanParserTests.CustomTypeFilter.class),
|
||||
// exclude this class from scanning since it's in the scanned package
|
||||
excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ComponentScanWithCustomTypeFilter.class),
|
||||
lazyInit = true)
|
||||
class ComponentScanWithCustomTypeFilter {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings({ "rawtypes", "serial", "unchecked" })
|
||||
public static CustomAutowireConfigurer customAutowireConfigurer() {
|
||||
@@ -318,30 +327,30 @@ class ComponentScanWithCustomTypeFilter {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
scopedProxy=ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters=false,
|
||||
@ComponentScan(basePackages = "example.scannable",
|
||||
scopedProxy = ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters = false,
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ScopedProxyTestBean.class))
|
||||
class ComponentScanWithScopedProxy {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
scopedProxy=ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters=false,
|
||||
includeFilters=@Filter(type=FilterType.REGEX, pattern ="((?:[a-z.]+))ScopedProxyTestBean"))
|
||||
@ComponentScan(basePackages = "example.scannable",
|
||||
scopedProxy = ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters = false,
|
||||
includeFilters = @Filter(type=FilterType.REGEX, pattern = "((?:[a-z.]+))ScopedProxyTestBean"))
|
||||
class ComponentScanWithScopedProxyThroughRegex {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
scopedProxy=ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters=false,
|
||||
includeFilters=@Filter(type=FilterType.ASPECTJ, pattern ="*..ScopedProxyTestBean"))
|
||||
@ComponentScan(basePackages = "example.scannable",
|
||||
scopedProxy = ScopedProxyMode.INTERFACES,
|
||||
useDefaultFilters = false,
|
||||
includeFilters = @Filter(type=FilterType.ASPECTJ, pattern = "*..ScopedProxyTestBean"))
|
||||
class ComponentScanWithScopedProxyThroughAspectJPattern {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
useDefaultFilters=false,
|
||||
includeFilters={
|
||||
@ComponentScan(basePackages = "example.scannable",
|
||||
useDefaultFilters = false,
|
||||
includeFilters = {
|
||||
@Filter(CustomStereotype.class),
|
||||
@Filter(CustomComponent.class)
|
||||
}
|
||||
@@ -349,15 +358,15 @@ class ComponentScanWithScopedProxyThroughAspectJPattern {}
|
||||
class ComponentScanWithMultipleAnnotationIncludeFilters1 {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages="example.scannable",
|
||||
useDefaultFilters=false,
|
||||
includeFilters=@Filter({CustomStereotype.class, CustomComponent.class})
|
||||
@ComponentScan(basePackages = "example.scannable",
|
||||
useDefaultFilters = false,
|
||||
includeFilters = @Filter({CustomStereotype.class, CustomComponent.class})
|
||||
)
|
||||
class ComponentScanWithMultipleAnnotationIncludeFilters2 {}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(
|
||||
value="example.scannable",
|
||||
basePackages="example.scannable",
|
||||
basePackageClasses=example.scannable._package.class)
|
||||
value = "example.scannable",
|
||||
basePackages = "example.scannable",
|
||||
basePackageClasses = example.scannable._package.class)
|
||||
class ComponentScanWithBasePackagesAndValueAlias {}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ public class ComponentScanAnnotationTests {
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(
|
||||
basePackageClasses={TestBean.class},
|
||||
basePackageClasses = TestBean.class,
|
||||
nameGenerator = DefaultBeanNameGenerator.class,
|
||||
scopedProxy = ScopedProxyMode.NO,
|
||||
scopeResolver = AnnotationScopeMetadataResolver.class,
|
||||
@@ -61,6 +61,6 @@ public class ComponentScanAnnotationTests {
|
||||
class MyConfig {
|
||||
}
|
||||
|
||||
@ComponentScan(basePackageClasses=example.scannable.NamedComponent.class)
|
||||
@ComponentScan(basePackageClasses = example.scannable.NamedComponent.class)
|
||||
class SimpleConfig {
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -122,7 +122,7 @@ public class ComponentScanParserBeanDefinitionDefaultsTests {
|
||||
context.refresh();
|
||||
fail("expected exception due to multiple matches for byType autowiring");
|
||||
}
|
||||
catch (UnsatisfiedDependencyException e) {
|
||||
catch (UnsatisfiedDependencyException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public class ComponentScanParserBeanDefinitionDefaultsTests {
|
||||
context.refresh();
|
||||
fail("expected exception due to dependency check");
|
||||
}
|
||||
catch (UnsatisfiedDependencyException e) {
|
||||
catch (UnsatisfiedDependencyException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,6 @@ public class ComponentScanParserBeanDefinitionDefaultsTests {
|
||||
|
||||
private boolean destroyed;
|
||||
|
||||
|
||||
public DefaultsTestBean() {
|
||||
INIT_COUNT++;
|
||||
}
|
||||
|
||||
+6
@@ -42,11 +42,13 @@ public class ComponentScanParserScopedProxyTests {
|
||||
@Rule
|
||||
public final ExpectedException exception = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void testDefaultScopedProxy() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/context/annotation/scopedProxyDefaultTests.xml");
|
||||
context.getBeanFactory().registerScope("myScope", new SimpleMapScope());
|
||||
|
||||
ScopedProxyTestBean bean = (ScopedProxyTestBean) context.getBean("scopedProxyTestBean");
|
||||
// should not be a proxy
|
||||
assertFalse(AopUtils.isAopProxy(bean));
|
||||
@@ -58,6 +60,7 @@ public class ComponentScanParserScopedProxyTests {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/context/annotation/scopedProxyNoTests.xml");
|
||||
context.getBeanFactory().registerScope("myScope", new SimpleMapScope());
|
||||
|
||||
ScopedProxyTestBean bean = (ScopedProxyTestBean) context.getBean("scopedProxyTestBean");
|
||||
// should not be a proxy
|
||||
assertFalse(AopUtils.isAopProxy(bean));
|
||||
@@ -69,6 +72,7 @@ public class ComponentScanParserScopedProxyTests {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/context/annotation/scopedProxyInterfacesTests.xml");
|
||||
context.getBeanFactory().registerScope("myScope", new SimpleMapScope());
|
||||
|
||||
// should cast to the interface
|
||||
FooService bean = (FooService) context.getBean("scopedProxyTestBean");
|
||||
// should be dynamic proxy
|
||||
@@ -86,6 +90,7 @@ public class ComponentScanParserScopedProxyTests {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"org/springframework/context/annotation/scopedProxyTargetClassTests.xml");
|
||||
context.getBeanFactory().registerScope("myScope", new SimpleMapScope());
|
||||
|
||||
ScopedProxyTestBean bean = (ScopedProxyTestBean) context.getBean("scopedProxyTestBean");
|
||||
// should be a class-based proxy
|
||||
assertTrue(AopUtils.isCglibProxy(bean));
|
||||
@@ -103,6 +108,7 @@ public class ComponentScanParserScopedProxyTests {
|
||||
exception.expect(BeanDefinitionParsingException.class);
|
||||
exception.expectMessage(containsString("Cannot define both 'scope-resolver' and 'scoped-proxy' on <component-scan> tag"));
|
||||
exception.expectMessage(containsString("Offending resource: class path resource [org/springframework/context/annotation/scopedProxyInvalidConfigTests.xml]"));
|
||||
|
||||
new ClassPathXmlApplicationContext("org/springframework/context/annotation/scopedProxyInvalidConfigTests.xml");
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -145,9 +145,9 @@ public class ComponentScanParserTests {
|
||||
}
|
||||
|
||||
|
||||
@Target({ ElementType.TYPE, ElementType.FIELD })
|
||||
@Target({ElementType.TYPE, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public static @interface CustomAnnotation {
|
||||
public @interface CustomAnnotation {
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,7 +53,7 @@ public class ComponentScanParserWithUserDefinedStrategiesTests {
|
||||
"org/springframework/context/annotation/invalidConstructorNameGeneratorTests.xml");
|
||||
fail("should have failed: no-arg constructor is required");
|
||||
}
|
||||
catch (BeansException e) {
|
||||
catch (BeansException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
@@ -65,9 +65,9 @@ public class ComponentScanParserWithUserDefinedStrategiesTests {
|
||||
"org/springframework/context/annotation/invalidClassNameScopeResolverTests.xml");
|
||||
fail("should have failed: no such class");
|
||||
}
|
||||
catch (BeansException e) {
|
||||
catch (BeansException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+33
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -592,17 +592,23 @@ public class ConfigurationClassPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrototypeArgumentsThroughBeanMethodCall() {
|
||||
public void testPrototypeArgumentThroughBeanMethodCall() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithPrototype.class);
|
||||
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingletonArgumentsThroughBeanMethodCall() {
|
||||
public void testSingletonArgumentThroughBeanMethodCall() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithSingleton.class);
|
||||
ctx.getBean(FooFactory.class).createFoo(new BarArgument());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullArgumentThroughBeanMethodCall() {
|
||||
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanArgumentConfigWithNull.class);
|
||||
ctx.getBean("aFoo");
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -1137,7 +1143,7 @@ public class ConfigurationClassPostProcessorTests {
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
public DependingFoo foo(final BarArgument bar) {
|
||||
public DependingFoo foo(BarArgument bar) {
|
||||
return new DependingFoo(bar);
|
||||
}
|
||||
|
||||
@@ -1145,7 +1151,7 @@ public class ConfigurationClassPostProcessorTests {
|
||||
public FooFactory fooFactory() {
|
||||
return new FooFactory() {
|
||||
@Override
|
||||
public DependingFoo createFoo(final BarArgument bar) {
|
||||
public DependingFoo createFoo(BarArgument bar) {
|
||||
return foo(bar);
|
||||
}
|
||||
};
|
||||
@@ -1156,7 +1162,7 @@ public class ConfigurationClassPostProcessorTests {
|
||||
static class BeanArgumentConfigWithSingleton {
|
||||
|
||||
@Bean @Lazy
|
||||
public DependingFoo foo(final BarArgument bar) {
|
||||
public DependingFoo foo(BarArgument bar) {
|
||||
return new DependingFoo(bar);
|
||||
}
|
||||
|
||||
@@ -1164,19 +1170,39 @@ public class ConfigurationClassPostProcessorTests {
|
||||
public FooFactory fooFactory() {
|
||||
return new FooFactory() {
|
||||
@Override
|
||||
public DependingFoo createFoo(final BarArgument bar) {
|
||||
public DependingFoo createFoo(BarArgument bar) {
|
||||
return foo(bar);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class BeanArgumentConfigWithNull {
|
||||
|
||||
@Bean
|
||||
public DependingFoo aFoo() {
|
||||
return foo(null);
|
||||
}
|
||||
|
||||
@Bean @Lazy
|
||||
public DependingFoo foo(BarArgument bar) {
|
||||
return new DependingFoo(bar);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BarArgument bar() {
|
||||
return new BarArgument();
|
||||
}
|
||||
}
|
||||
|
||||
static class BarArgument {
|
||||
}
|
||||
|
||||
static class DependingFoo {
|
||||
|
||||
DependingFoo(BarArgument bar) {
|
||||
Assert.notNull(bar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+34
-1
@@ -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.
|
||||
@@ -118,6 +118,28 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLazyOptionalResourceInjectionWithNonExistingTarget() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(OptionalFieldResourceInjectionBean.class);
|
||||
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("annotatedBean", bd);
|
||||
|
||||
OptionalFieldResourceInjectionBean bean = (OptionalFieldResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertNotNull(bean.getTestBean());
|
||||
try {
|
||||
bean.getTestBean().getName();
|
||||
fail("Should have thrown NoSuchBeanDefinitionException");
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// expected;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface TestBeanHolder {
|
||||
|
||||
@@ -136,6 +158,17 @@ public class LazyAutowiredAnnotationBeanPostProcessorTests {
|
||||
}
|
||||
|
||||
|
||||
public static class OptionalFieldResourceInjectionBean implements TestBeanHolder {
|
||||
|
||||
@Autowired(required = false) @Lazy
|
||||
private TestBean testBean;
|
||||
|
||||
public TestBean getTestBean() {
|
||||
return this.testBean;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class FieldResourceInjectionBeanWithCompositeAnnotation implements TestBeanHolder {
|
||||
|
||||
@LazyInject
|
||||
|
||||
+5
-3
@@ -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.
|
||||
@@ -73,7 +73,8 @@ public class EnableMBeanExportConfigurationTests {
|
||||
ObjectName oname = ObjectNameManager.getInstance("bean:name=testBean4");
|
||||
assertNotNull(server.getObjectInstance(oname));
|
||||
assertEquals("TEST", server.getAttribute(oname, "Name"));
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
@@ -142,7 +143,8 @@ public class EnableMBeanExportConfigurationTests {
|
||||
assertNotNull(server.getObjectInstance(oname));
|
||||
String name = (String) server.getAttribute(oname, "Name");
|
||||
assertNull(name);
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -203,7 +203,7 @@ public class OrderComparator implements Comparator<Object> {
|
||||
* Strategy interface to provide an order source for a given object.
|
||||
* @since 4.1
|
||||
*/
|
||||
public static interface OrderSourceProvider {
|
||||
public interface OrderSourceProvider {
|
||||
|
||||
/**
|
||||
* Return an order source for the specified object, i.e. an object that
|
||||
|
||||
+23
-25
@@ -495,8 +495,8 @@ public abstract class AnnotationUtils {
|
||||
|
||||
// Do NOT store result in the findAnnotationCache since doing so could break
|
||||
// findAnnotation(Class, Class) and findAnnotation(Method, Class).
|
||||
return synthesizeAnnotation(
|
||||
findAnnotation(annotatedElement, annotationType, new HashSet<Annotation>()), annotatedElement);
|
||||
A ann = findAnnotation(annotatedElement, annotationType, new HashSet<Annotation>());
|
||||
return synthesizeAnnotation(ann, annotatedElement);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1360,8 +1360,7 @@ public abstract class AnnotationUtils {
|
||||
if (annotation == null) {
|
||||
return null;
|
||||
}
|
||||
if (annotation instanceof SynthesizedAnnotation || (Proxy.isProxyClass(annotation.getClass()) &&
|
||||
Proxy.getInvocationHandler(annotation) instanceof SynthesizedAnnotationInvocationHandler)) {
|
||||
if (annotation instanceof SynthesizedAnnotation) {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
@@ -1373,8 +1372,10 @@ public abstract class AnnotationUtils {
|
||||
DefaultAnnotationAttributeExtractor attributeExtractor =
|
||||
new DefaultAnnotationAttributeExtractor(annotation, annotatedElement);
|
||||
InvocationHandler handler = new SynthesizedAnnotationInvocationHandler(attributeExtractor);
|
||||
Class<?>[] exposedInterfaces = (canExposeSynthesizedMarker(annotationType) ?
|
||||
new Class<?>[] {annotationType, SynthesizedAnnotation.class} : new Class<?>[] {annotationType});
|
||||
|
||||
// Can always expose Spring's SynthesizedAnnotation marker since we explicitly check for a
|
||||
// synthesizable annotation before (which needs to declare @AliasFor from the same package)
|
||||
Class<?>[] exposedInterfaces = new Class<?>[] {annotationType, SynthesizedAnnotation.class};
|
||||
return (A) Proxy.newProxyInstance(annotation.getClass().getClassLoader(), exposedInterfaces, handler);
|
||||
}
|
||||
|
||||
@@ -1945,11 +1946,11 @@ public abstract class AnnotationUtils {
|
||||
|
||||
this.sourceAttribute = sourceAttribute;
|
||||
this.sourceAnnotationType = (Class<? extends Annotation>) declaringClass;
|
||||
this.sourceAttributeName = this.sourceAttribute.getName();
|
||||
this.sourceAttributeName = sourceAttribute.getName();
|
||||
|
||||
this.aliasedAnnotationType = (Annotation.class == aliasFor.annotation() ?
|
||||
this.sourceAnnotationType : aliasFor.annotation());
|
||||
this.aliasedAttributeName = getAliasedAttributeName(aliasFor, this.sourceAttribute);
|
||||
this.aliasedAttributeName = getAliasedAttributeName(aliasFor, sourceAttribute);
|
||||
try {
|
||||
this.aliasedAttribute = this.aliasedAnnotationType.getDeclaredMethod(this.aliasedAttributeName);
|
||||
}
|
||||
@@ -1977,16 +1978,14 @@ public abstract class AnnotationUtils {
|
||||
if (this.isAliasPair) {
|
||||
AliasFor mirrorAliasFor = this.aliasedAttribute.getAnnotation(AliasFor.class);
|
||||
if (mirrorAliasFor == null) {
|
||||
String msg = String.format(
|
||||
"Attribute [%s] in annotation [%s] must be declared as an @AliasFor [%s].",
|
||||
String msg = String.format("Attribute [%s] in annotation [%s] must be declared as an @AliasFor [%s].",
|
||||
this.aliasedAttributeName, this.sourceAnnotationType.getName(), this.sourceAttributeName);
|
||||
throw new AnnotationConfigurationException(msg);
|
||||
}
|
||||
|
||||
String mirrorAliasedAttributeName = getAliasedAttributeName(mirrorAliasFor, this.aliasedAttribute);
|
||||
if (!this.sourceAttributeName.equals(mirrorAliasedAttributeName)) {
|
||||
String msg = String.format(
|
||||
"Attribute [%s] in annotation [%s] must be declared as an @AliasFor [%s], not [%s].",
|
||||
String msg = String.format("Attribute [%s] in annotation [%s] must be declared as an @AliasFor [%s], not [%s].",
|
||||
this.aliasedAttributeName, this.sourceAnnotationType.getName(), this.sourceAttributeName,
|
||||
mirrorAliasedAttributeName);
|
||||
throw new AnnotationConfigurationException(msg);
|
||||
@@ -2124,13 +2123,6 @@ public abstract class AnnotationUtils {
|
||||
return AliasDescriptor.from(this.aliasedAttribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s: @%s(%s) is an alias for @%s(%s)", getClass().getSimpleName(),
|
||||
this.sourceAnnotationType.getSimpleName(), this.sourceAttributeName,
|
||||
this.aliasedAnnotationType.getSimpleName(), this.aliasedAttributeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the aliased attribute configured via the supplied
|
||||
* {@link AliasFor @AliasFor} annotation on the supplied {@code attribute}.
|
||||
@@ -2145,9 +2137,8 @@ public abstract class AnnotationUtils {
|
||||
* @return the name of the aliased attribute (never {@code null} or empty)
|
||||
* @throws AnnotationConfigurationException if invalid configuration of
|
||||
* {@code @AliasFor} is detected
|
||||
* @since 4.2
|
||||
*/
|
||||
private static String getAliasedAttributeName(AliasFor aliasFor, Method attribute) {
|
||||
private String getAliasedAttributeName(AliasFor aliasFor, Method attribute) {
|
||||
String attributeName = aliasFor.attribute();
|
||||
String value = aliasFor.value();
|
||||
boolean attributeDeclared = StringUtils.hasText(attributeName);
|
||||
@@ -2155,10 +2146,10 @@ public abstract class AnnotationUtils {
|
||||
|
||||
// Ensure user did not declare both 'value' and 'attribute' in @AliasFor
|
||||
if (attributeDeclared && valueDeclared) {
|
||||
throw new AnnotationConfigurationException(String.format(
|
||||
"In @AliasFor declared on attribute [%s] in annotation [%s], attribute 'attribute' and its " +
|
||||
"alias 'value' are present with values of [%s] and [%s], but only one is permitted.",
|
||||
attribute.getName(), attribute.getDeclaringClass().getName(), attributeName, value));
|
||||
String msg = String.format("In @AliasFor declared on attribute [%s] in annotation [%s], attribute 'attribute' " +
|
||||
"and its alias 'value' are present with values of [%s] and [%s], but only one is permitted.",
|
||||
attribute.getName(), attribute.getDeclaringClass().getName(), attributeName, value);
|
||||
throw new AnnotationConfigurationException(msg);
|
||||
}
|
||||
|
||||
attributeName = (attributeDeclared ? attributeName : value);
|
||||
@@ -2173,6 +2164,13 @@ public abstract class AnnotationUtils {
|
||||
|
||||
return attributeName.trim();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s: @%s(%s) is an alias for @%s(%s)", getClass().getSimpleName(),
|
||||
this.sourceAnnotationType.getSimpleName(), this.sourceAttributeName,
|
||||
this.aliasedAnnotationType.getSimpleName(), this.aliasedAttributeName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-6
@@ -60,6 +60,7 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
|
||||
this.attributeExtractor = attributeExtractor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if (isEqualsMethod(method)) {
|
||||
@@ -75,8 +76,8 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
|
||||
return annotationType();
|
||||
}
|
||||
if (!isAttributeMethod(method)) {
|
||||
String msg = String.format("Method [%s] is unsupported for synthesized annotation type [%s]", method,
|
||||
annotationType());
|
||||
String msg = String.format("Method [%s] is unsupported for synthesized annotation type [%s]",
|
||||
method, annotationType());
|
||||
throw new AnnotationConfigurationException(msg);
|
||||
}
|
||||
return getAttributeValue(method);
|
||||
@@ -92,9 +93,9 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
|
||||
if (value == null) {
|
||||
value = this.attributeExtractor.getAttributeValue(attributeMethod);
|
||||
if (value == null) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"%s returned null for attribute name [%s] from attribute source [%s]",
|
||||
this.attributeExtractor.getClass().getName(), attributeName, this.attributeExtractor.getSource()));
|
||||
String msg = String.format("%s returned null for attribute name [%s] from attribute source [%s]",
|
||||
this.attributeExtractor.getClass().getName(), attributeName, this.attributeExtractor.getSource());
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
|
||||
// Synthesize nested annotations before returning them.
|
||||
@@ -200,7 +201,6 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
|
||||
* in Spring's {@link ObjectUtils} because those hash code generation
|
||||
* algorithms do not comply with the requirements specified in
|
||||
* {@link Annotation#hashCode()}.
|
||||
*
|
||||
* @param array the array to compute the hash code for
|
||||
*/
|
||||
private int hashCodeForArray(Object array) {
|
||||
|
||||
+7
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,8 +23,9 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Calls {@link Enum#name()} to convert a source Enum to a String. This converter will
|
||||
* not match enums with interfaces that can be converterd.
|
||||
* Calls {@link Enum#name()} to convert a source Enum to a String.
|
||||
* This converter will not match enums with interfaces that can be converted.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Phillip Webb
|
||||
* @since 3.0
|
||||
@@ -33,14 +34,16 @@ final class EnumToStringConverter implements Converter<Enum<?>, String>, Conditi
|
||||
|
||||
private final ConversionService conversionService;
|
||||
|
||||
|
||||
public EnumToStringConverter(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
for (Class<?> interfaceType : ClassUtils.getAllInterfacesForClass(sourceType.getType())) {
|
||||
if (conversionService.canConvert(TypeDescriptor.valueOf(interfaceType), targetType)) {
|
||||
if (this.conversionService.canConvert(TypeDescriptor.valueOf(interfaceType), targetType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,8 +40,7 @@ import org.springframework.util.NumberUtils;
|
||||
* @see java.math.BigDecimal
|
||||
* @see NumberUtils
|
||||
*/
|
||||
final class NumberToNumberConverterFactory implements ConverterFactory<Number, Number>,
|
||||
ConditionalConverter {
|
||||
final class NumberToNumberConverterFactory implements ConverterFactory<Number, Number>, ConditionalConverter {
|
||||
|
||||
@Override
|
||||
public <T extends Number> Converter<Number, T> getConverter(Class<T> targetType) {
|
||||
@@ -53,6 +52,7 @@ final class NumberToNumberConverterFactory implements ConverterFactory<Number, N
|
||||
return !sourceType.equals(targetType);
|
||||
}
|
||||
|
||||
|
||||
private final static class NumberToNumber<T extends Number> implements Converter<Number, T> {
|
||||
|
||||
private final Class<T> targetType;
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter {
|
||||
}
|
||||
}
|
||||
else if (member instanceof Constructor) {
|
||||
Constructor<?> ctor = (Constructor) member;
|
||||
Constructor<?> ctor = (Constructor<?>) member;
|
||||
return ctor.newInstance(source);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,6 +45,7 @@ final class StringToNumberConverterFactory implements ConverterFactory<String, N
|
||||
return new StringToNumber<T>(targetType);
|
||||
}
|
||||
|
||||
|
||||
private static final class StringToNumber<T extends Number> implements Converter<String, T> {
|
||||
|
||||
private final Class<T> targetType;
|
||||
|
||||
Vendored
+3
-3
@@ -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.
|
||||
@@ -80,8 +80,8 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
|
||||
if (debugEnabled) {
|
||||
logger.debug(String.format("Searching for key '%s' in [%s]", key, propertySource.getName()));
|
||||
}
|
||||
Object value;
|
||||
if ((value = propertySource.getProperty(key)) != null) {
|
||||
Object value = propertySource.getProperty(key);
|
||||
if (value != null) {
|
||||
Class<?> valueType = value.getClass();
|
||||
if (resolveNestedPlaceholders && value instanceof String) {
|
||||
value = resolveNestedPlaceholders((String) value);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -123,8 +123,8 @@ public abstract class AbstractResource implements Resource {
|
||||
*/
|
||||
@Override
|
||||
public long contentLength() throws IOException {
|
||||
InputStream is = this.getInputStream();
|
||||
Assert.state(is != null, "resource input stream must not be null");
|
||||
InputStream is = getInputStream();
|
||||
Assert.state(is != null, "Resource InputStream must not be null");
|
||||
try {
|
||||
long size = 0;
|
||||
byte[] buf = new byte[255];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -52,7 +52,7 @@ public class EncodedResource implements InputStreamSource {
|
||||
/**
|
||||
* Create a new {@code EncodedResource} for the given {@code Resource},
|
||||
* not specifying an explicit encoding or {@code Charset}.
|
||||
* @param resource the {@code Resource} to hold; never {@code null}
|
||||
* @param resource the {@code Resource} to hold (never {@code null})
|
||||
*/
|
||||
public EncodedResource(Resource resource) {
|
||||
this(resource, null, null);
|
||||
@@ -61,7 +61,7 @@ public class EncodedResource implements InputStreamSource {
|
||||
/**
|
||||
* Create a new {@code EncodedResource} for the given {@code Resource},
|
||||
* using the specified {@code encoding}.
|
||||
* @param resource the {@code Resource} to hold; never {@code null}
|
||||
* @param resource the {@code Resource} to hold (never {@code null})
|
||||
* @param encoding the encoding to use for reading from the resource
|
||||
*/
|
||||
public EncodedResource(Resource resource, String encoding) {
|
||||
@@ -71,7 +71,7 @@ public class EncodedResource implements InputStreamSource {
|
||||
/**
|
||||
* Create a new {@code EncodedResource} for the given {@code Resource},
|
||||
* using the specified {@code Charset}.
|
||||
* @param resource the {@code Resource} to hold; never {@code null}
|
||||
* @param resource the {@code Resource} to hold (never {@code null})
|
||||
* @param charset the {@code Charset} to use for reading from the resource
|
||||
*/
|
||||
public EncodedResource(Resource resource, Charset charset) {
|
||||
|
||||
+10
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -156,9 +156,9 @@ import org.springframework.util.StringUtils;
|
||||
* classpath:com/mycompany/**/service-context.xml
|
||||
* </pre>
|
||||
* is used to try to resolve it, the resolver will work off the (first) URL
|
||||
* returned by {@code getResource("com/mycompany");}. If this base package
|
||||
* node exists in multiple classloader locations, the actual end resource may
|
||||
* not be underneath. Therefore, preferably, use "{@code classpath*:}" with the same
|
||||
* returned by {@code getResource("com/mycompany");}. If this base package node
|
||||
* exists in multiple classloader locations, the actual end resource may not be
|
||||
* underneath. Therefore, preferably, use "{@code classpath*:}" with the same
|
||||
* Ant-style pattern in such a case, which will search <i>all</i> class path
|
||||
* locations that contain the root package.
|
||||
*
|
||||
@@ -308,6 +308,9 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
path = path.substring(1);
|
||||
}
|
||||
Set<Resource> result = doFindAllClassPathResources(path);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Resolved classpath location [" + location + "] to resources " + result);
|
||||
}
|
||||
return result.toArray(new Resource[result.size()]);
|
||||
}
|
||||
|
||||
@@ -316,6 +319,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
* Called by {@link #findAllClassPathResources(String)}.
|
||||
* @param path the absolute path within the classpath (never a leading slash)
|
||||
* @return a mutable Set of matching Resource instances
|
||||
* @since 4.1.1
|
||||
*/
|
||||
protected Set<Resource> doFindAllClassPathResources(String path) throws IOException {
|
||||
Set<Resource> result = new LinkedHashSet<Resource>(16);
|
||||
@@ -350,6 +354,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
* given set of resources in the form of pointers to the root of the jar file content.
|
||||
* @param classLoader the ClassLoader to search (including its ancestors)
|
||||
* @param result the set of resources to add jar roots to
|
||||
* @since 4.1.1
|
||||
*/
|
||||
protected void addAllClassLoaderJarRoots(ClassLoader classLoader, Set<Resource> result) {
|
||||
if (classLoader instanceof URLClassLoader) {
|
||||
@@ -381,6 +386,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
}
|
||||
if (classLoader != null) {
|
||||
try {
|
||||
// Hierarchy traversal...
|
||||
addAllClassLoaderJarRoots(classLoader.getParent(), result);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -183,7 +183,7 @@ public abstract class PropertiesLoaderUtils {
|
||||
ResourceUtils.useCachesIfNecessary(con);
|
||||
InputStream is = con.getInputStream();
|
||||
try {
|
||||
if (resourceName != null && resourceName.endsWith(XML_FILE_EXTENSION)) {
|
||||
if (resourceName.endsWith(XML_FILE_EXTENSION)) {
|
||||
props.loadFromXML(is);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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. You may obtain a copy of
|
||||
@@ -373,8 +373,8 @@ public abstract class Assert {
|
||||
public static void isAssignable(Class<?> superType, Class<?> subType, String message) {
|
||||
notNull(superType, "Type to check against must not be null");
|
||||
if (subType == null || !superType.isAssignableFrom(subType)) {
|
||||
throw new IllegalArgumentException((StringUtils.hasLength(message) ? message + " " : "")
|
||||
+ subType + " is not assignable to " + superType);
|
||||
throw new IllegalArgumentException((StringUtils.hasLength(message) ? message + " " : "") +
|
||||
subType + " is not assignable to " + superType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -428,7 +428,7 @@ public abstract class ClassUtils {
|
||||
* @see java.beans.Introspector#decapitalize(String)
|
||||
*/
|
||||
public static String getShortNameAsProperty(Class<?> clazz) {
|
||||
String shortName = ClassUtils.getShortName(clazz);
|
||||
String shortName = getShortName(clazz);
|
||||
int dotIndex = shortName.lastIndexOf(PACKAGE_SEPARATOR);
|
||||
shortName = (dotIndex != -1 ? shortName.substring(dotIndex + 1) : shortName);
|
||||
return Introspector.decapitalize(shortName);
|
||||
@@ -498,7 +498,7 @@ public abstract class ClassUtils {
|
||||
StringBuilder result = new StringBuilder();
|
||||
while (clazz.isArray()) {
|
||||
clazz = clazz.getComponentType();
|
||||
result.append(ClassUtils.ARRAY_SUFFIX);
|
||||
result.append(ARRAY_SUFFIX);
|
||||
}
|
||||
result.insert(0, clazz.getName());
|
||||
return result.toString();
|
||||
@@ -1222,7 +1222,7 @@ public abstract class ClassUtils {
|
||||
* @see org.springframework.aop.support.AopUtils#isCglibProxy(Object)
|
||||
*/
|
||||
public static boolean isCglibProxy(Object object) {
|
||||
return ClassUtils.isCglibProxyClass(object.getClass());
|
||||
return isCglibProxyClass(object.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -361,7 +361,7 @@ public class FastByteArrayOutputStream extends OutputStream {
|
||||
@Override
|
||||
public int read() {
|
||||
if (this.currentBuffer == null) {
|
||||
// this stream doesn't have any data in it
|
||||
// This stream doesn't have any data in it...
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
@@ -412,8 +412,8 @@ public class FastByteArrayOutputStream extends OutputStream {
|
||||
}
|
||||
else {
|
||||
if (this.currentBuffer == null) {
|
||||
// this stream doesn't have any data in it
|
||||
return 0;
|
||||
// This stream doesn't have any data in it...
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
if (this.nextIndexInCurrentBuffer < this.currentBufferLength) {
|
||||
@@ -456,7 +456,7 @@ public class FastByteArrayOutputStream extends OutputStream {
|
||||
}
|
||||
int len = (int) n;
|
||||
if (this.currentBuffer == null) {
|
||||
// this stream doesn't have any data in it
|
||||
// This stream doesn't have any data in it...
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
@@ -506,7 +506,7 @@ public class FastByteArrayOutputStream extends OutputStream {
|
||||
*/
|
||||
public void updateMessageDigest(MessageDigest messageDigest, int len) {
|
||||
if (this.currentBuffer == null) {
|
||||
// this stream doesn't have any data in it
|
||||
// This stream doesn't have any data in it...
|
||||
return;
|
||||
}
|
||||
else if (len == 0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -103,6 +103,7 @@ public class ExponentialBackOff implements BackOff {
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The initial interval in milliseconds.
|
||||
*/
|
||||
@@ -183,12 +184,12 @@ public class ExponentialBackOff implements BackOff {
|
||||
|
||||
@Override
|
||||
public long nextBackOff() {
|
||||
if (currentElapsedTime >= maxElapsedTime) {
|
||||
if (this.currentElapsedTime >= maxElapsedTime) {
|
||||
return STOP;
|
||||
}
|
||||
|
||||
long nextInterval = computeNextInterval();
|
||||
currentElapsedTime += nextInterval;
|
||||
this.currentElapsedTime += nextInterval;
|
||||
return nextInterval;
|
||||
}
|
||||
|
||||
@@ -205,7 +206,7 @@ public class ExponentialBackOff implements BackOff {
|
||||
else {
|
||||
this.currentInterval = multiplyInterval(maxInterval);
|
||||
}
|
||||
return currentInterval;
|
||||
return this.currentInterval;
|
||||
}
|
||||
|
||||
private long multiplyInterval(long maxInterval) {
|
||||
@@ -217,9 +218,8 @@ public class ExponentialBackOff implements BackOff {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String i = (this.currentInterval < 0 ? "n/a" : this.currentInterval + "ms");
|
||||
final StringBuilder sb = new StringBuilder("ExponentialBackOff{");
|
||||
sb.append("currentInterval=").append(i);
|
||||
StringBuilder sb = new StringBuilder("ExponentialBackOff{");
|
||||
sb.append("currentInterval=").append(this.currentInterval < 0 ? "n/a" : this.currentInterval + "ms");
|
||||
sb.append(", multiplier=").append(getMultiplier());
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,6 +57,7 @@ public class FixedBackOff implements BackOff {
|
||||
this.maxAttempts = maxAttempts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the interval between two attempts in milliseconds.
|
||||
*/
|
||||
@@ -110,14 +111,13 @@ public class FixedBackOff implements BackOff {
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("FixedBackOff{");
|
||||
sb.append("interval=").append(FixedBackOff.this.interval);
|
||||
String attemptValue = (FixedBackOff.this.maxAttempts == Long.MAX_VALUE ? "unlimited"
|
||||
: String.valueOf(FixedBackOff.this.maxAttempts));
|
||||
String attemptValue = (FixedBackOff.this.maxAttempts == Long.MAX_VALUE ?
|
||||
"unlimited" : String.valueOf(FixedBackOff.this.maxAttempts));
|
||||
sb.append(", currentAttempts=").append(this.currentAttempts);
|
||||
sb.append(", maxAttempts=").append(attemptValue);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+76
-66
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,36 +16,38 @@
|
||||
|
||||
package org.springframework.util.xml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.namespace.NamespaceContext;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple {@code javax.xml.namespace.NamespaceContext} implementation. Follows the standard
|
||||
* {@code NamespaceContext} contract, and is loadable via a {@code java.util.Map} or
|
||||
* {@code java.util.Properties} object
|
||||
* Simple {@code javax.xml.namespace.NamespaceContext} implementation.
|
||||
* Follows the standard {@code NamespaceContext} contract, and is loadable
|
||||
* via a {@code java.util.Map} or {@code java.util.Properties} object
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SimpleNamespaceContext implements NamespaceContext {
|
||||
|
||||
private Map<String, String> prefixToNamespaceUri = new HashMap<String, String>();
|
||||
private final Map<String, String> prefixToNamespaceUri = new HashMap<String, String>();
|
||||
|
||||
private Map<String, List<String>> namespaceUriToPrefixes = new HashMap<String, List<String>>();
|
||||
private final Map<String, Set<String>> namespaceUriToPrefixes = new HashMap<String, Set<String>>();
|
||||
|
||||
private String defaultNamespaceUri = "";
|
||||
|
||||
|
||||
@Override
|
||||
public String getNamespaceURI(String prefix) {
|
||||
Assert.notNull(prefix, "prefix is null");
|
||||
Assert.notNull(prefix, "No prefix given");
|
||||
if (XMLConstants.XML_NS_PREFIX.equals(prefix)) {
|
||||
return XMLConstants.XML_NS_URI;
|
||||
}
|
||||
@@ -53,29 +55,46 @@ public class SimpleNamespaceContext implements NamespaceContext {
|
||||
return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
|
||||
}
|
||||
else if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) {
|
||||
return defaultNamespaceUri;
|
||||
return this.defaultNamespaceUri;
|
||||
}
|
||||
else if (prefixToNamespaceUri.containsKey(prefix)) {
|
||||
return prefixToNamespaceUri.get(prefix);
|
||||
else if (this.prefixToNamespaceUri.containsKey(prefix)) {
|
||||
return this.prefixToNamespaceUri.get(prefix);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix(String namespaceUri) {
|
||||
List<?> prefixes = getPrefixesInternal(namespaceUri);
|
||||
return prefixes.isEmpty() ? null : (String) prefixes.get(0);
|
||||
Set<String> prefixes = getPrefixesSet(namespaceUri);
|
||||
return (!prefixes.isEmpty() ? prefixes.iterator().next() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getPrefixes(String namespaceUri) {
|
||||
return getPrefixesInternal(namespaceUri).iterator();
|
||||
return getPrefixesSet(namespaceUri).iterator();
|
||||
}
|
||||
|
||||
private Set<String> getPrefixesSet(String namespaceUri) {
|
||||
Assert.notNull(namespaceUri, "No namespaceUri given");
|
||||
if (this.defaultNamespaceUri.equals(namespaceUri)) {
|
||||
return Collections.singleton(XMLConstants.DEFAULT_NS_PREFIX);
|
||||
}
|
||||
else if (XMLConstants.XML_NS_URI.equals(namespaceUri)) {
|
||||
return Collections.singleton(XMLConstants.XML_NS_PREFIX);
|
||||
}
|
||||
else if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceUri)) {
|
||||
return Collections.singleton(XMLConstants.XMLNS_ATTRIBUTE);
|
||||
}
|
||||
else {
|
||||
Set<String> prefixes = this.namespaceUriToPrefixes.get(namespaceUri);
|
||||
return (prefixes != null ? Collections.unmodifiableSet(prefixes) : Collections.<String>emptySet());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the bindings for this namespace context. The supplied map must consist of string key value pairs.
|
||||
*
|
||||
* @param bindings the bindings
|
||||
* Set the bindings for this namespace context.
|
||||
* The supplied map must consist of string key value pairs.
|
||||
*/
|
||||
public void setBindings(Map<String, String> bindings) {
|
||||
for (Map.Entry<String, String> entry : bindings.entrySet()) {
|
||||
@@ -84,8 +103,7 @@ public class SimpleNamespaceContext implements NamespaceContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the given namespace as default namespace.
|
||||
*
|
||||
* Bind the given namespace as default namespace.
|
||||
* @param namespaceUri the namespace uri
|
||||
*/
|
||||
public void bindDefaultNamespaceUri(String namespaceUri) {
|
||||
@@ -93,70 +111,62 @@ public class SimpleNamespaceContext implements NamespaceContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the given prefix to the given namespace.
|
||||
*
|
||||
* @param prefix the namespace prefix
|
||||
* Bind the given prefix to the given namespace.
|
||||
* @param prefix the namespace prefix
|
||||
* @param namespaceUri the namespace uri
|
||||
*/
|
||||
public void bindNamespaceUri(String prefix, String namespaceUri) {
|
||||
Assert.notNull(prefix, "No prefix given");
|
||||
Assert.notNull(namespaceUri, "No namespaceUri given");
|
||||
if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) {
|
||||
defaultNamespaceUri = namespaceUri;
|
||||
this.defaultNamespaceUri = namespaceUri;
|
||||
}
|
||||
else {
|
||||
prefixToNamespaceUri.put(prefix, namespaceUri);
|
||||
getPrefixesInternal(namespaceUri).add(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes all declared prefixes. */
|
||||
public void clear() {
|
||||
prefixToNamespaceUri.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all declared prefixes.
|
||||
*
|
||||
* @return the declared prefixes
|
||||
*/
|
||||
public Iterator<String> getBoundPrefixes() {
|
||||
return prefixToNamespaceUri.keySet().iterator();
|
||||
}
|
||||
|
||||
private List<String> getPrefixesInternal(String namespaceUri) {
|
||||
if (defaultNamespaceUri.equals(namespaceUri)) {
|
||||
return Collections.singletonList(XMLConstants.DEFAULT_NS_PREFIX);
|
||||
}
|
||||
else if (XMLConstants.XML_NS_URI.equals(namespaceUri)) {
|
||||
return Collections.singletonList(XMLConstants.XML_NS_PREFIX);
|
||||
}
|
||||
else if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceUri)) {
|
||||
return Collections.singletonList(XMLConstants.XMLNS_ATTRIBUTE);
|
||||
}
|
||||
else {
|
||||
List<String> list = namespaceUriToPrefixes.get(namespaceUri);
|
||||
if (list == null) {
|
||||
list = new ArrayList<String>();
|
||||
namespaceUriToPrefixes.put(namespaceUri, list);
|
||||
this.prefixToNamespaceUri.put(prefix, namespaceUri);
|
||||
Set<String> prefixes = this.namespaceUriToPrefixes.get(namespaceUri);
|
||||
if (prefixes == null) {
|
||||
prefixes = new LinkedHashSet<String>();
|
||||
this.namespaceUriToPrefixes.put(namespaceUri, prefixes);
|
||||
}
|
||||
return list;
|
||||
prefixes.add(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given prefix from this context.
|
||||
*
|
||||
* Remove the given prefix from this context.
|
||||
* @param prefix the prefix to be removed
|
||||
*/
|
||||
public void removeBinding(String prefix) {
|
||||
if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) {
|
||||
defaultNamespaceUri = "";
|
||||
this.defaultNamespaceUri = "";
|
||||
}
|
||||
else {
|
||||
String namespaceUri = prefixToNamespaceUri.remove(prefix);
|
||||
List<String> prefixes = getPrefixesInternal(namespaceUri);
|
||||
prefixes.remove(prefix);
|
||||
else if (prefix != null) {
|
||||
String namespaceUri = this.prefixToNamespaceUri.remove(prefix);
|
||||
if (namespaceUri != null) {
|
||||
Set<String> prefixes = this.namespaceUriToPrefixes.get(namespaceUri);
|
||||
if (prefixes != null) {
|
||||
prefixes.remove(prefix);
|
||||
if (prefixes.isEmpty()) {
|
||||
this.namespaceUriToPrefixes.remove(namespaceUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all declared prefixes.
|
||||
*/
|
||||
public void clear() {
|
||||
this.prefixToNamespaceUri.clear();
|
||||
this.namespaceUriToPrefixes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all declared prefixes.
|
||||
*/
|
||||
public Iterator<String> getBoundPrefixes() {
|
||||
return this.prefixToNamespaceUri.keySet().iterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+143
-62
@@ -16,101 +16,182 @@
|
||||
|
||||
package org.springframework.util.xml;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import javax.xml.XMLConstants;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
* @author Leo Arnold
|
||||
*/
|
||||
public class SimpleNamespaceContextTests {
|
||||
|
||||
private final SimpleNamespaceContext context = new SimpleNamespaceContext() {{
|
||||
bindNamespaceUri("prefix", "namespaceURI");
|
||||
}};
|
||||
private final String unboundPrefix = "unbound";
|
||||
private final String prefix = "prefix";
|
||||
private final String namespaceUri = "http://Namespace-name-URI";
|
||||
private final String additionalNamespaceUri = "http://Additional-namespace-name-URI";
|
||||
private final String unboundNamespaceUri = "http://Unbound-namespace-name-URI";
|
||||
private final String defaultNamespaceUri = "http://Default-namespace-name-URI";
|
||||
|
||||
private final SimpleNamespaceContext context = new SimpleNamespaceContext();
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getNamespaceURI_withNull() throws Exception {
|
||||
context.getNamespaceURI(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNamespaceURI() {
|
||||
assertEquals("Invalid namespaceURI for default namespace", "",
|
||||
context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX));
|
||||
String defaultNamespaceUri = "defaultNamespace";
|
||||
context.bindNamespaceUri(XMLConstants.DEFAULT_NS_PREFIX, defaultNamespaceUri);
|
||||
assertEquals("Invalid namespaceURI for default namespace", defaultNamespaceUri,
|
||||
context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX));
|
||||
assertEquals("Invalid namespaceURI for bound prefix", "namespaceURI", context.getNamespaceURI("prefix"));
|
||||
assertEquals("Invalid namespaceURI for unbound prefix", "", context.getNamespaceURI("unbound"));
|
||||
assertEquals("Invalid namespaceURI for namespace prefix", XMLConstants.XML_NS_URI,
|
||||
context.getNamespaceURI(XMLConstants.XML_NS_PREFIX));
|
||||
assertEquals("Invalid namespaceURI for attribute prefix", XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
|
||||
context.getNamespaceURI(XMLConstants.XMLNS_ATTRIBUTE));
|
||||
context.bindNamespaceUri(XMLConstants.XMLNS_ATTRIBUTE, additionalNamespaceUri);
|
||||
assertThat("Always returns \"http://www.w3.org/2000/xmlns/\" for \"xmlns\"",
|
||||
context.getNamespaceURI(XMLConstants.XMLNS_ATTRIBUTE), is(XMLConstants.XMLNS_ATTRIBUTE_NS_URI));
|
||||
context.bindNamespaceUri(XMLConstants.XML_NS_PREFIX, additionalNamespaceUri);
|
||||
assertThat("Always returns \"http://www.w3.org/XML/1998/namespace\" for \"xml\"",
|
||||
context.getNamespaceURI(XMLConstants.XML_NS_PREFIX), is(XMLConstants.XML_NS_URI));
|
||||
|
||||
assertThat("Returns \"\" for an unbound prefix", context.getNamespaceURI(unboundPrefix),
|
||||
is(XMLConstants.NULL_NS_URI));
|
||||
context.bindNamespaceUri(prefix, namespaceUri);
|
||||
assertThat("Returns the bound namespace URI for a bound prefix", context.getNamespaceURI(prefix),
|
||||
is(namespaceUri));
|
||||
|
||||
assertThat("By default returns URI \"\" for the default namespace prefix",
|
||||
context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX), is(XMLConstants.NULL_NS_URI));
|
||||
context.bindDefaultNamespaceUri(defaultNamespaceUri);
|
||||
assertThat("Returns the set URI for the default namespace prefix",
|
||||
context.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX), is(defaultNamespaceUri));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getPrefix_withNull() throws Exception {
|
||||
context.getPrefix(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPrefix() {
|
||||
assertEquals("Invalid prefix for default namespace", XMLConstants.DEFAULT_NS_PREFIX, context.getPrefix(""));
|
||||
assertEquals("Invalid prefix for bound namespace", "prefix", context.getPrefix("namespaceURI"));
|
||||
assertNull("Invalid prefix for unbound namespace", context.getPrefix("unbound"));
|
||||
assertEquals("Invalid prefix for namespace", XMLConstants.XML_NS_PREFIX,
|
||||
context.getPrefix(XMLConstants.XML_NS_URI));
|
||||
assertEquals("Invalid prefix for attribute namespace", XMLConstants.XMLNS_ATTRIBUTE,
|
||||
context.getPrefix(XMLConstants.XMLNS_ATTRIBUTE_NS_URI));
|
||||
assertThat("Always returns \"xmlns\" for \"http://www.w3.org/2000/xmlns/\"",
|
||||
context.getPrefix(XMLConstants.XMLNS_ATTRIBUTE_NS_URI), is(XMLConstants.XMLNS_ATTRIBUTE));
|
||||
assertThat("Always returns \"xml\" for \"http://www.w3.org/XML/1998/namespace\"",
|
||||
context.getPrefix(XMLConstants.XML_NS_URI), is(XMLConstants.XML_NS_PREFIX));
|
||||
|
||||
assertThat("Returns null for an unbound namespace URI", context.getPrefix(unboundNamespaceUri),
|
||||
is(nullValue()));
|
||||
context.bindNamespaceUri("prefix1", namespaceUri);
|
||||
context.bindNamespaceUri("prefix2", namespaceUri);
|
||||
assertThat("Returns a prefix for a bound namespace URI", context.getPrefix(namespaceUri),
|
||||
anyOf(is("prefix1"), is("prefix2")));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getPrefixes_withNull() throws Exception {
|
||||
context.getPrefixes(null);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void getPrefixes_IteratorIsNotModifiable() throws Exception {
|
||||
context.bindNamespaceUri(prefix, namespaceUri);
|
||||
Iterator<String> iterator = context.getPrefixes(namespaceUri);
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPrefixes() {
|
||||
assertPrefixes("", XMLConstants.DEFAULT_NS_PREFIX);
|
||||
assertPrefixes("namespaceURI", "prefix");
|
||||
assertFalse("Invalid prefix for unbound namespace", context.getPrefixes("unbound").hasNext());
|
||||
assertPrefixes(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX);
|
||||
assertPrefixes(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE);
|
||||
assertThat("Returns only \"xmlns\" for \"http://www.w3.org/2000/xmlns/\"",
|
||||
getItemSet(context.getPrefixes(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)),
|
||||
is(makeSet(XMLConstants.XMLNS_ATTRIBUTE)));
|
||||
assertThat("Returns only \"xml\" for \"http://www.w3.org/XML/1998/namespace\"",
|
||||
getItemSet(context.getPrefixes(XMLConstants.XML_NS_URI)), is(makeSet(XMLConstants.XML_NS_PREFIX)));
|
||||
|
||||
assertThat("Returns empty iterator for unbound prefix", context.getPrefixes("unbound Namespace URI").hasNext(),
|
||||
is(false));
|
||||
context.bindNamespaceUri("prefix1", namespaceUri);
|
||||
context.bindNamespaceUri("prefix2", namespaceUri);
|
||||
assertThat("Returns all prefixes (and only those) bound to the namespace URI",
|
||||
getItemSet(context.getPrefixes(namespaceUri)), is(makeSet("prefix1", "prefix2")));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void bindNamespaceUri_withNullNamespaceUri() {
|
||||
context.bindNamespaceUri("prefix", null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void bindNamespaceUri_withNullPrefix() {
|
||||
context.bindNamespaceUri(null, namespaceUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multiplePrefixes() {
|
||||
context.bindNamespaceUri("prefix1", "namespace");
|
||||
context.bindNamespaceUri("prefix2", "namespace");
|
||||
Iterator<String> iterator = context.getPrefixes("namespace");
|
||||
assertNotNull("getPrefixes returns null", iterator);
|
||||
assertTrue("iterator is empty", iterator.hasNext());
|
||||
String result = iterator.next();
|
||||
assertTrue("Invalid prefix", result.equals("prefix1") || result.equals("prefix2"));
|
||||
assertTrue("iterator is empty", iterator.hasNext());
|
||||
result = iterator.next();
|
||||
assertTrue("Invalid prefix", result.equals("prefix1") || result.equals("prefix2"));
|
||||
assertFalse("iterator contains more than two values", iterator.hasNext());
|
||||
}
|
||||
|
||||
private void assertPrefixes(String namespaceUri, String prefix) {
|
||||
Iterator<String> iterator = context.getPrefixes(namespaceUri);
|
||||
assertNotNull("getPrefixes returns null", iterator);
|
||||
assertTrue("iterator is empty", iterator.hasNext());
|
||||
String result = iterator.next();
|
||||
assertEquals("Invalid prefix", prefix, result);
|
||||
assertFalse("iterator contains multiple values", iterator.hasNext());
|
||||
public void bindNamespaceUri() {
|
||||
context.bindNamespaceUri(prefix, namespaceUri);
|
||||
assertThat("The Namespace URI was bound to the prefix", context.getNamespaceURI(prefix), is(namespaceUri));
|
||||
assertThat("The prefix was bound to the namespace URI", getItemSet(context.getPrefixes(namespaceUri)),
|
||||
hasItem(prefix));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBoundPrefixes() throws Exception {
|
||||
Iterator<String> iterator = context.getBoundPrefixes();
|
||||
assertNotNull("getPrefixes returns null", iterator);
|
||||
assertTrue("iterator is empty", iterator.hasNext());
|
||||
String result = iterator.next();
|
||||
assertEquals("Invalid prefix", "prefix", result);
|
||||
assertFalse("iterator contains multiple values", iterator.hasNext());
|
||||
public void getBoundPrefixes() {
|
||||
context.bindNamespaceUri("prefix1", namespaceUri);
|
||||
context.bindNamespaceUri("prefix2", namespaceUri);
|
||||
context.bindNamespaceUri("prefix3", additionalNamespaceUri);
|
||||
assertThat("Returns all bound prefixes", getItemSet(context.getBoundPrefixes()),
|
||||
is(makeSet("prefix1", "prefix2", "prefix3")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setBindings() throws Exception {
|
||||
context.setBindings(Collections.singletonMap("prefix", "namespace"));
|
||||
assertEquals("Invalid namespace uri", "namespace", context.getNamespaceURI("prefix"));
|
||||
public void clear() {
|
||||
context.bindNamespaceUri("prefix1", namespaceUri);
|
||||
context.bindNamespaceUri("prefix2", namespaceUri);
|
||||
context.bindNamespaceUri("prefix3", additionalNamespaceUri);
|
||||
context.clear();
|
||||
assertThat("All bound prefixes were removed", context.getBoundPrefixes().hasNext(), is(false));
|
||||
assertThat("All bound namespace URIs were removed", context.getPrefixes(namespaceUri).hasNext(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeBinding() throws Exception {
|
||||
context.removeBinding("prefix");
|
||||
assertNull("Invalid prefix for unbound namespace", context.getPrefix("prefix"));
|
||||
public void removeBinding() {
|
||||
context.removeBinding(unboundPrefix);
|
||||
|
||||
context.bindNamespaceUri(prefix, namespaceUri);
|
||||
context.removeBinding(prefix);
|
||||
assertThat("Returns default namespace URI for removed prefix", context.getNamespaceURI(prefix),
|
||||
is(XMLConstants.NULL_NS_URI));
|
||||
assertThat("#getPrefix returns null when all prefixes for a namespace URI were removed",
|
||||
context.getPrefix(namespaceUri), is(nullValue()));
|
||||
assertThat("#getPrefixes returns an empty iterator when all prefixes for a namespace URI were removed",
|
||||
context.getPrefixes(namespaceUri).hasNext(), is(false));
|
||||
|
||||
context.bindNamespaceUri("prefix1", additionalNamespaceUri);
|
||||
context.bindNamespaceUri("prefix2", additionalNamespaceUri);
|
||||
context.removeBinding("prefix1");
|
||||
assertThat("Prefix was unbound", context.getNamespaceURI("prefix1"), is(XMLConstants.NULL_NS_URI));
|
||||
assertThat("#getPrefix returns a bound prefix after removal of another prefix for the same namespace URI",
|
||||
context.getPrefix(additionalNamespaceUri), is("prefix2"));
|
||||
assertThat("Prefix was removed from namespace URI", getItemSet(context.getPrefixes(additionalNamespaceUri)),
|
||||
is(makeSet("prefix2")));
|
||||
}
|
||||
|
||||
|
||||
private Set<String> getItemSet(Iterator<String> iterator) {
|
||||
Set<String> itemSet = new HashSet<String>();
|
||||
while (iterator.hasNext()) {
|
||||
itemSet.add(iterator.next());
|
||||
}
|
||||
return itemSet;
|
||||
}
|
||||
|
||||
private Set<String> makeSet(String... items) {
|
||||
Set<String> itemSet = new HashSet<String>();
|
||||
for (String item : items) {
|
||||
itemSet.add(item);
|
||||
}
|
||||
return itemSet;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-2
@@ -221,14 +221,15 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||
private Collection<Method> getMethods(Class<?> type, Object targetObject) {
|
||||
if (targetObject instanceof Class) {
|
||||
Set<Method> result = new LinkedHashSet<Method>();
|
||||
result.addAll(Arrays.asList(getMethods(targetObject.getClass())));
|
||||
// Add these also so that static result are invocable on the type: e.g. Float.valueOf(..)
|
||||
// Add these so that static methods are invocable on the type: e.g. Float.valueOf(..)
|
||||
Method[] methods = getMethods(type);
|
||||
for (Method method : methods) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
result.add(method);
|
||||
}
|
||||
}
|
||||
// Also expose methods from java.lang.Class itself
|
||||
result.addAll(Arrays.asList(getMethods(Class.class)));
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
|
||||
+14
@@ -19,6 +19,7 @@ package org.springframework.expression.spel;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -36,6 +37,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
@@ -2051,6 +2053,17 @@ public class SpelReproTests extends AbstractExpressionTests {
|
||||
assertEquals("{X=66}", result.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void SPR13918() {
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("encoding", "UTF-8");
|
||||
|
||||
Expression ex = parser.parseExpression("T(java.nio.charset.Charset).forName(#encoding)");
|
||||
Object result = ex.getValue(context);
|
||||
assertEquals(Charset.forName("UTF-8"), result);
|
||||
}
|
||||
|
||||
|
||||
public static class ListOf {
|
||||
|
||||
private final double value;
|
||||
@@ -2064,6 +2077,7 @@ public class SpelReproTests extends AbstractExpressionTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class BeanClass {
|
||||
|
||||
private final List<ListOf> list;
|
||||
|
||||
@@ -277,7 +277,11 @@ public abstract class StatementCreatorUtils {
|
||||
if (jdbcDriverName == null) {
|
||||
jdbcDriverName = dbmd.getDriverName();
|
||||
}
|
||||
if (checkGetParameterType) {
|
||||
if (checkGetParameterType &&
|
||||
!(jdbcDriverName.startsWith("Oracle") && dbmd.getDriverMajorVersion() >= 12)) {
|
||||
// Register JDBC driver with no support for getParameterType, except for the
|
||||
// Oracle 12c driver where getParameterType fails for specific statements only
|
||||
// (so an exception thrown above does not indicate general lack of support).
|
||||
driversWithNoSupportForGetParameterType.add(jdbcDriverName);
|
||||
}
|
||||
String databaseProductName = dbmd.getDatabaseProductName();
|
||||
|
||||
+20
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -80,8 +80,8 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
/**
|
||||
* Construct a new {@code ResourceDatabasePopulator} with default settings
|
||||
* for the supplied scripts.
|
||||
* @param scripts the scripts to execute to initialize or clean up the database;
|
||||
* never {@code null}
|
||||
* @param scripts the scripts to execute to initialize or clean up the database
|
||||
* (never {@code null})
|
||||
* @since 4.0.3
|
||||
*/
|
||||
public ResourceDatabasePopulator(Resource... scripts) {
|
||||
@@ -97,21 +97,23 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
* statement can be ignored
|
||||
* @param sqlScriptEncoding the encoding for the supplied SQL scripts; may
|
||||
* be {@code null} or <em>empty</em> to indicate platform encoding
|
||||
* @param scripts the scripts to execute to initialize or clean up the database;
|
||||
* never {@code null}
|
||||
* @param scripts the scripts to execute to initialize or clean up the database
|
||||
* (never {@code null})
|
||||
* @since 4.0.3
|
||||
*/
|
||||
public ResourceDatabasePopulator(boolean continueOnError, boolean ignoreFailedDrops, String sqlScriptEncoding,
|
||||
Resource... scripts) {
|
||||
public ResourceDatabasePopulator(boolean continueOnError, boolean ignoreFailedDrops,
|
||||
String sqlScriptEncoding, Resource... scripts) {
|
||||
|
||||
this(scripts);
|
||||
this.continueOnError = continueOnError;
|
||||
this.ignoreFailedDrops = ignoreFailedDrops;
|
||||
setSqlScriptEncoding(sqlScriptEncoding);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a script to execute to initialize or clean up the database.
|
||||
* @param script the path to an SQL script; never {@code null}
|
||||
* @param script the path to an SQL script (never {@code null})
|
||||
*/
|
||||
public void addScript(Resource script) {
|
||||
Assert.notNull(script, "Script must not be null");
|
||||
@@ -120,7 +122,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
|
||||
/**
|
||||
* Add multiple scripts to execute to initialize or clean up the database.
|
||||
* @param scripts the scripts to execute; never {@code null}
|
||||
* @param scripts the scripts to execute (never {@code null})
|
||||
*/
|
||||
public void addScripts(Resource... scripts) {
|
||||
assertContentsOfScriptArray(scripts);
|
||||
@@ -130,7 +132,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
/**
|
||||
* Set the scripts to execute to initialize or clean up the database,
|
||||
* replacing any previously added scripts.
|
||||
* @param scripts the scripts to execute; never {@code null}
|
||||
* @param scripts the scripts to execute (never {@code null})
|
||||
*/
|
||||
public void setScripts(Resource... scripts) {
|
||||
assertContentsOfScriptArray(scripts);
|
||||
@@ -173,8 +175,8 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
* Set the start delimiter that identifies block comments within the SQL
|
||||
* scripts.
|
||||
* <p>Defaults to {@code "/*"}.
|
||||
* @param blockCommentStartDelimiter the start delimiter for block comments;
|
||||
* never {@code null} or empty
|
||||
* @param blockCommentStartDelimiter the start delimiter for block comments
|
||||
* (never {@code null} or empty)
|
||||
* @since 4.0.3
|
||||
* @see #setBlockCommentEndDelimiter
|
||||
*/
|
||||
@@ -187,8 +189,8 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
* Set the end delimiter that identifies block comments within the SQL
|
||||
* scripts.
|
||||
* <p>Defaults to <code>"*/"</code>.
|
||||
* @param blockCommentEndDelimiter the end delimiter for block comments;
|
||||
* never {@code null} or empty
|
||||
* @param blockCommentEndDelimiter the end delimiter for block comments
|
||||
* (never {@code null} or empty)
|
||||
* @since 4.0.3
|
||||
* @see #setBlockCommentStartDelimiter
|
||||
*/
|
||||
@@ -227,8 +229,8 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
Assert.notNull(connection, "Connection must not be null");
|
||||
for (Resource script : getScripts()) {
|
||||
ScriptUtils.executeSqlScript(connection, encodeScript(script), this.continueOnError,
|
||||
this.ignoreFailedDrops, this.commentPrefix, this.separator, this.blockCommentStartDelimiter,
|
||||
this.blockCommentEndDelimiter);
|
||||
this.ignoreFailedDrops, this.commentPrefix, this.separator, this.blockCommentStartDelimiter,
|
||||
this.blockCommentEndDelimiter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +238,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
* Execute this {@code ResourceDatabasePopulator} against the given
|
||||
* {@link DataSource}.
|
||||
* <p>Delegates to {@link DatabasePopulatorUtils#execute}.
|
||||
* @param dataSource the {@code DataSource} to execute against; never {@code null}
|
||||
* @param dataSource the {@code DataSource} to execute against (never {@code null})
|
||||
* @throws ScriptException if an error occurs
|
||||
* @since 4.1
|
||||
* @see #populate(Connection)
|
||||
@@ -254,7 +256,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
|
||||
* {@link EncodedResource} is not a sub-type of {@link Resource}. Thus we
|
||||
* always need to wrap each script resource in an {@code EncodedResource}
|
||||
* using the configured {@linkplain #setSqlScriptEncoding encoding}.
|
||||
* @param script the script to wrap; never {@code null}
|
||||
* @param script the script to wrap (never {@code null})
|
||||
*/
|
||||
private EncodedResource encodeScript(Resource script) {
|
||||
Assert.notNull(script, "Script must not be null");
|
||||
|
||||
+11
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.sql.Statement;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -399,7 +400,7 @@ public abstract class ScriptUtils {
|
||||
*/
|
||||
public static void executeSqlScript(Connection connection, EncodedResource resource) throws ScriptException {
|
||||
executeSqlScript(connection, resource, false, false, DEFAULT_COMMENT_PREFIX, DEFAULT_STATEMENT_SEPARATOR,
|
||||
DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
|
||||
DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -472,7 +473,14 @@ public abstract class ScriptUtils {
|
||||
stmt.execute(statement);
|
||||
int rowsAffected = stmt.getUpdateCount();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(rowsAffected + " returned as updateCount for SQL: " + statement);
|
||||
logger.debug(rowsAffected + " returned as update count for SQL: " + statement);
|
||||
SQLWarning warningToLog = stmt.getWarnings();
|
||||
while (warningToLog != null) {
|
||||
logger.debug("SQLWarning ignored: SQL state '" + warningToLog.getSQLState() +
|
||||
"', error code '" + warningToLog.getErrorCode() +
|
||||
"', message [" + warningToLog.getMessage() + "]");
|
||||
warningToLog = warningToLog.getNextWarning();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
|
||||
+20
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -175,7 +175,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
|
||||
private Executor taskExecutor;
|
||||
|
||||
private BackOff backOff = createDefaultBackOff(DEFAULT_RECOVERY_INTERVAL);
|
||||
private BackOff backOff = new FixedBackOff(DEFAULT_RECOVERY_INTERVAL, Long.MAX_VALUE);
|
||||
|
||||
private int cacheLevel = CACHE_AUTO;
|
||||
|
||||
@@ -197,6 +197,8 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
|
||||
private volatile boolean recovering = false;
|
||||
|
||||
private volatile boolean interrupted = false;
|
||||
|
||||
private Runnable stopCallback;
|
||||
|
||||
private Object currentRecoveryMarker = new Object();
|
||||
@@ -229,6 +231,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
* attempt to recover.
|
||||
* <p>The {@link #setRecoveryInterval(long) recovery interval} is ignored
|
||||
* when this property is set.
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setBackOff(BackOff backOff) {
|
||||
this.backOff = backOff;
|
||||
@@ -244,7 +247,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
* @see #handleListenerSetupFailure
|
||||
*/
|
||||
public void setRecoveryInterval(long recoveryInterval) {
|
||||
this.backOff = createDefaultBackOff(recoveryInterval);
|
||||
this.backOff = new FixedBackOff(recoveryInterval, Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -892,6 +895,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
}
|
||||
finally {
|
||||
this.recovering = false;
|
||||
this.interrupted = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -941,7 +945,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Stopping container for destination '")
|
||||
.append(getDestinationDescription())
|
||||
.append("' - back off policy does not allow ").append("for further attempts.");
|
||||
.append("': back-off policy does not allow ").append("for further attempts.");
|
||||
logger.error(msg.toString());
|
||||
stop();
|
||||
}
|
||||
@@ -968,12 +972,17 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the next back off time using the specified {@link BackOffExecution}.
|
||||
* <p>Return {@code true} if the back off period has been applied and a new
|
||||
* Apply the next back-off time using the specified {@link BackOffExecution}.
|
||||
* <p>Return {@code true} if the back-off period has been applied and a new
|
||||
* attempt to recover should be made, {@code false} if no further attempt
|
||||
* should be made.
|
||||
* @since 4.1
|
||||
*/
|
||||
protected boolean applyBackOffTime(BackOffExecution execution) {
|
||||
if (this.recovering && this.interrupted) {
|
||||
// Interrupted right before and still failing... give up.
|
||||
return false;
|
||||
}
|
||||
long interval = execution.nextBackOff();
|
||||
if (interval == BackOffExecution.STOP) {
|
||||
return false;
|
||||
@@ -985,13 +994,12 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
catch (InterruptedException interEx) {
|
||||
// Re-interrupt current thread, to allow other threads to react.
|
||||
Thread.currentThread().interrupt();
|
||||
if (this.recovering) {
|
||||
this.interrupted = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private FixedBackOff createDefaultBackOff(long interval) {
|
||||
return new FixedBackOff(interval, Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1205,7 +1213,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the back off time once. In a regular scenario, the back off is only applied if we
|
||||
* Apply the back-off time once. In a regular scenario, the back-off is only applied if we
|
||||
* failed to recover with the broker. This additional sleep period avoids a burst retry
|
||||
* scenario when the broker is actually up but something else if failing (i.e. listener
|
||||
* specific).
|
||||
|
||||
+1
-1
@@ -277,7 +277,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
|
||||
return extractViewClass((JsonView) conversionHint, conversionHint);
|
||||
}
|
||||
else if (conversionHint instanceof Class) {
|
||||
return (Class) conversionHint;
|
||||
return (Class<?>) conversionHint;
|
||||
}
|
||||
|
||||
// No JSON view specified...
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -144,7 +144,7 @@ public class DefaultMessageHandlerMethodFactory implements MessageHandlerMethodF
|
||||
@Override
|
||||
public InvocableHandlerMethod createInvocableHandlerMethod(Object bean, Method method) {
|
||||
InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(bean, method);
|
||||
handlerMethod.setMessageMethodArgumentResolvers(argumentResolvers);
|
||||
handlerMethod.setMessageMethodArgumentResolvers(this.argumentResolvers);
|
||||
return handlerMethod;
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -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.
|
||||
@@ -42,6 +42,7 @@ public class DestinationVariableMethodArgumentResolver extends AbstractNamedValu
|
||||
super(cs, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return parameter.hasParameterAnnotation(DestinationVariable.class);
|
||||
@@ -58,10 +59,9 @@ public class DestinationVariableMethodArgumentResolver extends AbstractNamedValu
|
||||
throws Exception {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> vars = (Map<String, String>) message.getHeaders().get(
|
||||
DESTINATION_TEMPLATE_VARIABLES_HEADER);
|
||||
|
||||
return (vars != null) ? vars.get(name) : null;
|
||||
Map<String, String> vars =
|
||||
(Map<String, String>) message.getHeaders().get(DESTINATION_TEMPLATE_VARIABLES_HEADER);
|
||||
return (vars != null ? vars.get(name) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,4 +77,5 @@ public class DestinationVariableMethodArgumentResolver extends AbstractNamedValu
|
||||
super(annotation.value(), true, ValueConstants.DEFAULT_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-1
@@ -17,7 +17,6 @@
|
||||
package org.springframework.messaging.handler.invocation;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
|
||||
+22
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,6 +42,26 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
|
||||
new ConcurrentHashMap<MethodParameter, HandlerMethodArgumentResolver>(256);
|
||||
|
||||
|
||||
/**
|
||||
* Add the given {@link HandlerMethodArgumentResolver}.
|
||||
*/
|
||||
public HandlerMethodArgumentResolverComposite addResolver(HandlerMethodArgumentResolver argumentResolver) {
|
||||
this.argumentResolvers.add(argumentResolver);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given {@link HandlerMethodArgumentResolver}s.
|
||||
*/
|
||||
public HandlerMethodArgumentResolverComposite addResolvers(List<? extends HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
if (argumentResolvers != null) {
|
||||
for (HandlerMethodArgumentResolver resolver : argumentResolvers) {
|
||||
this.argumentResolvers.add(resolver);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a read-only list with the contained resolvers, or an empty list.
|
||||
*/
|
||||
@@ -56,6 +76,7 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
|
||||
this.argumentResolvers.clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether the given {@linkplain MethodParameter method parameter} is supported by any registered
|
||||
* {@link HandlerMethodArgumentResolver}.
|
||||
@@ -94,24 +115,4 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given {@link HandlerMethodArgumentResolver}.
|
||||
*/
|
||||
public HandlerMethodArgumentResolverComposite addResolver(HandlerMethodArgumentResolver argumentResolver) {
|
||||
this.argumentResolvers.add(argumentResolver);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given {@link HandlerMethodArgumentResolver}s.
|
||||
*/
|
||||
public HandlerMethodArgumentResolverComposite addResolvers(List<? extends HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
if (argumentResolvers != null) {
|
||||
for (HandlerMethodArgumentResolver resolver : argumentResolvers) {
|
||||
this.argumentResolvers.add(resolver);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user