Nullability fine-tuning around declaration inconsistencies
Issue: SPR-15720 Issue: SPR-15792
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ public abstract class AbstractExpressionPointcut implements ExpressionPointcut,
|
||||
* Return this pointcut's expression.
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public String getExpression() {
|
||||
return this.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.
|
||||
@@ -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;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user