Browse Source

Merge branch '6.0.x'

pull/30624/head
Juergen Hoeller 1 year ago
parent
commit
ef2b47e202
  1. 7
      spring-aop/src/main/java/org/springframework/aop/Advisor.java
  2. 5
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java
  3. 7
      spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java
  4. 87
      spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java
  5. 87
      spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java
  6. 7
      spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java
  7. 8
      spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java
  8. 4
      spring-aop/src/main/java/org/springframework/aop/framework/ProxyCreatorSupport.java
  9. 7
      spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java
  10. 18
      spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java
  11. 13
      spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java
  12. 13
      spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java
  13. 12
      spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java
  14. 17
      spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java
  15. 20
      spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java
  16. 7
      spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcherPointcutAdvisor.java
  17. 12
      spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java
  18. 22
      spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java
  19. 19
      spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java
  20. 55
      spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/BeanFactoryJCacheOperationSourceAdvisor.java
  21. 4
      spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSourcePointcut.java
  22. 13
      spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java
  23. 20
      spring-context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java
  24. 38
      spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java
  25. 12
      spring-context/src/main/java/org/springframework/cache/interceptor/NameMatchCacheOperationSource.java
  26. 37
      spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java
  27. 13
      spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java
  28. 16
      spring-tx/src/main/java/org/springframework/transaction/interceptor/BeanFactoryTransactionAttributeSourceAdvisor.java
  29. 11
      spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java
  30. 11
      spring-tx/src/main/java/org/springframework/transaction/interceptor/NameMatchTransactionAttributeSource.java
  31. 12
      spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourceAdvisor.java
  32. 38
      spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java

7
spring-aop/src/main/java/org/springframework/aop/Advisor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2023 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.
@ -62,8 +62,11 @@ public interface Advisor { @@ -62,8 +62,11 @@ public interface Advisor {
* Typical Advisor implementations always return {@code true}.
* Use singleton/prototype bean definitions or appropriate programmatic
* proxy creation to ensure that Advisors have the correct lifecycle model.
* <p>As of 6.0.10, the default implementation returns {@code true}.
* @return whether this advice is associated with a particular target instance
*/
boolean isPerInstance();
default boolean isPerInstance() {
return true;
}
}

5
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java

@ -67,11 +67,6 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered { @@ -67,11 +67,6 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
}
}
@Override
public boolean isPerInstance() {
return true;
}
@Override
public Advice getAdvice() {
return this.advice;

7
spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -91,11 +91,6 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor { @@ -91,11 +91,6 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
// Do nothing
}
@Override
public boolean isPerInstance() {
return true;
}
@Override
public Advice getAdvice() {
return this.advice;

87
spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.lang.reflect.Method; @@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -32,6 +33,8 @@ import org.springframework.aop.Advisor; @@ -32,6 +33,8 @@ import org.springframework.aop.Advisor;
import org.springframework.aop.DynamicIntroductionAdvice;
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.IntroductionInfo;
import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
@ -41,6 +44,7 @@ import org.springframework.lang.Nullable; @@ -41,6 +44,7 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
/**
* Base class for AOP proxy configuration managers.
@ -72,15 +76,13 @@ public class AdvisedSupport extends ProxyConfig implements Advised { @@ -72,15 +76,13 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
/** Package-protected to allow direct access for efficiency. */
@SuppressWarnings("serial")
TargetSource targetSource = EMPTY_TARGET_SOURCE;
/** Whether the Advisors are already filtered for the specific target class. */
private boolean preFiltered = false;
/** The AdvisorChainFactory to use. */
@SuppressWarnings("serial")
AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
private AdvisorChainFactory advisorChainFactory;
/** Cache with Method as key and advisor chain List as value. */
private transient Map<MethodCacheKey, List<Object>> methodCache;
@ -89,21 +91,22 @@ public class AdvisedSupport extends ProxyConfig implements Advised { @@ -89,21 +91,22 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
* Interfaces to be implemented by the proxy. Held in List to keep the order
* of registration, to create JDK proxy with specified order of interfaces.
*/
@SuppressWarnings("serial")
private List<Class<?>> interfaces = new ArrayList<>();
/**
* List of Advisors. If an Advice is added, it will be wrapped
* in an Advisor before being added to this List.
*/
@SuppressWarnings("serial")
private List<Advisor> advisors = new ArrayList<>();
private List<Advisor> advisorKey = this.advisors;
/**
* No-arg constructor for use as a JavaBean.
*/
public AdvisedSupport() {
this.advisorChainFactory = DefaultAdvisorChainFactory.INSTANCE;
this.methodCache = new ConcurrentHashMap<>(32);
}
@ -116,6 +119,15 @@ public class AdvisedSupport extends ProxyConfig implements Advised { @@ -116,6 +119,15 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
setInterfaces(interfaces);
}
/**
* Internal constructor for {@link #getConfigurationOnlyCopy()}.
* @since 6.0.10
*/
private AdvisedSupport(AdvisorChainFactory advisorChainFactory, Map<MethodCacheKey, List<Object>> methodCache) {
this.advisorChainFactory = advisorChainFactory;
this.methodCache = methodCache;
}
/**
* Set the given object as target.
@ -520,15 +532,27 @@ public class AdvisedSupport extends ProxyConfig implements Advised { @@ -520,15 +532,27 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
* replacing the TargetSource.
*/
AdvisedSupport getConfigurationOnlyCopy() {
AdvisedSupport copy = new AdvisedSupport();
AdvisedSupport copy = new AdvisedSupport(this.advisorChainFactory, this.methodCache);
copy.copyFrom(this);
copy.targetSource = EmptyTargetSource.forClass(getTargetClass(), getTargetSource().isStatic());
copy.advisorChainFactory = this.advisorChainFactory;
copy.interfaces = new ArrayList<>(this.interfaces);
copy.advisors = new ArrayList<>(this.advisors);
copy.advisorKey = new ArrayList<>(this.advisors.size());
for (Advisor advisor : this.advisors) {
copy.advisorKey.add(new AdvisorKeyEntry(advisor));
}
return copy;
}
void reduceToAdvisorKey() {
this.advisors = this.advisorKey;
this.methodCache = Collections.emptyMap();
}
Object getAdvisorKey() {
return this.advisorKey;
}
//---------------------------------------------------------------------
// Serialization support
@ -604,4 +628,51 @@ public class AdvisedSupport extends ProxyConfig implements Advised { @@ -604,4 +628,51 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
}
}
/**
* Stub for an Advisor instance that is just needed for key purposes,
* allowing for efficient equals and hashCode comparisons against the
* advice class and the pointcut.
* @since 6.0.10
* @see #getConfigurationOnlyCopy()
* @see #getAdvisorKey()
*/
private static class AdvisorKeyEntry implements Advisor {
private final Class<?> adviceType;
@Nullable
private String classFilterKey;
@Nullable
private String methodMatcherKey;
public AdvisorKeyEntry(Advisor advisor) {
this.adviceType = advisor.getAdvice().getClass();
if (advisor instanceof PointcutAdvisor pointcutAdvisor) {
Pointcut pointcut = pointcutAdvisor.getPointcut();
this.classFilterKey = ObjectUtils.identityToString(pointcut.getClassFilter());
this.methodMatcherKey = ObjectUtils.identityToString(pointcut.getMethodMatcher());
}
}
@Override
public Advice getAdvice() {
throw new UnsupportedOperationException();
}
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof AdvisorKeyEntry otherEntry &&
this.adviceType == otherEntry.adviceType &&
ObjectUtils.nullSafeEquals(this.classFilterKey, otherEntry.classFilterKey) &&
ObjectUtils.nullSafeEquals(this.methodMatcherKey, otherEntry.methodMatcherKey)));
}
@Override
public int hashCode() {
return this.adviceType.hashCode();
}
}
}

87
spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

@ -26,14 +26,11 @@ import java.util.Map; @@ -26,14 +26,11 @@ import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.AopInvocationException;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.RawTargetAccess;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
@ -205,12 +202,21 @@ class CglibAopProxy implements AopProxy, Serializable { @@ -205,12 +202,21 @@ class CglibAopProxy implements AopProxy, Serializable {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
ProxyCallbackFilter filter = new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset);
enhancer.setCallbackFilter(filter);
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return (classOnly ? createProxyClass(enhancer) : createProxyClassAndInstance(enhancer, callbacks));
// ProxyCallbackFilter has method introspection capability with Advisor access.
try {
return (classOnly ? createProxyClass(enhancer) : createProxyClassAndInstance(enhancer, callbacks));
}
finally {
// Reduce ProxyCallbackFilter to key-only state for its class cache role
// in the CGLIB$CALLBACK_FILTER field, not leaking any Advisor state...
filter.advised.reduceToAdvisorKey();
}
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
@ -294,9 +300,9 @@ class CglibAopProxy implements AopProxy, Serializable { @@ -294,9 +300,9 @@ class CglibAopProxy implements AopProxy, Serializable {
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
boolean isFrozen = this.advised.isFrozen();
boolean exposeProxy = this.advised.isExposeProxy();
// Choose an "aop" interceptor (used for AOP calls).
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
@ -776,7 +782,7 @@ class CglibAopProxy implements AopProxy, Serializable { @@ -776,7 +782,7 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
private static class ProxyCallbackFilter implements CallbackFilter {
private final AdvisedSupport advised;
final AdvisedSupport advised;
private final Map<Method, Integer> fixedInterceptorMap;
@ -857,9 +863,9 @@ class CglibAopProxy implements AopProxy, Serializable { @@ -857,9 +863,9 @@ class CglibAopProxy implements AopProxy, Serializable {
// Proxy is not yet available, but that shouldn't matter.
List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
boolean haveAdvice = !chain.isEmpty();
boolean exposeProxy = this.advised.isExposeProxy();
boolean isStatic = this.advised.getTargetSource().isStatic();
boolean isFrozen = this.advised.isFrozen();
boolean exposeProxy = this.advised.isExposeProxy();
if (haveAdvice || !isFrozen) {
// If exposing the proxy, then AOP_PROXY must be used.
if (exposeProxy) {
@ -921,63 +927,18 @@ class CglibAopProxy implements AopProxy, Serializable { @@ -921,63 +927,18 @@ class CglibAopProxy implements AopProxy, Serializable {
return false;
}
AdvisedSupport otherAdvised = otherCallbackFilter.advised;
if (this.advised.isFrozen() != otherAdvised.isFrozen()) {
return false;
}
if (this.advised.isExposeProxy() != otherAdvised.isExposeProxy()) {
return false;
}
if (this.advised.getTargetSource().isStatic() != otherAdvised.getTargetSource().isStatic()) {
return false;
}
if (!AopProxyUtils.equalsProxiedInterfaces(this.advised, otherAdvised)) {
return false;
}
// Advice instance identity is unimportant to the proxy class:
// All that matters is type and ordering.
if (this.advised.getAdvisorCount() != otherAdvised.getAdvisorCount()) {
return false;
}
Advisor[] thisAdvisors = this.advised.getAdvisors();
Advisor[] thatAdvisors = otherAdvised.getAdvisors();
for (int i = 0; i < thisAdvisors.length; i++) {
Advisor thisAdvisor = thisAdvisors[i];
Advisor thatAdvisor = thatAdvisors[i];
if (!equalsAdviceClasses(thisAdvisor, thatAdvisor)) {
return false;
}
if (!equalsPointcuts(thisAdvisor, thatAdvisor)) {
return false;
}
}
return true;
}
private static boolean equalsAdviceClasses(Advisor a, Advisor b) {
return (a.getAdvice().getClass() == b.getAdvice().getClass());
}
private static boolean equalsPointcuts(Advisor a, Advisor b) {
// If only one of the advisor (but not both) is PointcutAdvisor, then it is a mismatch.
// Takes care of the situations where an IntroductionAdvisor is used (see SPR-3959).
return (!(a instanceof PointcutAdvisor pointcutAdvisor1) ||
(b instanceof PointcutAdvisor pointcutAdvisor2 &&
ObjectUtils.nullSafeEquals(pointcutAdvisor1.getPointcut(), pointcutAdvisor2.getPointcut())));
return (this.advised.getAdvisorKey().equals(otherAdvised.getAdvisorKey()) &&
AopProxyUtils.equalsProxiedInterfaces(this.advised, otherAdvised) &&
ObjectUtils.nullSafeEquals(this.advised.getTargetClass(), otherAdvised.getTargetClass()) &&
this.advised.getTargetSource().isStatic() == otherAdvised.getTargetSource().isStatic() &&
this.advised.isFrozen() == otherAdvised.isFrozen() &&
this.advised.isExposeProxy() == otherAdvised.isExposeProxy() &&
this.advised.isOpaque() == otherAdvised.isOpaque());
}
@Override
public int hashCode() {
int hashCode = 0;
Advisor[] advisors = this.advised.getAdvisors();
for (Advisor advisor : advisors) {
Advice advice = advisor.getAdvice();
hashCode = 13 * hashCode + advice.getClass().hashCode();
}
hashCode = 13 * hashCode + (this.advised.isFrozen() ? 1 : 0);
hashCode = 13 * hashCode + (this.advised.isExposeProxy() ? 1 : 0);
hashCode = 13 * hashCode + (this.advised.isOptimize() ? 1 : 0);
hashCode = 13 * hashCode + (this.advised.isOpaque() ? 1 : 0);
return hashCode;
return this.advised.getAdvisorKey().hashCode();
}
}

7
spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java

@ -47,6 +47,13 @@ import org.springframework.lang.Nullable; @@ -47,6 +47,13 @@ import org.springframework.lang.Nullable;
@SuppressWarnings("serial")
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
/**
* Singleton instance of this class.
* @since 6.0.10
*/
public static final DefaultAdvisorChainFactory INSTANCE = new DefaultAdvisorChainFactory();
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {

8
spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -48,6 +48,12 @@ import org.springframework.util.ClassUtils; @@ -48,6 +48,12 @@ import org.springframework.util.ClassUtils;
*/
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
/**
* Singleton instance of this class.
* @since 6.0.10
*/
public static final DefaultAopProxyFactory INSTANCE = new DefaultAopProxyFactory();
private static final long serialVersionUID = 7930414337282325166L;

4
spring-aop/src/main/java/org/springframework/aop/framework/ProxyCreatorSupport.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -44,7 +44,7 @@ public class ProxyCreatorSupport extends AdvisedSupport { @@ -44,7 +44,7 @@ public class ProxyCreatorSupport extends AdvisedSupport {
* Create a new ProxyCreatorSupport instance.
*/
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
this.aopProxyFactory = DefaultAopProxyFactory.INSTANCE;
}
/**

7
spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -606,11 +606,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -606,11 +606,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
}
@Override
public boolean isPerInstance() {
throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
}
@Override
public String toString() {
return this.message;

18
spring-aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -58,22 +58,12 @@ public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordere @@ -58,22 +58,12 @@ public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordere
return Ordered.LOWEST_PRECEDENCE;
}
@Override
public boolean isPerInstance() {
return true;
}
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof PointcutAdvisor otherAdvisor)) {
return false;
}
return (ObjectUtils.nullSafeEquals(getAdvice(), otherAdvisor.getAdvice()) &&
ObjectUtils.nullSafeEquals(getPointcut(), otherAdvisor.getPointcut()));
return (this == other || (other instanceof PointcutAdvisor otherAdvisor &&
ObjectUtils.nullSafeEquals(getAdvice(), otherAdvisor.getAdvice()) &&
ObjectUtils.nullSafeEquals(getPointcut(), otherAdvisor.getPointcut())));
}
@Override

13
spring-aop/src/main/java/org/springframework/aop/support/AbstractRegexpMethodPointcut.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -196,14 +196,9 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo @@ -196,14 +196,9 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AbstractRegexpMethodPointcut otherPointcut)) {
return false;
}
return (Arrays.equals(this.patterns, otherPointcut.patterns) &&
Arrays.equals(this.excludedPatterns, otherPointcut.excludedPatterns));
return (this == other || (other instanceof AbstractRegexpMethodPointcut otherPointcut &&
Arrays.equals(this.patterns, otherPointcut.patterns) &&
Arrays.equals(this.excludedPatterns, otherPointcut.excludedPatterns)));
}
@Override

13
spring-aop/src/main/java/org/springframework/aop/support/ComposablePointcut.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -187,14 +187,9 @@ public class ComposablePointcut implements Pointcut, Serializable { @@ -187,14 +187,9 @@ public class ComposablePointcut implements Pointcut, Serializable {
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof ComposablePointcut otherPointcut)) {
return false;
}
return (this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher));
return (this == other || (other instanceof ComposablePointcut otherPointcut &&
this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher)));
}
@Override

12
spring-aop/src/main/java/org/springframework/aop/support/ControlFlowPointcut.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -125,13 +125,9 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher @@ -125,13 +125,9 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof ControlFlowPointcut that)) {
return false;
}
return (this.clazz.equals(that.clazz)) && ObjectUtils.nullSafeEquals(this.methodName, that.methodName);
return (this == other || (other instanceof ControlFlowPointcut that &&
this.clazz.equals(that.clazz)) &&
ObjectUtils.nullSafeEquals(this.methodName, that.methodName));
}
@Override

17
spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -134,11 +134,6 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil @@ -134,11 +134,6 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
return this.advice;
}
@Override
public boolean isPerInstance() {
return true;
}
@Override
public ClassFilter getClassFilter() {
return this;
@ -152,13 +147,9 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil @@ -152,13 +147,9 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof DefaultIntroductionAdvisor otherAdvisor)) {
return false;
}
return (this.advice.equals(otherAdvisor.advice) && this.interfaces.equals(otherAdvisor.interfaces));
return (this == other || (other instanceof DefaultIntroductionAdvisor otherAdvisor &&
this.advice.equals(otherAdvisor.advice) &&
this.interfaces.equals(otherAdvisor.interfaces)));
}
@Override

20
spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -143,13 +143,8 @@ public abstract class MethodMatchers { @@ -143,13 +143,8 @@ public abstract class MethodMatchers {
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof UnionMethodMatcher that)) {
return false;
}
return (this.mm1.equals(that.mm1) && this.mm2.equals(that.mm2));
return (this == other || (other instanceof UnionMethodMatcher that &&
this.mm1.equals(that.mm1) && this.mm2.equals(that.mm2)));
}
@Override
@ -307,13 +302,8 @@ public abstract class MethodMatchers { @@ -307,13 +302,8 @@ public abstract class MethodMatchers {
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof IntersectionMethodMatcher that)) {
return false;
}
return (this.mm1.equals(that.mm1) && this.mm2.equals(that.mm2));
return (this == other || (other instanceof IntersectionMethodMatcher that &&
this.mm1.equals(that.mm1) && this.mm2.equals(that.mm2)));
}
@Override

7
spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcherPointcutAdvisor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -77,11 +77,6 @@ public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMat @@ -77,11 +77,6 @@ public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMat
return this.advice;
}
@Override
public boolean isPerInstance() {
return true;
}
@Override
public Pointcut getPointcut() {
return this;

12
spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationClassFilter.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -68,13 +68,9 @@ public class AnnotationClassFilter implements ClassFilter { @@ -68,13 +68,9 @@ public class AnnotationClassFilter implements ClassFilter {
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationClassFilter otherCf)) {
return false;
}
return (this.annotationType.equals(otherCf.annotationType) && this.checkInherited == otherCf.checkInherited);
return (this == other || (other instanceof AnnotationClassFilter otherCf &&
this.annotationType.equals(otherCf.annotationType) &&
this.checkInherited == otherCf.checkInherited));
}
@Override

22
spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMatchingPointcut.java

@ -121,14 +121,9 @@ public class AnnotationMatchingPointcut implements Pointcut { @@ -121,14 +121,9 @@ public class AnnotationMatchingPointcut implements Pointcut {
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationMatchingPointcut otherPointcut)) {
return false;
}
return (this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher));
return (this == other || (other instanceof AnnotationMatchingPointcut otherPointcut &&
this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher)));
}
@Override
@ -183,14 +178,9 @@ public class AnnotationMatchingPointcut implements Pointcut { @@ -183,14 +178,9 @@ public class AnnotationMatchingPointcut implements Pointcut {
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof AnnotationCandidateClassFilter that)) {
return false;
}
return this.annotationType.equals(that.annotationType);
public boolean equals(@Nullable Object other) {
return (this == other || (other instanceof AnnotationCandidateClassFilter that &&
this.annotationType.equals(that.annotationType)));
}
@Override

19
spring-aop/src/main/java/org/springframework/aop/support/annotation/AnnotationMethodMatcher.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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,10 +27,9 @@ import org.springframework.lang.Nullable; @@ -27,10 +27,9 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Simple {@link org.springframework.aop.MethodMatcher MethodMatcher} that looks
* for a specific annotation being present on a method (checking both the method
* on the invoked interface, if any, and the corresponding method on the target
* class).
* Simple {@link org.springframework.aop.MethodMatcher MethodMatcher} that looks for
* a specific annotation being present on a method (checking both the method on the
* invoked interface, if any, and the corresponding method on the target class).
*
* @author Juergen Hoeller
* @author Sam Brannen
@ -90,13 +89,9 @@ public class AnnotationMethodMatcher extends StaticMethodMatcher { @@ -90,13 +89,9 @@ public class AnnotationMethodMatcher extends StaticMethodMatcher {
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationMethodMatcher otherMm)) {
return false;
}
return (this.annotationType.equals(otherMm.annotationType) && this.checkInherited == otherMm.checkInherited);
return (this == other || (other instanceof AnnotationMethodMatcher otherMm &&
this.annotationType.equals(otherMm.annotationType) &&
this.checkInherited == otherMm.checkInherited));
}
@Override

55
spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/BeanFactoryJCacheOperationSourceAdvisor.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,30 +16,30 @@ @@ -16,30 +16,30 @@
package org.springframework.cache.jcache.interceptor;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
* Advisor driven by a {@link JCacheOperationSource}, used to include a
* cache advice bean for methods that are cacheable.
*
* @author Stephane Nicoll
* @author Juergen Hoeller
* @since 4.1
* @see #setAdviceBeanName
* @see JCacheInterceptor
*/
@SuppressWarnings("serial")
public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private JCacheOperationSource cacheOperationSource;
private final JCacheOperationSourcePointcut pointcut = new JCacheOperationSourcePointcut() {
@Override
protected JCacheOperationSource getCacheOperationSource() {
return cacheOperationSource;
}
};
private final JCacheOperationSourcePointcut pointcut = new JCacheOperationSourcePointcut();
/**
@ -48,7 +48,7 @@ public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactory @@ -48,7 +48,7 @@ public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactory
* set on the cache interceptor itself.
*/
public void setCacheOperationSource(JCacheOperationSource cacheOperationSource) {
this.cacheOperationSource = cacheOperationSource;
this.pointcut.setCacheOperationSource(cacheOperationSource);
}
/**
@ -64,4 +64,37 @@ public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactory @@ -64,4 +64,37 @@ public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactory
return this.pointcut;
}
private static class JCacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@Nullable
private JCacheOperationSource cacheOperationSource;
public void setCacheOperationSource(@Nullable JCacheOperationSource cacheOperationSource) {
this.cacheOperationSource = cacheOperationSource;
}
@Override
public boolean matches(Method method, Class<?> targetClass) {
return (this.cacheOperationSource == null ||
this.cacheOperationSource.getCacheOperation(method, targetClass) != null);
}
@Override
public boolean equals(@Nullable Object other) {
return (this == other || (other instanceof JCacheOperationSourcePointcut otherPc &&
ObjectUtils.nullSafeEquals(this.cacheOperationSource, otherPc.cacheOperationSource)));
}
@Override
public int hashCode() {
return JCacheOperationSourcePointcut.class.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + this.cacheOperationSource;
}
}
}

4
spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheOperationSourcePointcut.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,7 +29,9 @@ import org.springframework.util.ObjectUtils; @@ -29,7 +29,9 @@ import org.springframework.util.ObjectUtils;
*
* @author Stephane Nicoll
* @since 4.1
* @deprecated since 6.0.10, as it is not used by the framework anymore
*/
@Deprecated(since = "6.0.10", forRemoval = true)
@SuppressWarnings("serial")
public abstract class JCacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

13
spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
@ -165,14 +165,9 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati @@ -165,14 +165,9 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationCacheOperationSource otherCos)) {
return false;
}
return (this.annotationParsers.equals(otherCos.annotationParsers) &&
this.publicMethodsOnly == otherCos.publicMethodsOnly);
return (this == other || (other instanceof AnnotationCacheOperationSource otherCos &&
this.annotationParsers.equals(otherCos.annotationParsers) &&
this.publicMethodsOnly == otherCos.publicMethodsOnly));
}
@Override

20
spring-context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2023 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,37 +19,31 @@ package org.springframework.cache.interceptor; @@ -19,37 +19,31 @@ package org.springframework.cache.interceptor;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
import org.springframework.lang.Nullable;
/**
* Advisor driven by a {@link CacheOperationSource}, used to include a
* cache advice bean for methods that are cacheable.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
* @see #setAdviceBeanName
* @see CacheInterceptor
*/
@SuppressWarnings("serial")
public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private CacheOperationSource cacheOperationSource;
private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
@Override
@Nullable
protected CacheOperationSource getCacheOperationSource() {
return cacheOperationSource;
}
};
private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut();
/**
* Set the cache operation attribute source which is used to find cache
* attributes. This should usually be identical to the source reference
* set on the cache interceptor itself.
* @see CacheInterceptor#setCacheOperationSource
*/
public void setCacheOperationSource(CacheOperationSource cacheOperationSource) {
this.cacheOperationSource = cacheOperationSource;
this.pointcut.setCacheOperationSource(cacheOperationSource);
}
/**

38
spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java vendored

@ -35,28 +35,31 @@ import org.springframework.util.ObjectUtils; @@ -35,28 +35,31 @@ import org.springframework.util.ObjectUtils;
* @since 3.1
*/
@SuppressWarnings("serial")
abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
protected CacheOperationSourcePointcut() {
@Nullable
private CacheOperationSource cacheOperationSource;
public CacheOperationSourcePointcut() {
setClassFilter(new CacheOperationSourceClassFilter());
}
public void setCacheOperationSource(@Nullable CacheOperationSource cacheOperationSource) {
this.cacheOperationSource = cacheOperationSource;
}
@Override
public boolean matches(Method method, Class<?> targetClass) {
CacheOperationSource cas = getCacheOperationSource();
return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass)));
return (this.cacheOperationSource == null ||
!CollectionUtils.isEmpty(this.cacheOperationSource.getCacheOperations(method, targetClass)));
}
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof CacheOperationSourcePointcut otherPc)) {
return false;
}
return ObjectUtils.nullSafeEquals(getCacheOperationSource(), otherPc.getCacheOperationSource());
return (this == other || (other instanceof CacheOperationSourcePointcut otherPc &&
ObjectUtils.nullSafeEquals(this.cacheOperationSource, otherPc.cacheOperationSource)));
}
@Override
@ -66,18 +69,10 @@ abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut @@ -66,18 +69,10 @@ abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut
@Override
public String toString() {
return getClass().getName() + ": " + getCacheOperationSource();
return getClass().getName() + ": " + this.cacheOperationSource;
}
/**
* Obtain the underlying {@link CacheOperationSource} (may be {@code null}).
* To be implemented by subclasses.
*/
@Nullable
protected abstract CacheOperationSource getCacheOperationSource();
/**
* {@link ClassFilter} that delegates to {@link CacheOperationSource#isCandidateClass}
* for filtering classes whose methods are not worth searching to begin with.
@ -89,8 +84,7 @@ abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut @@ -89,8 +84,7 @@ abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut
if (CacheManager.class.isAssignableFrom(clazz)) {
return false;
}
CacheOperationSource cas = getCacheOperationSource();
return (cas == null || cas.isCandidateClass(clazz));
return (cacheOperationSource == null || cacheOperationSource.isCandidateClass(clazz));
}
}

12
spring-context/src/main/java/org/springframework/cache/interceptor/NameMatchCacheOperationSource.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
@ -111,13 +111,8 @@ public class NameMatchCacheOperationSource implements CacheOperationSource, Seri @@ -111,13 +111,8 @@ public class NameMatchCacheOperationSource implements CacheOperationSource, Seri
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof NameMatchCacheOperationSource otherTas)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.nameMap, otherTas.nameMap);
return (this == other || (other instanceof NameMatchCacheOperationSource otherCos &&
ObjectUtils.nullSafeEquals(this.nameMap, otherCos.nameMap)));
}
@Override
@ -129,4 +124,5 @@ public class NameMatchCacheOperationSource implements CacheOperationSource, Seri @@ -129,4 +124,5 @@ public class NameMatchCacheOperationSource implements CacheOperationSource, Seri
public String toString() {
return getClass().getName() + ": " + this.nameMap;
}
}

37
spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java

@ -28,6 +28,7 @@ import org.springframework.aop.MethodMatcher; @@ -28,6 +28,7 @@ import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.aop.testfixture.advice.CountingBeforeAdvice;
import org.springframework.aop.testfixture.interceptor.NopInterceptor;
import org.springframework.beans.testfixture.beans.ITestBean;
@ -35,6 +36,7 @@ import org.springframework.beans.testfixture.beans.TestBean; @@ -35,6 +36,7 @@ import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import static org.assertj.core.api.Assertions.assertThat;
@ -304,6 +306,8 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab @@ -304,6 +306,8 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
CglibAopProxy cglib = new CglibAopProxy(as);
ITestBean proxy1 = (ITestBean) cglib.getProxy();
ITestBean proxy1a = (ITestBean) cglib.getProxy();
assertThat(proxy1a.getClass()).isSameAs(proxy1.getClass());
mockTargetSource.setTarget(proxy1);
as = new AdvisedSupport(new Class<?>[]{});
@ -313,6 +317,39 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab @@ -313,6 +317,39 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
ITestBean proxy2 = (ITestBean) cglib.getProxy();
assertThat(proxy2).isInstanceOf(Serializable.class);
assertThat(proxy2.getClass()).isNotSameAs(proxy1.getClass());
ITestBean proxy2a = (ITestBean) cglib.getProxy();
assertThat(proxy2a).isInstanceOf(Serializable.class);
assertThat(proxy2a.getClass()).isSameAs(proxy2.getClass());
mockTargetSource.setTarget(proxy1);
as = new AdvisedSupport(new Class<?>[]{});
as.setTargetSource(mockTargetSource);
as.addAdvisor(new DefaultPointcutAdvisor(new AnnotationMatchingPointcut(Nullable.class), new NopInterceptor()));
cglib = new CglibAopProxy(as);
ITestBean proxy3 = (ITestBean) cglib.getProxy();
assertThat(proxy3).isInstanceOf(Serializable.class);
assertThat(proxy3.getClass()).isNotSameAs(proxy2.getClass());
ITestBean proxy3a = (ITestBean) cglib.getProxy();
assertThat(proxy3a).isInstanceOf(Serializable.class);
assertThat(proxy3a.getClass()).isSameAs(proxy3.getClass());
mockTargetSource.setTarget(proxy1);
as = new AdvisedSupport(new Class<?>[]{});
as.setTargetSource(mockTargetSource);
as.addAdvisor(new DefaultPointcutAdvisor(new AnnotationMatchingPointcut(NonNull.class), new NopInterceptor()));
cglib = new CglibAopProxy(as);
ITestBean proxy4 = (ITestBean) cglib.getProxy();
assertThat(proxy4).isInstanceOf(Serializable.class);
assertThat(proxy4.getClass()).isNotSameAs(proxy3.getClass());
ITestBean proxy4a = (ITestBean) cglib.getProxy();
assertThat(proxy4a).isInstanceOf(Serializable.class);
assertThat(proxy4a.getClass()).isSameAs(proxy4.getClass());
}
@Test

13
spring-tx/src/main/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
@ -191,14 +191,9 @@ public class AnnotationTransactionAttributeSource extends AbstractFallbackTransa @@ -191,14 +191,9 @@ public class AnnotationTransactionAttributeSource extends AbstractFallbackTransa
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AnnotationTransactionAttributeSource otherTas)) {
return false;
}
return (this.annotationParsers.equals(otherTas.annotationParsers) &&
this.publicMethodsOnly == otherTas.publicMethodsOnly);
return (this == other || (other instanceof AnnotationTransactionAttributeSource otherTas &&
this.annotationParsers.equals(otherTas.annotationParsers) &&
this.publicMethodsOnly == otherTas.publicMethodsOnly));
}
@Override

16
spring-tx/src/main/java/org/springframework/transaction/interceptor/BeanFactoryTransactionAttributeSourceAdvisor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2023 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,6 @@ package org.springframework.transaction.interceptor; @@ -19,7 +19,6 @@ package org.springframework.transaction.interceptor;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
import org.springframework.lang.Nullable;
/**
* Advisor driven by a {@link TransactionAttributeSource}, used to include
@ -34,16 +33,7 @@ import org.springframework.lang.Nullable; @@ -34,16 +33,7 @@ import org.springframework.lang.Nullable;
@SuppressWarnings("serial")
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private TransactionAttributeSource transactionAttributeSource;
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut();
/**
@ -53,7 +43,7 @@ public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFa @@ -53,7 +43,7 @@ public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFa
* @see TransactionInterceptor#setTransactionAttributeSource
*/
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
this.pointcut.setTransactionAttributeSource(transactionAttributeSource);
}
/**

11
spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
@ -239,13 +239,8 @@ public class MethodMapTransactionAttributeSource @@ -239,13 +239,8 @@ public class MethodMapTransactionAttributeSource
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof MethodMapTransactionAttributeSource otherTas)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.methodMap, otherTas.methodMap);
return (this == other || (other instanceof MethodMapTransactionAttributeSource otherTas &&
ObjectUtils.nullSafeEquals(this.methodMap, otherTas.methodMap)));
}
@Override

11
spring-tx/src/main/java/org/springframework/transaction/interceptor/NameMatchTransactionAttributeSource.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 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.
@ -164,13 +164,8 @@ public class NameMatchTransactionAttributeSource @@ -164,13 +164,8 @@ public class NameMatchTransactionAttributeSource
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof NameMatchTransactionAttributeSource otherTas)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.nameMap, otherTas.nameMap);
return (this == other || (other instanceof NameMatchTransactionAttributeSource otherTas &&
ObjectUtils.nullSafeEquals(this.nameMap, otherTas.nameMap)));
}
@Override

12
spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourceAdvisor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2023 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.
@ -43,13 +43,7 @@ public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor { @@ -43,13 +43,7 @@ public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor {
@Nullable
private TransactionInterceptor transactionInterceptor;
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return (transactionInterceptor != null ? transactionInterceptor.getTransactionAttributeSource() : null);
}
};
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut();
/**
@ -71,7 +65,9 @@ public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor { @@ -71,7 +65,9 @@ public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor {
* Set the transaction interceptor to use for this advisor.
*/
public void setTransactionInterceptor(TransactionInterceptor interceptor) {
Assert.notNull(interceptor, "TransactionInterceptor must not be null");
this.transactionInterceptor = interceptor;
this.pointcut.setTransactionAttributeSource(interceptor.getTransactionAttributeSource());
}
/**

38
spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAttributeSourcePointcut.java

@ -34,28 +34,31 @@ import org.springframework.util.ObjectUtils; @@ -34,28 +34,31 @@ import org.springframework.util.ObjectUtils;
* @since 2.5.5
*/
@SuppressWarnings("serial")
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
protected TransactionAttributeSourcePointcut() {
@Nullable
private TransactionAttributeSource transactionAttributeSource;
public TransactionAttributeSourcePointcut() {
setClassFilter(new TransactionAttributeSourceClassFilter());
}
public void setTransactionAttributeSource(@Nullable TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
@Override
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
return (this.transactionAttributeSource == null ||
this.transactionAttributeSource.getTransactionAttribute(method, targetClass) != null);
}
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof TransactionAttributeSourcePointcut otherPc)) {
return false;
}
return ObjectUtils.nullSafeEquals(getTransactionAttributeSource(), otherPc.getTransactionAttributeSource());
return (this == other || (other instanceof TransactionAttributeSourcePointcut otherPc &&
ObjectUtils.nullSafeEquals(this.transactionAttributeSource, otherPc.transactionAttributeSource)));
}
@Override
@ -65,18 +68,10 @@ abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPoi @@ -65,18 +68,10 @@ abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPoi
@Override
public String toString() {
return getClass().getName() + ": " + getTransactionAttributeSource();
return getClass().getName() + ": " + this.transactionAttributeSource;
}
/**
* Obtain the underlying TransactionAttributeSource (may be {@code null}).
* To be implemented by subclasses.
*/
@Nullable
protected abstract TransactionAttributeSource getTransactionAttributeSource();
/**
* {@link ClassFilter} that delegates to {@link TransactionAttributeSource#isCandidateClass}
* for filtering classes whose methods are not worth searching to begin with.
@ -90,8 +85,7 @@ abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPoi @@ -90,8 +85,7 @@ abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPoi
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.isCandidateClass(clazz));
return (transactionAttributeSource == null || transactionAttributeSource.isCandidateClass(clazz));
}
}

Loading…
Cancel
Save