Skip to content

Commit

Permalink
Redesign inner Pointcut implementations as standalone classes
Browse files Browse the repository at this point in the history
Avoids exposure of implicit Advisor instance state in Pointcut instance.

See gh-30621
  • Loading branch information
jhoeller committed Jun 8, 2023
1 parent 045df81 commit 6931106
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 90 deletions.
@@ -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.
Expand All @@ -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();


/**
Expand All @@ -48,7 +48,7 @@ protected JCacheOperationSource getCacheOperationSource() {
* set on the cache interceptor itself.
*/
public void setCacheOperationSource(JCacheOperationSource cacheOperationSource) {
this.cacheOperationSource = cacheOperationSource;
this.pointcut.setCacheOperationSource(cacheOperationSource);
}

/**
Expand All @@ -64,4 +64,37 @@ public Pointcut getPointcut() {
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;
}
}

}
@@ -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.
Expand Down Expand Up @@ -29,7 +29,9 @@
*
* @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 {

Expand Down
@@ -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.
Expand All @@ -19,37 +19,31 @@
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);
}

/**
Expand Down
Expand Up @@ -35,28 +35,31 @@
* @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
Expand All @@ -66,18 +69,10 @@ public int hashCode() {

@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.
Expand All @@ -89,8 +84,7 @@ public boolean matches(Class<?> clazz) {
if (CacheManager.class.isAssignableFrom(clazz)) {
return false;
}
CacheOperationSource cas = getCacheOperationSource();
return (cas == null || cas.isCandidateClass(clazz));
return (cacheOperationSource == null || cacheOperationSource.isCandidateClass(clazz));
}
}

Expand Down
@@ -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.
Expand All @@ -19,7 +19,6 @@
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
Expand All @@ -34,16 +33,7 @@
@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();


/**
Expand All @@ -53,7 +43,7 @@ protected TransactionAttributeSource getTransactionAttributeSource() {
* @see TransactionInterceptor#setTransactionAttributeSource
*/
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
this.pointcut.setTransactionAttributeSource(transactionAttributeSource);
}

/**
Expand Down
@@ -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.
Expand Down Expand Up @@ -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();


/**
Expand All @@ -71,7 +65,9 @@ public TransactionAttributeSourceAdvisor(TransactionInterceptor interceptor) {
* 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());
}

/**
Expand Down
Expand Up @@ -34,28 +34,31 @@
* @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
Expand All @@ -65,18 +68,10 @@ public int hashCode() {

@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.
Expand All @@ -90,8 +85,7 @@ public boolean matches(Class<?> clazz) {
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.isCandidateClass(clazz));
return (transactionAttributeSource == null || transactionAttributeSource.isCandidateClass(clazz));
}
}

Expand Down

0 comments on commit 6931106

Please sign in to comment.