Nullability fine-tuning around declaration inconsistencies

Issue: SPR-15720
Issue: SPR-15792
This commit is contained in:
Juergen Hoeller
2017-07-19 22:22:14 +02:00
parent 68e6b148cb
commit 46eba3dbfa
186 changed files with 986 additions and 619 deletions

View File

@@ -31,9 +31,18 @@ import org.aopalliance.aop.Advice;
* implemented using interception.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public interface Advisor {
/**
* Common placeholder for an empty {@code Advice} to be returned from
* {@link #getAdvice()} if no proper advice has been configured (yet).
* @since 5.0
*/
Advice EMPTY_ADVICE = new Advice() {};
/**
* Return the advice part of this aspect. An advice may be an
* interceptor, a before advice, a throws advice, etc.

View File

@@ -23,7 +23,6 @@ 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;
/**
* AspectJPointcutAdvisor that adapts an {@link AbstractAspectJAdvice}
@@ -53,11 +52,11 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
this.pointcut = advice.buildSafePointcut();
}
public void setOrder(int order) {
this.order = order;
}
@Override
public boolean isPerInstance() {
return true;
@@ -93,12 +92,12 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
return false;
}
AspectJPointcutAdvisor otherAdvisor = (AspectJPointcutAdvisor) other;
return (ObjectUtils.nullSafeEquals(this.advice, otherAdvisor.advice));
return this.advice.equals(otherAdvisor.advice);
}
@Override
public int hashCode() {
return AspectJPointcutAdvisor.class.hashCode();
return AspectJPointcutAdvisor.class.hashCode() * 29 + this.advice.hashCode();
}
}

View File

@@ -39,11 +39,11 @@ public class AdvisorComponentDefinition extends AbstractComponentDefinition {
private final BeanDefinition advisorDefinition;
private String description;
private final String description;
private BeanReference[] beanReferences;
private final BeanReference[] beanReferences;
private BeanDefinition[] beanDefinitions;
private final BeanDefinition[] beanDefinitions;
public AdvisorComponentDefinition(String advisorBeanName, BeanDefinition advisorDefinition) {
@@ -57,11 +57,7 @@ public class AdvisorComponentDefinition extends AbstractComponentDefinition {
Assert.notNull(advisorDefinition, "'advisorDefinition' must not be null");
this.advisorBeanName = advisorBeanName;
this.advisorDefinition = advisorDefinition;
unwrapDefinitions(advisorDefinition, pointcutDefinition);
}
private void unwrapDefinitions(BeanDefinition advisorDefinition, @Nullable BeanDefinition pointcutDefinition) {
MutablePropertyValues pvs = advisorDefinition.getPropertyValues();
BeanReference adviceReference = (BeanReference) pvs.get("adviceBeanName");
Assert.state(adviceReference != null, "Missing 'adviceBeanName' property");

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,8 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -34,8 +36,10 @@ import org.springframework.util.StringUtils;
*/
public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstanceFactory, BeanFactoryAware {
@Nullable
private String aspectBeanName;
@Nullable
private BeanFactory beanFactory;
@@ -50,9 +54,7 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
if (!StringUtils.hasText(this.aspectBeanName)) {
throw new IllegalArgumentException("'aspectBeanName' is required");
}
Assert.notNull(this.aspectBeanName, "'aspectBeanName' is required");
}
@@ -62,6 +64,8 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan
*/
@Override
public Object getAspectInstance() {
Assert.state(this.beanFactory != null, "No BeanFactory set");
Assert.state(this.aspectBeanName != null, "No 'aspectBeanName' set");
return this.beanFactory.getBean(this.aspectBeanName);
}
@@ -77,7 +81,8 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan
@Override
public int getOrder() {
if (this.beanFactory.isSingleton(this.aspectBeanName) &&
if (this.beanFactory != null && this.aspectBeanName != null &&
this.beanFactory.isSingleton(this.aspectBeanName) &&
this.beanFactory.isTypeMatch(this.aspectBeanName, Ordered.class)) {
return ((Ordered) this.beanFactory.getBean(this.aspectBeanName)).getOrder();
}

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.
@@ -22,6 +22,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.springframework.aop.Advisor;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.Nullable;
/**
* Base class for {@link BeanPostProcessor} implementations that apply a
@@ -33,6 +34,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
@SuppressWarnings("serial")
public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSupport implements BeanPostProcessor {
@Nullable
protected Advisor advisor;
protected boolean beforeExistingAdvisors = false;
@@ -61,7 +63,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof AopInfrastructureBean) {
if (bean instanceof AopInfrastructureBean || this.advisor == null) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
@@ -125,6 +127,9 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu
if (eligible != null) {
return eligible;
}
if (this.advisor == null) {
return false;
}
eligible = AopUtils.canApply(this.advisor, targetClass);
this.eligibleBeans.put(targetClass, eligible);
return eligible;

View File

@@ -107,7 +107,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
* No-arg constructor for use as a JavaBean.
*/
public AdvisedSupport() {
initMethodCache();
this.methodCache = new ConcurrentHashMap<>(32);
}
/**
@@ -119,13 +119,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
setInterfaces(interfaces);
}
/**
* Initialize the method cache.
*/
private void initMethodCache() {
this.methodCache = new ConcurrentHashMap<>(32);
}
/**
* Set the given object as target.
@@ -558,7 +551,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
ois.defaultReadObject();
// Initialize transient fields.
initMethodCache();
this.methodCache = new ConcurrentHashMap<>(32);
}

View File

@@ -25,6 +25,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Generic auto proxy creator that builds AOP proxies for specific beans
@@ -48,6 +49,7 @@ import org.springframework.lang.Nullable;
@SuppressWarnings("serial")
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@Nullable
private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
@@ -101,6 +103,7 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC
* @return the List of candidate Advisors
*/
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}

View File

@@ -203,7 +203,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
@Override
public void setBeanFactory(@Nullable BeanFactory beanFactory) {
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@@ -241,10 +241,10 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, @Nullable String beanName) throws BeansException {
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
@@ -257,15 +257,15 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
@@ -333,8 +333,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
protected Object wrapIfNecessary(Object bean, @Nullable String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
@@ -391,7 +391,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
* @param beanName the name of the bean
* @return whether to skip the given bean
*/
protected boolean shouldSkip(Class<?> beanClass, @Nullable String beanName) {
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
return false;
}
@@ -582,8 +582,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
* @see #PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
*/
@Nullable
protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass,
@Nullable String beanName, @Nullable TargetSource customTargetSource)
throws BeansException;
protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,
@Nullable TargetSource customTargetSource) throws BeansException;
}

View File

@@ -76,7 +76,9 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
*/
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
if (this.beanNames != null) {
for (String mappedName : this.beanNames) {
if (FactoryBean.class.isAssignableFrom(beanClass)) {

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.
@@ -18,6 +18,7 @@ package org.springframework.aop.framework.autoproxy;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.lang.Nullable;
/**
* Auto-proxy creator that considers infrastructure Advisor beans only,
@@ -29,6 +30,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@SuppressWarnings("serial")
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
@Nullable
private ConfigurableListableBeanFactory beanFactory;
@@ -40,7 +42,7 @@ public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoPr
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
return (this.beanFactory.containsBeanDefinition(beanName) &&
return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
}

View File

@@ -89,6 +89,7 @@ public abstract class AbstractExpressionPointcut implements ExpressionPointcut,
* Return this pointcut's expression.
*/
@Override
@Nullable
public String getExpression() {
return this.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.
@@ -19,7 +19,8 @@ package org.springframework.aop.support;
import org.aopalliance.aop.Advice;
/**
* Abstract generic PointcutAdvisor that allows for any Advice to be configured.
* Abstract generic {@link org.springframework.aop.PointcutAdvisor}
* that allows for any {@link Advice} to be configured.
*
* @author Juergen Hoeller
* @since 2.0
@@ -29,7 +30,7 @@ import org.aopalliance.aop.Advice;
@SuppressWarnings("serial")
public abstract class AbstractGenericPointcutAdvisor extends AbstractPointcutAdvisor {
private Advice advice;
private Advice advice = EMPTY_ADVICE;
/**

View File

@@ -57,6 +57,7 @@ public class DelegatingIntroductionInterceptor extends IntroductionInfoSupport
* Object that actually implements the interfaces.
* May be "this" if a subclass implements the introduced interfaces.
*/
@Nullable
private Object delegate;

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.
@@ -38,7 +38,7 @@ public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMat
private int order = Integer.MAX_VALUE;
private Advice advice;
private Advice advice = EMPTY_ADVICE;
/**