Skip to content

Commit 6931106

Browse files
committed
Redesign inner Pointcut implementations as standalone classes
Avoids exposure of implicit Advisor instance state in Pointcut instance. See gh-30621
1 parent 045df81 commit 6931106

File tree

7 files changed

+93
-90
lines changed

7 files changed

+93
-90
lines changed

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

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,30 +16,30 @@
1616

1717
package org.springframework.cache.jcache.interceptor;
1818

19+
import java.io.Serializable;
20+
import java.lang.reflect.Method;
21+
1922
import org.springframework.aop.ClassFilter;
2023
import org.springframework.aop.Pointcut;
2124
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
25+
import org.springframework.aop.support.StaticMethodMatcherPointcut;
2226
import org.springframework.lang.Nullable;
27+
import org.springframework.util.ObjectUtils;
2328

2429
/**
2530
* Advisor driven by a {@link JCacheOperationSource}, used to include a
2631
* cache advice bean for methods that are cacheable.
2732
*
2833
* @author Stephane Nicoll
34+
* @author Juergen Hoeller
2935
* @since 4.1
36+
* @see #setAdviceBeanName
37+
* @see JCacheInterceptor
3038
*/
3139
@SuppressWarnings("serial")
3240
public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
3341

34-
@Nullable
35-
private JCacheOperationSource cacheOperationSource;
36-
37-
private final JCacheOperationSourcePointcut pointcut = new JCacheOperationSourcePointcut() {
38-
@Override
39-
protected JCacheOperationSource getCacheOperationSource() {
40-
return cacheOperationSource;
41-
}
42-
};
42+
private final JCacheOperationSourcePointcut pointcut = new JCacheOperationSourcePointcut();
4343

4444

4545
/**
@@ -48,7 +48,7 @@ protected JCacheOperationSource getCacheOperationSource() {
4848
* set on the cache interceptor itself.
4949
*/
5050
public void setCacheOperationSource(JCacheOperationSource cacheOperationSource) {
51-
this.cacheOperationSource = cacheOperationSource;
51+
this.pointcut.setCacheOperationSource(cacheOperationSource);
5252
}
5353

5454
/**
@@ -64,4 +64,37 @@ public Pointcut getPointcut() {
6464
return this.pointcut;
6565
}
6666

67+
68+
private static class JCacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
69+
70+
@Nullable
71+
private JCacheOperationSource cacheOperationSource;
72+
73+
public void setCacheOperationSource(@Nullable JCacheOperationSource cacheOperationSource) {
74+
this.cacheOperationSource = cacheOperationSource;
75+
}
76+
77+
@Override
78+
public boolean matches(Method method, Class<?> targetClass) {
79+
return (this.cacheOperationSource == null ||
80+
this.cacheOperationSource.getCacheOperation(method, targetClass) != null);
81+
}
82+
83+
@Override
84+
public boolean equals(@Nullable Object other) {
85+
return (this == other || (other instanceof JCacheOperationSourcePointcut otherPc &&
86+
ObjectUtils.nullSafeEquals(this.cacheOperationSource, otherPc.cacheOperationSource)));
87+
}
88+
89+
@Override
90+
public int hashCode() {
91+
return JCacheOperationSourcePointcut.class.hashCode();
92+
}
93+
94+
@Override
95+
public String toString() {
96+
return getClass().getName() + ": " + this.cacheOperationSource;
97+
}
98+
}
99+
67100
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,7 +29,9 @@
2929
*
3030
* @author Stephane Nicoll
3131
* @since 4.1
32+
* @deprecated since 6.0.10, as it is not used by the framework anymore
3233
*/
34+
@Deprecated(since = "6.0.10", forRemoval = true)
3335
@SuppressWarnings("serial")
3436
public abstract class JCacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
3537

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

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,37 +19,31 @@
1919
import org.springframework.aop.ClassFilter;
2020
import org.springframework.aop.Pointcut;
2121
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
22-
import org.springframework.lang.Nullable;
2322

2423
/**
2524
* Advisor driven by a {@link CacheOperationSource}, used to include a
2625
* cache advice bean for methods that are cacheable.
2726
*
2827
* @author Costin Leau
28+
* @author Juergen Hoeller
2929
* @since 3.1
30+
* @see #setAdviceBeanName
31+
* @see CacheInterceptor
3032
*/
3133
@SuppressWarnings("serial")
3234
public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
3335

34-
@Nullable
35-
private CacheOperationSource cacheOperationSource;
36-
37-
private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
38-
@Override
39-
@Nullable
40-
protected CacheOperationSource getCacheOperationSource() {
41-
return cacheOperationSource;
42-
}
43-
};
36+
private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut();
4437

4538

4639
/**
4740
* Set the cache operation attribute source which is used to find cache
4841
* attributes. This should usually be identical to the source reference
4942
* set on the cache interceptor itself.
43+
* @see CacheInterceptor#setCacheOperationSource
5044
*/
5145
public void setCacheOperationSource(CacheOperationSource cacheOperationSource) {
52-
this.cacheOperationSource = cacheOperationSource;
46+
this.pointcut.setCacheOperationSource(cacheOperationSource);
5347
}
5448

5549
/**

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

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,31 @@
3535
* @since 3.1
3636
*/
3737
@SuppressWarnings("serial")
38-
abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
38+
class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
3939

40-
protected CacheOperationSourcePointcut() {
40+
@Nullable
41+
private CacheOperationSource cacheOperationSource;
42+
43+
44+
public CacheOperationSourcePointcut() {
4145
setClassFilter(new CacheOperationSourceClassFilter());
4246
}
4347

4448

49+
public void setCacheOperationSource(@Nullable CacheOperationSource cacheOperationSource) {
50+
this.cacheOperationSource = cacheOperationSource;
51+
}
52+
4553
@Override
4654
public boolean matches(Method method, Class<?> targetClass) {
47-
CacheOperationSource cas = getCacheOperationSource();
48-
return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass)));
55+
return (this.cacheOperationSource == null ||
56+
!CollectionUtils.isEmpty(this.cacheOperationSource.getCacheOperations(method, targetClass)));
4957
}
5058

5159
@Override
5260
public boolean equals(@Nullable Object other) {
53-
if (this == other) {
54-
return true;
55-
}
56-
if (!(other instanceof CacheOperationSourcePointcut otherPc)) {
57-
return false;
58-
}
59-
return ObjectUtils.nullSafeEquals(getCacheOperationSource(), otherPc.getCacheOperationSource());
61+
return (this == other || (other instanceof CacheOperationSourcePointcut otherPc &&
62+
ObjectUtils.nullSafeEquals(this.cacheOperationSource, otherPc.cacheOperationSource)));
6063
}
6164

6265
@Override
@@ -66,18 +69,10 @@ public int hashCode() {
6669

6770
@Override
6871
public String toString() {
69-
return getClass().getName() + ": " + getCacheOperationSource();
72+
return getClass().getName() + ": " + this.cacheOperationSource;
7073
}
7174

7275

73-
/**
74-
* Obtain the underlying {@link CacheOperationSource} (may be {@code null}).
75-
* To be implemented by subclasses.
76-
*/
77-
@Nullable
78-
protected abstract CacheOperationSource getCacheOperationSource();
79-
80-
8176
/**
8277
* {@link ClassFilter} that delegates to {@link CacheOperationSource#isCandidateClass}
8378
* for filtering classes whose methods are not worth searching to begin with.
@@ -89,8 +84,7 @@ public boolean matches(Class<?> clazz) {
8984
if (CacheManager.class.isAssignableFrom(clazz)) {
9085
return false;
9186
}
92-
CacheOperationSource cas = getCacheOperationSource();
93-
return (cas == null || cas.isCandidateClass(clazz));
87+
return (cacheOperationSource == null || cacheOperationSource.isCandidateClass(clazz));
9488
}
9589
}
9690

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

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@
1919
import org.springframework.aop.ClassFilter;
2020
import org.springframework.aop.Pointcut;
2121
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
22-
import org.springframework.lang.Nullable;
2322

2423
/**
2524
* Advisor driven by a {@link TransactionAttributeSource}, used to include
@@ -34,16 +33,7 @@
3433
@SuppressWarnings("serial")
3534
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
3635

37-
@Nullable
38-
private TransactionAttributeSource transactionAttributeSource;
39-
40-
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
41-
@Override
42-
@Nullable
43-
protected TransactionAttributeSource getTransactionAttributeSource() {
44-
return transactionAttributeSource;
45-
}
46-
};
36+
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut();
4737

4838

4939
/**
@@ -53,7 +43,7 @@ protected TransactionAttributeSource getTransactionAttributeSource() {
5343
* @see TransactionInterceptor#setTransactionAttributeSource
5444
*/
5545
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
56-
this.transactionAttributeSource = transactionAttributeSource;
46+
this.pointcut.setTransactionAttributeSource(transactionAttributeSource);
5747
}
5848

5949
/**

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,13 +43,7 @@ public class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor {
4343
@Nullable
4444
private TransactionInterceptor transactionInterceptor;
4545

46-
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
47-
@Override
48-
@Nullable
49-
protected TransactionAttributeSource getTransactionAttributeSource() {
50-
return (transactionInterceptor != null ? transactionInterceptor.getTransactionAttributeSource() : null);
51-
}
52-
};
46+
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut();
5347

5448

5549
/**
@@ -71,7 +65,9 @@ public TransactionAttributeSourceAdvisor(TransactionInterceptor interceptor) {
7165
* Set the transaction interceptor to use for this advisor.
7266
*/
7367
public void setTransactionInterceptor(TransactionInterceptor interceptor) {
68+
Assert.notNull(interceptor, "TransactionInterceptor must not be null");
7469
this.transactionInterceptor = interceptor;
70+
this.pointcut.setTransactionAttributeSource(interceptor.getTransactionAttributeSource());
7571
}
7672

7773
/**

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

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,31 @@
3434
* @since 2.5.5
3535
*/
3636
@SuppressWarnings("serial")
37-
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
37+
class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
3838

39-
protected TransactionAttributeSourcePointcut() {
39+
@Nullable
40+
private TransactionAttributeSource transactionAttributeSource;
41+
42+
43+
public TransactionAttributeSourcePointcut() {
4044
setClassFilter(new TransactionAttributeSourceClassFilter());
4145
}
4246

4347

48+
public void setTransactionAttributeSource(@Nullable TransactionAttributeSource transactionAttributeSource) {
49+
this.transactionAttributeSource = transactionAttributeSource;
50+
}
51+
4452
@Override
4553
public boolean matches(Method method, Class<?> targetClass) {
46-
TransactionAttributeSource tas = getTransactionAttributeSource();
47-
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
54+
return (this.transactionAttributeSource == null ||
55+
this.transactionAttributeSource.getTransactionAttribute(method, targetClass) != null);
4856
}
4957

5058
@Override
5159
public boolean equals(@Nullable Object other) {
52-
if (this == other) {
53-
return true;
54-
}
55-
if (!(other instanceof TransactionAttributeSourcePointcut otherPc)) {
56-
return false;
57-
}
58-
return ObjectUtils.nullSafeEquals(getTransactionAttributeSource(), otherPc.getTransactionAttributeSource());
60+
return (this == other || (other instanceof TransactionAttributeSourcePointcut otherPc &&
61+
ObjectUtils.nullSafeEquals(this.transactionAttributeSource, otherPc.transactionAttributeSource)));
5962
}
6063

6164
@Override
@@ -65,18 +68,10 @@ public int hashCode() {
6568

6669
@Override
6770
public String toString() {
68-
return getClass().getName() + ": " + getTransactionAttributeSource();
71+
return getClass().getName() + ": " + this.transactionAttributeSource;
6972
}
7073

7174

72-
/**
73-
* Obtain the underlying TransactionAttributeSource (may be {@code null}).
74-
* To be implemented by subclasses.
75-
*/
76-
@Nullable
77-
protected abstract TransactionAttributeSource getTransactionAttributeSource();
78-
79-
8075
/**
8176
* {@link ClassFilter} that delegates to {@link TransactionAttributeSource#isCandidateClass}
8277
* for filtering classes whose methods are not worth searching to begin with.
@@ -90,8 +85,7 @@ public boolean matches(Class<?> clazz) {
9085
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
9186
return false;
9287
}
93-
TransactionAttributeSource tas = getTransactionAttributeSource();
94-
return (tas == null || tas.isCandidateClass(clazz));
88+
return (transactionAttributeSource == null || transactionAttributeSource.isCandidateClass(clazz));
9589
}
9690
}
9791

0 commit comments

Comments
 (0)