@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:
Juergen Hoeller
2017-06-30 01:53:45 +02:00
parent c4694c3f5c
commit cc74a2891a
936 changed files with 6090 additions and 2806 deletions

View File

@@ -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++;
}

View File

@@ -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) {

View File

@@ -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());

View File

@@ -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;

View File

@@ -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());

View File

@@ -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;

View File

@@ -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");

View File

@@ -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() {

View File

@@ -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)));
}
/**

View File

@@ -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;
}
/**

View File

@@ -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<>();

View File

@@ -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) {

View File

@@ -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() {

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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;

View File

@@ -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());

View File

@@ -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;

View File

@@ -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));
}
}

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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 +

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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));
}

View File

@@ -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

View File

@@ -40,6 +40,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
private Class<?> clazz;
@Nullable
private String methodName;
private volatile int evaluations;

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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