Skip to content

Commit f88f69e

Browse files
committed
AspectJExpressionPointcut uses bean ClassLoader for initializing the AspectJ pointcut parser (SPR-7570)
1 parent eda6268 commit f88f69e

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed

org.springframework.aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2010 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.
@@ -54,6 +54,7 @@
5454
import org.springframework.beans.factory.BeanFactoryAware;
5555
import org.springframework.beans.factory.BeanFactoryUtils;
5656
import org.springframework.beans.factory.FactoryBean;
57+
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
5758
import org.springframework.util.ObjectUtils;
5859
import org.springframework.util.StringUtils;
5960

@@ -95,12 +96,6 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
9596

9697
private static final Log logger = LogFactory.getLog(AspectJExpressionPointcut.class);
9798

98-
private transient PointcutParser pointcutParser;
99-
100-
private transient PointcutExpression pointcutExpression;
101-
102-
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
103-
10499
private Class pointcutDeclarationScope;
105100

106101
private String[] pointcutParameterNames = new String[0];
@@ -109,12 +104,15 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
109104

110105
private BeanFactory beanFactory;
111106

107+
private transient PointcutExpression pointcutExpression;
108+
109+
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
110+
112111

113112
/**
114113
* Create a new default AspectJExpressionPointcut.
115114
*/
116115
public AspectJExpressionPointcut() {
117-
initializePointcutParser();
118116
}
119117

120118
/**
@@ -124,7 +122,6 @@ public AspectJExpressionPointcut() {
124122
* @param paramTypes the parameter types for the pointcut
125123
*/
126124
public AspectJExpressionPointcut(Class declarationScope, String[] paramNames, Class[] paramTypes) {
127-
initializePointcutParser();
128125
this.pointcutDeclarationScope = declarationScope;
129126
if (paramNames.length != paramTypes.length) {
130127
throw new IllegalStateException(
@@ -134,13 +131,6 @@ public AspectJExpressionPointcut(Class declarationScope, String[] paramNames, Cl
134131
this.pointcutParameterTypes = paramTypes;
135132
}
136133

137-
private void initializePointcutParser() {
138-
this.pointcutParser =
139-
PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(
140-
SUPPORTED_PRIMITIVES);
141-
this.pointcutParser.registerPointcutDesignatorHandler(new BeanNamePointcutDesignatorHandler());
142-
}
143-
144134

145135
/**
146136
* Set the declaration scope for the pointcut.
@@ -196,15 +186,30 @@ private void checkReadyToMatch() {
196186
* Build the underlying AspectJ pointcut expression.
197187
*/
198188
private PointcutExpression buildPointcutExpression() {
189+
PointcutParser parser = initializePointcutParser();
199190
PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
200191
for (int i = 0; i < pointcutParameters.length; i++) {
201-
pointcutParameters[i] = this.pointcutParser.createPointcutParameter(
192+
pointcutParameters[i] = parser.createPointcutParameter(
202193
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
203194
}
204-
return this.pointcutParser.parsePointcutExpression(
195+
return parser.parsePointcutExpression(
205196
replaceBooleanOperators(getExpression()), this.pointcutDeclarationScope, pointcutParameters);
206197
}
207198

199+
/**
200+
* Initialize the underlying AspectJ pointcut parser.
201+
*/
202+
private PointcutParser initializePointcutParser() {
203+
ClassLoader cl = (this.beanFactory instanceof ConfigurableBeanFactory ?
204+
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
205+
Thread.currentThread().getContextClassLoader());
206+
PointcutParser parser =
207+
PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(
208+
SUPPORTED_PRIMITIVES, cl);
209+
parser.registerPointcutDesignatorHandler(new BeanNamePointcutDesignatorHandler());
210+
return parser;
211+
}
212+
208213
/**
209214
* If a pointcut expression has been specified in XML, the user cannot
210215
* write <code>and</code> as "&&" (though &amp;&amp; will work).
@@ -218,6 +223,7 @@ private String replaceBooleanOperators(String pcExpr) {
218223
return result;
219224
}
220225

226+
221227
/**
222228
* Return the underlying AspectJ pointcut expression.
223229
*/
@@ -226,7 +232,6 @@ public PointcutExpression getPointcutExpression() {
226232
return this.pointcutExpression;
227233
}
228234

229-
230235
public boolean matches(Class targetClass) {
231236
checkReadyToMatch();
232237
try {
@@ -455,7 +460,6 @@ public ContextBasedMatcher parse(String expression) {
455460

456461
/**
457462
* Matcher class for the BeanNamePointcutDesignatorHandler.
458-
*
459463
* <p>Dynamic match tests for this matcher always return true,
460464
* since the matching decision is made at the proxy creation time.
461465
* For static match tests, this matcher abstains to allow the overall
@@ -535,7 +539,7 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound
535539
ois.defaultReadObject();
536540

537541
// Initialize transient fields.
538-
initializePointcutParser();
542+
// pointcutExpression will be initialized lazily by checkReadyToMatch()
539543
this.shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
540544
}
541545

0 commit comments

Comments
 (0)