@Nullable all the way: null-safety at field level
This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch. Issue: SPR-15720
This commit is contained in:
@@ -104,11 +104,11 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
private final AspectInstanceFactory aspectInstanceFactory;
|
||||
|
||||
/**
|
||||
* The name of the aspect (ref bean) in which this advice was defined (used
|
||||
* when determining advice precedence so that we can determine
|
||||
* The name of the aspect (ref bean) in which this advice was defined
|
||||
* (used when determining advice precedence so that we can determine
|
||||
* whether two pieces of advice come from the same aspect).
|
||||
*/
|
||||
private String aspectName;
|
||||
private String aspectName = "";
|
||||
|
||||
/**
|
||||
* The order of declaration of this advice within the aspect.
|
||||
@@ -119,13 +119,16 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
* This will be non-null if the creator of this advice object knows the argument names
|
||||
* and sets them explicitly
|
||||
*/
|
||||
private String[] argumentNames = null;
|
||||
@Nullable
|
||||
private String[] argumentNames;
|
||||
|
||||
/** Non-null if after throwing advice binds the thrown value */
|
||||
private String throwingName = null;
|
||||
@Nullable
|
||||
private String throwingName;
|
||||
|
||||
/** Non-null if after returning advice binds the return value */
|
||||
private String returningName = null;
|
||||
@Nullable
|
||||
private String returningName;
|
||||
|
||||
private Class<?> discoveredReturningType = Object.class;
|
||||
|
||||
@@ -143,10 +146,12 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
*/
|
||||
private int joinPointStaticPartArgumentIndex = -1;
|
||||
|
||||
@Nullable
|
||||
private Map<String, Integer> argumentBindings;
|
||||
|
||||
private boolean argumentsIntrospected = false;
|
||||
|
||||
@Nullable
|
||||
private Type discoveredReturningGenericType;
|
||||
// Note: Unlike return type, no such generic information is needed for the throwing type,
|
||||
// since Java doesn't allow exception types to be parameterized.
|
||||
@@ -464,6 +469,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
|
||||
private void bindExplicitArguments(int numArgumentsLeftToBind) {
|
||||
Assert.state(this.argumentNames != null, "No argument names available");
|
||||
this.argumentBindings = new HashMap<>();
|
||||
|
||||
int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterCount();
|
||||
@@ -504,7 +510,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
}
|
||||
|
||||
// configure the pointcut expression accordingly.
|
||||
configurePointcutParameters(argumentIndexOffset);
|
||||
configurePointcutParameters(this.argumentNames, argumentIndexOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -512,7 +518,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
* pointcut parameters - but returning and throwing vars are handled differently
|
||||
* and must be removed from the list if present.
|
||||
*/
|
||||
private void configurePointcutParameters(int argumentIndexOffset) {
|
||||
private void configurePointcutParameters(String[] argumentNames, int argumentIndexOffset) {
|
||||
int numParametersToRemove = argumentIndexOffset;
|
||||
if (this.returningName != null) {
|
||||
numParametersToRemove++;
|
||||
@@ -520,20 +526,20 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
if (this.throwingName != null) {
|
||||
numParametersToRemove++;
|
||||
}
|
||||
String[] pointcutParameterNames = new String[this.argumentNames.length - numParametersToRemove];
|
||||
String[] pointcutParameterNames = new String[argumentNames.length - numParametersToRemove];
|
||||
Class<?>[] pointcutParameterTypes = new Class<?>[pointcutParameterNames.length];
|
||||
Class<?>[] methodParameterTypes = this.aspectJAdviceMethod.getParameterTypes();
|
||||
|
||||
int index = 0;
|
||||
for (int i = 0; i < this.argumentNames.length; i++) {
|
||||
for (int i = 0; i < argumentNames.length; i++) {
|
||||
if (i < argumentIndexOffset) {
|
||||
continue;
|
||||
}
|
||||
if (this.argumentNames[i].equals(this.returningName) ||
|
||||
this.argumentNames[i].equals(this.throwingName)) {
|
||||
if (argumentNames[i].equals(this.returningName) ||
|
||||
argumentNames[i].equals(this.throwingName)) {
|
||||
continue;
|
||||
}
|
||||
pointcutParameterNames[index] = this.argumentNames[i];
|
||||
pointcutParameterNames[index] = argumentNames[i];
|
||||
pointcutParameterTypes[index] = methodParameterTypes[i];
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ import org.springframework.util.StringUtils;
|
||||
* returning {@code null} in the case that the parameter names cannot be discovered.
|
||||
*
|
||||
* @author Adrian Colyer
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscoverer {
|
||||
@@ -155,26 +156,23 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
}
|
||||
|
||||
|
||||
private boolean raiseExceptions;
|
||||
|
||||
/**
|
||||
* If the advice is afterReturning, and binds the return value, this is the parameter name used.
|
||||
*/
|
||||
private String returningName;
|
||||
|
||||
/**
|
||||
* If the advice is afterThrowing, and binds the thrown value, this is the parameter name used.
|
||||
*/
|
||||
private String throwingName;
|
||||
|
||||
/**
|
||||
* The pointcut expression associated with the advice, as a simple String.
|
||||
*/
|
||||
/** The pointcut expression associated with the advice, as a simple String */
|
||||
@Nullable
|
||||
private String pointcutExpression;
|
||||
|
||||
private Class<?>[] argumentTypes;
|
||||
private boolean raiseExceptions;
|
||||
|
||||
private String[] parameterNameBindings;
|
||||
/** If the advice is afterReturning, and binds the return value, this is the parameter name used */
|
||||
@Nullable
|
||||
private String returningName;
|
||||
|
||||
/** If the advice is afterThrowing, and binds the thrown value, this is the parameter name used */
|
||||
@Nullable
|
||||
private String throwingName;
|
||||
|
||||
private Class<?>[] argumentTypes = new Class<?>[0];
|
||||
|
||||
private String[] parameterNameBindings = new String[0];
|
||||
|
||||
private int numberOfRemainingUnboundArguments;
|
||||
|
||||
@@ -202,7 +200,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
* returning variable name must be specified.
|
||||
* @param returningName the name of the returning variable
|
||||
*/
|
||||
public void setReturningName(String returningName) {
|
||||
public void setReturningName(@Nullable String returningName) {
|
||||
this.returningName = returningName;
|
||||
}
|
||||
|
||||
@@ -211,7 +209,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
* throwing variable name must be specified.
|
||||
* @param throwingName the name of the throwing variable
|
||||
*/
|
||||
public void setThrowingName(String throwingName) {
|
||||
public void setThrowingName(@Nullable String throwingName) {
|
||||
this.throwingName = throwingName;
|
||||
}
|
||||
|
||||
@@ -781,6 +779,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
|
||||
|
||||
private int numTokensConsumed;
|
||||
|
||||
@Nullable
|
||||
private String text;
|
||||
|
||||
public PointcutBody(int tokens, @Nullable String text) {
|
||||
|
||||
@@ -102,16 +102,20 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AspectJExpressionPointcut.class);
|
||||
|
||||
@Nullable
|
||||
private Class<?> pointcutDeclarationScope;
|
||||
|
||||
private String[] pointcutParameterNames = new String[0];
|
||||
|
||||
private Class<?>[] pointcutParameterTypes = new Class<?>[0];
|
||||
|
||||
@Nullable
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@Nullable
|
||||
private transient ClassLoader pointcutClassLoader;
|
||||
|
||||
@Nullable
|
||||
private transient PointcutExpression pointcutExpression;
|
||||
|
||||
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<>(32);
|
||||
@@ -169,13 +173,13 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
@Override
|
||||
public ClassFilter getClassFilter() {
|
||||
checkReadyToMatch();
|
||||
obtainPointcutExpression();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
checkReadyToMatch();
|
||||
obtainPointcutExpression();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -184,7 +188,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
* Check whether this pointcut is ready to match,
|
||||
* lazily building the underlying AspectJ pointcut expression.
|
||||
*/
|
||||
private void checkReadyToMatch() {
|
||||
private PointcutExpression obtainPointcutExpression() {
|
||||
if (getExpression() == null) {
|
||||
throw new IllegalStateException("Must set property 'expression' before attempting to match");
|
||||
}
|
||||
@@ -192,6 +196,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
this.pointcutClassLoader = determinePointcutClassLoader();
|
||||
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
|
||||
}
|
||||
return this.pointcutExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,16 +263,15 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
* Return the underlying AspectJ pointcut expression.
|
||||
*/
|
||||
public PointcutExpression getPointcutExpression() {
|
||||
checkReadyToMatch();
|
||||
return this.pointcutExpression;
|
||||
return obtainPointcutExpression();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Class<?> targetClass) {
|
||||
checkReadyToMatch();
|
||||
PointcutExpression pointcutExpression = obtainPointcutExpression();
|
||||
try {
|
||||
try {
|
||||
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
|
||||
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
|
||||
}
|
||||
catch (ReflectionWorldException ex) {
|
||||
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
|
||||
@@ -286,7 +290,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, @Nullable Class<?> targetClass, boolean beanHasIntroductions) {
|
||||
checkReadyToMatch();
|
||||
obtainPointcutExpression();
|
||||
Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
|
||||
ShadowMatch shadowMatch = getShadowMatch(targetMethod, method);
|
||||
|
||||
@@ -321,13 +325,12 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
@Override
|
||||
public boolean isRuntime() {
|
||||
checkReadyToMatch();
|
||||
return this.pointcutExpression.mayNeedDynamicTest();
|
||||
return obtainPointcutExpression().mayNeedDynamicTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, @Nullable Class<?> targetClass, Object... args) {
|
||||
checkReadyToMatch();
|
||||
obtainPointcutExpression();
|
||||
ShadowMatch shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method);
|
||||
ShadowMatch originalShadowMatch = getShadowMatch(method, method);
|
||||
|
||||
@@ -436,7 +439,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
if (shadowMatch == null) {
|
||||
try {
|
||||
try {
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
shadowMatch = obtainPointcutExpression().matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
catch (ReflectionWorldException ex) {
|
||||
// Failed to introspect target method, probably because it has been loaded
|
||||
@@ -454,7 +457,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
if (shadowMatch == null && targetMethod != originalMethod) {
|
||||
methodToMatch = originalMethod;
|
||||
try {
|
||||
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
|
||||
shadowMatch = obtainPointcutExpression().matchesMethodExecution(methodToMatch);
|
||||
}
|
||||
catch (ReflectionWorldException ex3) {
|
||||
// Could neither introspect the target class nor the proxy class ->
|
||||
@@ -519,18 +522,16 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("AspectJExpressionPointcut: ");
|
||||
if (this.pointcutParameterNames != null && this.pointcutParameterTypes != null) {
|
||||
sb.append("(");
|
||||
for (int i = 0; i < this.pointcutParameterTypes.length; i++) {
|
||||
sb.append(this.pointcutParameterTypes[i].getName());
|
||||
sb.append(" ");
|
||||
sb.append(this.pointcutParameterNames[i]);
|
||||
if ((i+1) < this.pointcutParameterTypes.length) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append("(");
|
||||
for (int i = 0; i < this.pointcutParameterTypes.length; i++) {
|
||||
sb.append(this.pointcutParameterTypes[i].getName());
|
||||
sb.append(" ");
|
||||
sb.append(this.pointcutParameterNames[i]);
|
||||
if ((i+1) < this.pointcutParameterTypes.length) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(")");
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(" ");
|
||||
if (getExpression() != null) {
|
||||
sb.append(getExpression());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import org.aopalliance.aop.Advice;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.PointcutAdvisor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -38,6 +39,7 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
|
||||
|
||||
private final Pointcut pointcut;
|
||||
|
||||
@Nullable
|
||||
private Integer order;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,12 +57,15 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
|
||||
private final ProxyMethodInvocation methodInvocation;
|
||||
|
||||
@Nullable
|
||||
private Object[] defensiveCopyOfArgs;
|
||||
|
||||
/** Lazily initialized signature object */
|
||||
@Nullable
|
||||
private Signature signature;
|
||||
|
||||
/** Lazily initialized source location object */
|
||||
@Nullable
|
||||
private SourceLocation sourceLocation;
|
||||
|
||||
|
||||
@@ -178,6 +181,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
*/
|
||||
private class MethodSignatureImpl implements MethodSignature {
|
||||
|
||||
@Nullable
|
||||
private volatile String[] parameterNames;
|
||||
|
||||
@Override
|
||||
@@ -216,6 +220,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String[] getParameterNames() {
|
||||
if (this.parameterNames == null) {
|
||||
this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,6 +37,7 @@ import org.aspectj.weaver.reflect.ReflectionVar;
|
||||
import org.aspectj.weaver.reflect.ShadowMatchImpl;
|
||||
import org.aspectj.weaver.tools.ShadowMatch;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@@ -78,6 +79,7 @@ class RuntimeTestWalker {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private final Test runtimeTest;
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.aspectj.weaver.tools.PointcutParser;
|
||||
import org.aspectj.weaver.tools.TypePatternMatcher;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -32,8 +33,9 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class TypePatternClassFilter implements ClassFilter {
|
||||
|
||||
private String typePattern;
|
||||
private String typePattern = "";
|
||||
|
||||
@Nullable
|
||||
private TypePatternMatcher aspectJTypePatternMatcher;
|
||||
|
||||
|
||||
@@ -51,8 +53,6 @@ public class TypePatternClassFilter implements ClassFilter {
|
||||
* Create a fully configured {@link TypePatternClassFilter} using the
|
||||
* given type pattern.
|
||||
* @param typePattern the type pattern that AspectJ weaver should parse
|
||||
* @throws IllegalArgumentException if the supplied {@code typePattern} is {@code null}
|
||||
* or is recognized as invalid
|
||||
*/
|
||||
public TypePatternClassFilter(String typePattern) {
|
||||
setTypePattern(typePattern);
|
||||
@@ -73,8 +73,6 @@ public class TypePatternClassFilter implements ClassFilter {
|
||||
* that implements it.
|
||||
* <p>These conventions are established by AspectJ, not Spring AOP.
|
||||
* @param typePattern the type pattern that AspectJ weaver should parse
|
||||
* @throws IllegalArgumentException if the supplied {@code typePattern} is {@code null}
|
||||
* or is recognized as invalid
|
||||
*/
|
||||
public void setTypePattern(String typePattern) {
|
||||
Assert.notNull(typePattern, "Type pattern must not be null");
|
||||
|
||||
@@ -212,9 +212,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
throw new IllegalStateException("Unknown annotation type: " + annotation.toString());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String resolveExpression(A annotation) throws Exception {
|
||||
String expression = null;
|
||||
for (String methodName : EXPRESSION_PROPERTIES) {
|
||||
Method method;
|
||||
try {
|
||||
@@ -226,11 +224,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
if (method != null) {
|
||||
String candidate = (String) method.invoke(annotation);
|
||||
if (StringUtils.hasText(candidate)) {
|
||||
expression = candidate;
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
throw new IllegalStateException("Failed to resolve expression: " + annotation);
|
||||
}
|
||||
|
||||
public AspectJAnnotationType getAnnotationType() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -48,10 +49,13 @@ import org.springframework.util.Assert;
|
||||
@SuppressWarnings("serial")
|
||||
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
|
||||
|
||||
@Nullable
|
||||
private List<Pattern> includePatterns;
|
||||
|
||||
@Nullable
|
||||
private AspectJAdvisorFactory aspectJAdvisorFactory;
|
||||
|
||||
@Nullable
|
||||
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
|
||||
|
||||
|
||||
@@ -87,7 +91,9 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
|
||||
// Add all the Spring advisors found according to superclass rules.
|
||||
List<Advisor> advisors = super.findCandidateAdvisors();
|
||||
// Build Advisors for all AspectJ aspects in the bean factory.
|
||||
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
|
||||
if (this.aspectJAdvisorsBuilder != null) {
|
||||
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
|
||||
}
|
||||
return advisors;
|
||||
}
|
||||
|
||||
@@ -101,7 +107,8 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
|
||||
// proxied by that interface and fail at runtime as the advice method is not
|
||||
// defined on the interface. We could potentially relax the restriction about
|
||||
// not advising aspects in the future.
|
||||
return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));
|
||||
return (super.isInfrastructureClass(beanClass) ||
|
||||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -104,19 +104,19 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
||||
|
||||
@Override
|
||||
public Object getAspectCreationMutex() {
|
||||
if (this.beanFactory != null) {
|
||||
if (this.beanFactory.isSingleton(name)) {
|
||||
// Rely on singleton semantics provided by the factory -> no local lock.
|
||||
return null;
|
||||
}
|
||||
else if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
// No singleton guarantees from the factory -> let's lock locally but
|
||||
// reuse the factory's singleton lock, just in case a lazy dependency
|
||||
// of our advice bean happens to trigger the singleton lock implicitly...
|
||||
return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
|
||||
}
|
||||
if (this.beanFactory.isSingleton(this.name)) {
|
||||
// Rely on singleton semantics provided by the factory -> no local lock.
|
||||
return null;
|
||||
}
|
||||
else if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
// No singleton guarantees from the factory -> let's lock locally but
|
||||
// reuse the factory's singleton lock, just in case a lazy dependency
|
||||
// of our advice bean happens to trigger the singleton lock implicitly...
|
||||
return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
|
||||
}
|
||||
else {
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,7 @@ import org.aspectj.lang.reflect.PerClauseKind;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -43,6 +44,7 @@ public class BeanFactoryAspectJAdvisorsBuilder {
|
||||
|
||||
private final AspectJAdvisorFactory advisorFactory;
|
||||
|
||||
@Nullable
|
||||
private volatile List<String> aspectBeanNames;
|
||||
|
||||
private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -70,10 +70,13 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
private final boolean lazy;
|
||||
|
||||
@Nullable
|
||||
private Advice instantiatedAdvice;
|
||||
|
||||
@Nullable
|
||||
private Boolean isBeforeAdvice;
|
||||
|
||||
@Nullable
|
||||
private Boolean isAfterAdvice;
|
||||
|
||||
|
||||
@@ -267,10 +270,12 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
private final Pointcut preInstantiationPointcut;
|
||||
|
||||
@Nullable
|
||||
private LazySingletonAspectInstanceFactoryDecorator aspectInstanceFactory;
|
||||
|
||||
private PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut,
|
||||
Pointcut preInstantiationPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
|
||||
|
||||
this.declaredPointcut = declaredPointcut;
|
||||
this.preInstantiationPointcut = preInstantiationPointcut;
|
||||
if (aspectInstanceFactory instanceof LazySingletonAspectInstanceFactoryDecorator) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -32,6 +33,7 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
|
||||
private final MetadataAwareAspectInstanceFactory maaif;
|
||||
|
||||
@Nullable
|
||||
private volatile Object materialized;
|
||||
|
||||
|
||||
@@ -47,20 +49,24 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
||||
|
||||
@Override
|
||||
public Object getAspectInstance() {
|
||||
if (this.materialized == null) {
|
||||
Object aspectInstance = this.materialized;
|
||||
if (aspectInstance == null) {
|
||||
Object mutex = this.maaif.getAspectCreationMutex();
|
||||
if (mutex == null) {
|
||||
this.materialized = this.maaif.getAspectInstance();
|
||||
aspectInstance = this.maaif.getAspectInstance();
|
||||
this.materialized = aspectInstance;
|
||||
}
|
||||
else {
|
||||
synchronized (mutex) {
|
||||
if (this.materialized == null) {
|
||||
this.materialized = this.maaif.getAspectInstance();
|
||||
aspectInstance = this.materialized;
|
||||
if (aspectInstance == null) {
|
||||
aspectInstance = this.maaif.getAspectInstance();
|
||||
this.materialized = aspectInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.materialized;
|
||||
return aspectInstance;
|
||||
}
|
||||
|
||||
public boolean isMaterialized() {
|
||||
|
||||
@@ -86,6 +86,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
|
||||
@@ -209,7 +210,9 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
|
||||
AspectJExpressionPointcut ajexp =
|
||||
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
|
||||
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
|
||||
ajexp.setBeanFactory(this.beanFactory);
|
||||
if (this.beanFactory != null) {
|
||||
ajexp.setBeanFactory(this.beanFactory);
|
||||
}
|
||||
return ajexp;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -32,10 +33,13 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class MethodLocatingFactoryBean implements FactoryBean<Method>, BeanFactoryAware {
|
||||
|
||||
@Nullable
|
||||
private String targetBeanName;
|
||||
|
||||
@Nullable
|
||||
private String methodName;
|
||||
|
||||
@Nullable
|
||||
private Method method;
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.FactoryBeanNotInitializedException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -41,19 +42,25 @@ import org.springframework.util.ClassUtils;
|
||||
public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
|
||||
implements FactoryBean<Object>, BeanClassLoaderAware, InitializingBean {
|
||||
|
||||
@Nullable
|
||||
private Object target;
|
||||
|
||||
@Nullable
|
||||
private Class<?>[] proxyInterfaces;
|
||||
|
||||
@Nullable
|
||||
private Object[] preInterceptors;
|
||||
|
||||
@Nullable
|
||||
private Object[] postInterceptors;
|
||||
|
||||
/** Default is global AdvisorAdapterRegistry */
|
||||
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
|
||||
|
||||
@Nullable
|
||||
private transient ClassLoader proxyClassLoader;
|
||||
|
||||
@Nullable
|
||||
private Object proxy;
|
||||
|
||||
|
||||
|
||||
@@ -220,8 +220,11 @@ public abstract class AopProxyUtils {
|
||||
* @return a cloned argument array, or the original if no adaptation is needed
|
||||
* @since 4.2.3
|
||||
*/
|
||||
static Object[] adaptArgumentsIfNecessary(Method method, Object... arguments) {
|
||||
if (method.isVarArgs() && !ObjectUtils.isEmpty(arguments)) {
|
||||
static Object[] adaptArgumentsIfNecessary(Method method, @Nullable Object[] arguments) {
|
||||
if (ObjectUtils.isEmpty(arguments)) {
|
||||
return new Object[0];
|
||||
}
|
||||
if (method.isVarArgs()) {
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
if (paramTypes.length == arguments.length) {
|
||||
int varargIndex = paramTypes.length - 1;
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -102,14 +103,16 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
/** The configuration used to configure this proxy */
|
||||
protected final AdvisedSupport advised;
|
||||
|
||||
@Nullable
|
||||
protected Object[] constructorArgs;
|
||||
|
||||
@Nullable
|
||||
protected Class<?>[] constructorArgTypes;
|
||||
|
||||
/** Dispatcher used for methods on Advised */
|
||||
private final transient AdvisedDispatcher advisedDispatcher;
|
||||
|
||||
private transient Map<String, Integer> fixedInterceptorMap;
|
||||
private transient Map<String, Integer> fixedInterceptorMap = Collections.emptyMap();
|
||||
|
||||
private transient int fixedInterceptorOffset;
|
||||
|
||||
@@ -216,7 +219,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
|
||||
enhancer.setInterceptDuringConstruction(false);
|
||||
enhancer.setCallbacks(callbacks);
|
||||
return (this.constructorArgs != null ?
|
||||
return (this.constructorArgs != null && this.constructorArgTypes != null ?
|
||||
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
|
||||
enhancer.create());
|
||||
}
|
||||
@@ -409,6 +412,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {
|
||||
|
||||
@Nullable
|
||||
private final Object target;
|
||||
|
||||
public StaticUnadvisedInterceptor(@Nullable Object target) {
|
||||
@@ -430,6 +434,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {
|
||||
|
||||
@Nullable
|
||||
private final Object target;
|
||||
|
||||
public StaticUnadvisedExposedInterceptor(@Nullable Object target) {
|
||||
@@ -520,6 +525,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
private static class StaticDispatcher implements Dispatcher, Serializable {
|
||||
|
||||
@Nullable
|
||||
private Object target;
|
||||
|
||||
public StaticDispatcher(@Nullable Object target) {
|
||||
@@ -527,6 +533,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object loadObject() {
|
||||
return this.target;
|
||||
}
|
||||
@@ -610,8 +617,10 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
private final List<Object> adviceChain;
|
||||
|
||||
@Nullable
|
||||
private final Object target;
|
||||
|
||||
@Nullable
|
||||
private final Class<?> targetClass;
|
||||
|
||||
public FixedChainStaticTargetInterceptor(
|
||||
@@ -960,6 +969,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
*/
|
||||
private static class ClassLoaderAwareUndeclaredThrowableStrategy extends UndeclaredThrowableStrategy {
|
||||
|
||||
@Nullable
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
public ClassLoaderAwareUndeclaredThrowableStrategy(@Nullable ClassLoader classLoader) {
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.springframework.beans.factory.FactoryBeanNotInitializedException;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -101,8 +102,10 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@Nullable
|
||||
private String[] interceptorNames;
|
||||
|
||||
@Nullable
|
||||
private String targetName;
|
||||
|
||||
private boolean autodetectInterfaces = true;
|
||||
@@ -113,16 +116,19 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
|
||||
private boolean freezeProxy = false;
|
||||
|
||||
@Nullable
|
||||
private transient ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
private transient boolean classLoaderConfigured = false;
|
||||
|
||||
@Nullable
|
||||
private transient BeanFactory beanFactory;
|
||||
|
||||
/** Whether the advisor chain has already been initialized */
|
||||
private boolean advisorChainInitialized = false;
|
||||
|
||||
/** If this is a singleton, the cached singleton proxy instance */
|
||||
@Nullable
|
||||
private Object singletonInstance;
|
||||
|
||||
|
||||
@@ -404,6 +410,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
|
||||
* @return {@code true} if it's an Advisor or Advice
|
||||
*/
|
||||
private boolean isNamedBeanAnAdvisorOrAdvice(String beanName) {
|
||||
Assert.state(this.beanFactory != null, "No BeanFactory set");
|
||||
Class<?> namedBeanClass = this.beanFactory.getType(beanName);
|
||||
if (namedBeanClass != null) {
|
||||
return (Advisor.class.isAssignableFrom(namedBeanClass) || Advice.class.isAssignableFrom(namedBeanClass));
|
||||
|
||||
@@ -43,6 +43,7 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
|
||||
*/
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
@Nullable
|
||||
private ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
private boolean classLoaderConfigured = false;
|
||||
@@ -77,6 +78,7 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
|
||||
/**
|
||||
* Return the configured proxy ClassLoader for this processor.
|
||||
*/
|
||||
@Nullable
|
||||
protected ClassLoader getProxyClassLoader() {
|
||||
return this.proxyClassLoader;
|
||||
}
|
||||
|
||||
@@ -63,17 +63,20 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
|
||||
protected final Object proxy;
|
||||
|
||||
@Nullable
|
||||
protected final Object target;
|
||||
|
||||
protected final Method method;
|
||||
|
||||
protected Object[] arguments;
|
||||
protected Object[] arguments = new Object[0];
|
||||
|
||||
@Nullable
|
||||
private final Class<?> targetClass;
|
||||
|
||||
/**
|
||||
* Lazily initialized map of user-specific attributes for this invocation.
|
||||
*/
|
||||
@Nullable
|
||||
private Map<String, Object> userAttributes;
|
||||
|
||||
/**
|
||||
@@ -103,7 +106,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
* but would complicate the code. And it would work only for static pointcuts.
|
||||
*/
|
||||
protected ReflectiveMethodInvocation(
|
||||
Object proxy, @Nullable Object target, Method method, Object[] arguments,
|
||||
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
|
||||
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
||||
|
||||
this.proxy = proxy;
|
||||
@@ -143,7 +146,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
|
||||
@Override
|
||||
public final Object[] getArguments() {
|
||||
return (this.arguments != null ? this.arguments : new Object[0]);
|
||||
return this.arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,8 +208,8 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
*/
|
||||
@Override
|
||||
public MethodInvocation invocableClone() {
|
||||
Object[] cloneArguments = null;
|
||||
if (this.arguments != null) {
|
||||
Object[] cloneArguments = this.arguments;
|
||||
if (this.arguments.length > 0) {
|
||||
// Build an independent copy of the arguments array.
|
||||
cloneArguments = new Object[this.arguments.length];
|
||||
System.arraycopy(this.arguments, 0, cloneArguments, 0, this.arguments.length);
|
||||
@@ -223,7 +226,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
public MethodInvocation invocableClone(@Nullable Object... arguments) {
|
||||
public MethodInvocation invocableClone(Object... arguments) {
|
||||
// Force initialization of the user attributes Map,
|
||||
// for having a shared Map reference in the clone.
|
||||
if (this.userAttributes == null) {
|
||||
|
||||
@@ -97,6 +97,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
* Convenience constant for subclasses: Return value for "do not proxy".
|
||||
* @see #getAdvicesAndAdvisorsForBean
|
||||
*/
|
||||
@Nullable
|
||||
protected static final Object[] DO_NOT_PROXY = null;
|
||||
|
||||
/**
|
||||
@@ -124,8 +125,10 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
||||
|
||||
private boolean applyCommonInterceptorsFirst = true;
|
||||
|
||||
@Nullable
|
||||
private TargetSourceCreator[] customTargetSourceCreators;
|
||||
|
||||
@Nullable
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Extension of {@link AbstractAutoProxyCreator} which implements {@link BeanFactoryAware},
|
||||
@@ -39,6 +40,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
public abstract class AbstractBeanFactoryAwareAdvisingPostProcessor extends AbstractAdvisingBeanPostProcessor
|
||||
implements BeanFactoryAware {
|
||||
|
||||
@Nullable
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -43,6 +44,7 @@ public class BeanFactoryAdvisorRetrievalHelper {
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Nullable
|
||||
private String[] cachedAdvisorBeanNames;
|
||||
|
||||
|
||||
@@ -95,7 +97,8 @@ public class BeanFactoryAdvisorRetrievalHelper {
|
||||
Throwable rootCause = ex.getMostSpecificCause();
|
||||
if (rootCause instanceof BeanCurrentlyInCreationException) {
|
||||
BeanCreationException bce = (BeanCreationException) rootCause;
|
||||
if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
|
||||
String bceBeanName = bce.getBeanName();
|
||||
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Skipping advisor '" + name +
|
||||
"' with dependency on currently created bean: " + ex.getMessage());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,6 +46,7 @@ import org.springframework.util.StringUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
|
||||
@Nullable
|
||||
private List<String> beanNames;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.aop.framework.autoproxy;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* {@code BeanPostProcessor} implementation that creates AOP proxies based on all
|
||||
@@ -43,6 +44,7 @@ public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCrea
|
||||
|
||||
private boolean usePrefix = false;
|
||||
|
||||
@Nullable
|
||||
private String advisorBeanNamePrefix;
|
||||
|
||||
|
||||
@@ -76,6 +78,7 @@ public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCrea
|
||||
* Return the prefix for bean names that will cause them to be included
|
||||
* for auto-proxying by this object.
|
||||
*/
|
||||
@Nullable
|
||||
public String getAdvisorBeanNamePrefix() {
|
||||
return this.advisorBeanNamePrefix;
|
||||
}
|
||||
@@ -96,7 +99,11 @@ public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCrea
|
||||
*/
|
||||
@Override
|
||||
protected boolean isEligibleAdvisorBean(String beanName) {
|
||||
return (!isUsePrefix() || beanName.startsWith(getAdvisorBeanNamePrefix()));
|
||||
if (!isUsePrefix()) {
|
||||
return true;
|
||||
}
|
||||
String prefix = getAdvisorBeanNamePrefix();
|
||||
return (prefix != null && beanName.startsWith(prefix));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Base {@code MethodInterceptor} implementation for tracing.
|
||||
@@ -50,6 +51,7 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
|
||||
* The default {@code Log} instance used to write trace messages.
|
||||
* This instance is mapped to the implementing {@code Class}.
|
||||
*/
|
||||
@Nullable
|
||||
protected transient Log defaultLogger = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
@@ -83,7 +85,6 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
|
||||
* but rather into a specific named category.
|
||||
* <p><b>NOTE:</b> Specify either this property or "useDynamicLogger", not both.
|
||||
* @see org.apache.commons.logging.LogFactory#getLog(String)
|
||||
* @see org.apache.log4j.Logger#getLogger(String)
|
||||
* @see java.util.logging.Logger#getLogger(String)
|
||||
*/
|
||||
public void setLoggerName(String loggerName) {
|
||||
|
||||
@@ -72,10 +72,12 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
|
||||
|
||||
private final Map<Method, AsyncTaskExecutor> executors = new ConcurrentHashMap<>(16);
|
||||
|
||||
@Nullable
|
||||
private volatile Executor defaultExecutor;
|
||||
|
||||
private AsyncUncaughtExceptionHandler exceptionHandler;
|
||||
|
||||
@Nullable
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,6 +28,8 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.FactoryBeanNotInitializedException;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -56,9 +58,11 @@ public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean<O
|
||||
private final SimpleBeanTargetSource scopedTargetSource = new SimpleBeanTargetSource();
|
||||
|
||||
/** The name of the target bean */
|
||||
@Nullable
|
||||
private String targetBeanName;
|
||||
|
||||
/** The cached singleton proxy */
|
||||
@Nullable
|
||||
private Object proxy;
|
||||
|
||||
|
||||
@@ -91,6 +95,7 @@ public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean<O
|
||||
pf.copyFrom(this);
|
||||
pf.setTargetSource(this.scopedTargetSource);
|
||||
|
||||
Assert.notNull(this.targetBeanName, "Property 'targetBeanName' is required");
|
||||
Class<?> beanType = beanFactory.getType(this.targetBeanName);
|
||||
if (beanType == null) {
|
||||
throw new IllegalStateException("Cannot create scoped proxy for bean '" + this.targetBeanName +
|
||||
|
||||
@@ -43,10 +43,13 @@ import org.springframework.util.Assert;
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
|
||||
|
||||
@Nullable
|
||||
private String adviceBeanName;
|
||||
|
||||
@Nullable
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@Nullable
|
||||
private transient volatile Advice advice;
|
||||
|
||||
private transient volatile Object adviceMonitor = new Object();
|
||||
@@ -119,10 +122,12 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
// reuse the factory's singleton lock, just in case a lazy dependency
|
||||
// of our advice bean happens to trigger the singleton lock implicitly...
|
||||
synchronized (this.adviceMonitor) {
|
||||
if (this.advice == null) {
|
||||
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||
advice = this.advice;
|
||||
if (advice == null) {
|
||||
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||
this.advice = advice;
|
||||
}
|
||||
return this.advice;
|
||||
return advice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,8 +33,10 @@ import org.springframework.lang.Nullable;
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractExpressionPointcut implements ExpressionPointcut, Serializable {
|
||||
|
||||
@Nullable
|
||||
private String location;
|
||||
|
||||
@Nullable
|
||||
private String expression;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import org.aopalliance.aop.Advice;
|
||||
|
||||
import org.springframework.aop.PointcutAdvisor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -37,6 +38,7 @@ import org.springframework.util.ObjectUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable {
|
||||
|
||||
@Nullable
|
||||
private Integer order;
|
||||
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public abstract class AopUtils {
|
||||
* @see #isJdkDynamicProxy
|
||||
* @see #isCglibProxy
|
||||
*/
|
||||
public static boolean isAopProxy(Object object) {
|
||||
public static boolean isAopProxy(@Nullable Object object) {
|
||||
return (object instanceof SpringProxy &&
|
||||
(Proxy.isProxyClass(object.getClass()) || ClassUtils.isCglibProxyClass(object.getClass())));
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public abstract class AopUtils {
|
||||
* @param object the object to check
|
||||
* @see java.lang.reflect.Proxy#isProxyClass
|
||||
*/
|
||||
public static boolean isJdkDynamicProxy(Object object) {
|
||||
public static boolean isJdkDynamicProxy(@Nullable Object object) {
|
||||
return (object instanceof SpringProxy && Proxy.isProxyClass(object.getClass()));
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public abstract class AopUtils {
|
||||
* @param object the object to check
|
||||
* @see ClassUtils#isCglibProxy(Object)
|
||||
*/
|
||||
public static boolean isCglibProxy(Object object) {
|
||||
public static boolean isCglibProxy(@Nullable Object object) {
|
||||
return (object instanceof SpringProxy && ClassUtils.isCglibProxy(object));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,6 @@ import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Convenient class for building up pointcuts. All methods return
|
||||
@@ -188,21 +187,14 @@ public class ComposablePointcut implements Pointcut, Serializable {
|
||||
if (!(other instanceof ComposablePointcut)) {
|
||||
return false;
|
||||
}
|
||||
ComposablePointcut that = (ComposablePointcut) other;
|
||||
return ObjectUtils.nullSafeEquals(that.classFilter, this.classFilter) &&
|
||||
ObjectUtils.nullSafeEquals(that.methodMatcher, this.methodMatcher);
|
||||
ComposablePointcut otherPointcut = (ComposablePointcut) other;
|
||||
return (this.classFilter.equals(otherPointcut.classFilter) &&
|
||||
this.methodMatcher.equals(otherPointcut.methodMatcher));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = 17;
|
||||
if (this.classFilter != null) {
|
||||
code = 37 * code + this.classFilter.hashCode();
|
||||
}
|
||||
if (this.methodMatcher != null) {
|
||||
code = 37 * code + this.methodMatcher.hashCode();
|
||||
}
|
||||
return code;
|
||||
return this.classFilter.hashCode() * 37 + this.methodMatcher.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,6 +40,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
|
||||
|
||||
private Class<?> clazz;
|
||||
|
||||
@Nullable
|
||||
private String methodName;
|
||||
|
||||
private volatile int evaluations;
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
|
||||
/**
|
||||
@@ -105,12 +104,12 @@ public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut impleme
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return (this == other || (other instanceof NameMatchMethodPointcut &&
|
||||
ObjectUtils.nullSafeEquals(this.mappedNames, ((NameMatchMethodPointcut) other).mappedNames)));
|
||||
this.mappedNames.equals(((NameMatchMethodPointcut) other).mappedNames)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.mappedNames != null ? this.mappedNames.hashCode() : 0);
|
||||
return this.mappedNames.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.io.Serializable;
|
||||
import org.aopalliance.aop.Advice;
|
||||
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -44,8 +45,10 @@ import org.springframework.util.ObjectUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class RegexpMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor {
|
||||
|
||||
@Nullable
|
||||
private String[] patterns;
|
||||
|
||||
@Nullable
|
||||
private AbstractRegexpMethodPointcut pointcut;
|
||||
|
||||
private final Object pointcutMonitor = new SerializableMonitor();
|
||||
@@ -121,7 +124,9 @@ public class RegexpMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor
|
||||
synchronized (this.pointcutMonitor) {
|
||||
if (this.pointcut == null) {
|
||||
this.pointcut = createPointcut();
|
||||
this.pointcut.setPatterns(this.patterns);
|
||||
if (this.patterns != null) {
|
||||
this.pointcut.setPatterns(this.patterns);
|
||||
}
|
||||
}
|
||||
return pointcut;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Simple Pointcut that looks for a specific Java 5 annotation
|
||||
@@ -127,21 +126,14 @@ public class AnnotationMatchingPointcut implements Pointcut {
|
||||
if (!(other instanceof AnnotationMatchingPointcut)) {
|
||||
return false;
|
||||
}
|
||||
AnnotationMatchingPointcut that = (AnnotationMatchingPointcut) other;
|
||||
return ObjectUtils.nullSafeEquals(that.classFilter, this.classFilter) &&
|
||||
ObjectUtils.nullSafeEquals(that.methodMatcher, this.methodMatcher);
|
||||
AnnotationMatchingPointcut otherPointcut = (AnnotationMatchingPointcut) other;
|
||||
return (this.classFilter.equals(otherPointcut.classFilter) &&
|
||||
this.methodMatcher.equals(otherPointcut.methodMatcher));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = 17;
|
||||
if (this.classFilter != null) {
|
||||
code = 37 * code + this.classFilter.hashCode();
|
||||
}
|
||||
if (this.methodMatcher != null) {
|
||||
code = 37 * code + this.methodMatcher.hashCode();
|
||||
}
|
||||
return code;
|
||||
return this.classFilter.hashCode() * 37 + this.methodMatcher.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user