1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2013 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
42
42
import org .aspectj .weaver .tools .PointcutParser ;
43
43
import org .aspectj .weaver .tools .PointcutPrimitive ;
44
44
import org .aspectj .weaver .tools .ShadowMatch ;
45
+
45
46
import org .springframework .aop .ClassFilter ;
46
47
import org .springframework .aop .IntroductionAwareMethodMatcher ;
47
48
import org .springframework .aop .MethodMatcher ;
55
56
import org .springframework .beans .factory .BeanFactoryUtils ;
56
57
import org .springframework .beans .factory .FactoryBean ;
57
58
import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
59
+ import org .springframework .util .ClassUtils ;
58
60
import org .springframework .util .ObjectUtils ;
59
61
import org .springframework .util .StringUtils ;
60
62
@@ -98,11 +100,11 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
98
100
99
101
private static final Log logger = LogFactory .getLog (AspectJExpressionPointcut .class );
100
102
101
- private Class pointcutDeclarationScope ;
103
+ private Class <?> pointcutDeclarationScope ;
102
104
103
105
private String [] pointcutParameterNames = new String [0 ];
104
106
105
- private Class [] pointcutParameterTypes = new Class [0 ];
107
+ private Class <?> [] pointcutParameterTypes = new Class <?> [0 ];
106
108
107
109
private BeanFactory beanFactory ;
108
110
@@ -123,7 +125,7 @@ public AspectJExpressionPointcut() {
123
125
* @param paramNames the parameter names for the pointcut
124
126
* @param paramTypes the parameter types for the pointcut
125
127
*/
126
- public AspectJExpressionPointcut (Class declarationScope , String [] paramNames , Class [] paramTypes ) {
128
+ public AspectJExpressionPointcut (Class <?> declarationScope , String [] paramNames , Class <?> [] paramTypes ) {
127
129
this .pointcutDeclarationScope = declarationScope ;
128
130
if (paramNames .length != paramTypes .length ) {
129
131
throw new IllegalStateException (
@@ -137,21 +139,21 @@ public AspectJExpressionPointcut(Class declarationScope, String[] paramNames, Cl
137
139
/**
138
140
* Set the declaration scope for the pointcut.
139
141
*/
140
- public void setPointcutDeclarationScope (Class pointcutDeclarationScope ) {
142
+ public void setPointcutDeclarationScope (Class <?> pointcutDeclarationScope ) {
141
143
this .pointcutDeclarationScope = pointcutDeclarationScope ;
142
144
}
143
145
144
146
/**
145
147
* Set the parameter names for the pointcut.
146
148
*/
147
- public void setParameterNames (String [] names ) {
149
+ public void setParameterNames (String ... names ) {
148
150
this .pointcutParameterNames = names ;
149
151
}
150
152
151
153
/**
152
154
* Set the parameter types for the pointcut.
153
155
*/
154
- public void setParameterTypes (Class [] types ) {
156
+ public void setParameterTypes (Class <?>... types ) {
155
157
this .pointcutParameterTypes = types ;
156
158
}
157
159
@@ -188,9 +190,9 @@ private void checkReadyToMatch() {
188
190
* Build the underlying AspectJ pointcut expression.
189
191
*/
190
192
private PointcutExpression buildPointcutExpression () {
191
- ClassLoader cl = (this .beanFactory instanceof ConfigurableBeanFactory ? (( ConfigurableBeanFactory ) this . beanFactory )
192
- . getBeanClassLoader () : Thread . currentThread ()
193
- . getContextClassLoader ());
193
+ ClassLoader cl = (this .beanFactory instanceof ConfigurableBeanFactory ?
194
+ (( ConfigurableBeanFactory ) this . beanFactory ). getBeanClassLoader () :
195
+ ClassUtils . getDefaultClassLoader ());
194
196
return buildPointcutExpression (cl );
195
197
}
196
198
@@ -202,8 +204,7 @@ private PointcutExpression buildPointcutExpression(ClassLoader classLoader) {
202
204
PointcutParameter [] pointcutParameters = new PointcutParameter [this .pointcutParameterNames .length ];
203
205
for (int i = 0 ; i < pointcutParameters .length ; i ++) {
204
206
pointcutParameters [i ] = parser .createPointcutParameter (
205
- this .pointcutParameterNames [i ],
206
- this .pointcutParameterTypes [i ]);
207
+ this .pointcutParameterNames [i ], this .pointcutParameterTypes [i ]);
207
208
}
208
209
return parser .parsePointcutExpression (
209
210
replaceBooleanOperators (getExpression ()),
@@ -244,20 +245,19 @@ public PointcutExpression getPointcutExpression() {
244
245
return this .pointcutExpression ;
245
246
}
246
247
247
- public boolean matches (Class targetClass ) {
248
+ public boolean matches (Class <?> targetClass ) {
248
249
checkReadyToMatch ();
249
250
try {
250
251
return this .pointcutExpression .couldMatchJoinPointsInType (targetClass );
251
- } catch (ReflectionWorldException e ) {
252
- logger .debug ("PointcutExpression matching rejected target class" , e );
252
+ }
253
+ catch (ReflectionWorldException rwe ) {
254
+ logger .debug ("PointcutExpression matching rejected target class" , rwe );
253
255
try {
254
- // Actually this is still a "maybe" - treat the pointcut as dynamic if we
255
- // don't know enough yet
256
+ // Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
256
257
return getFallbackPointcutExpression (targetClass ).couldMatchJoinPointsInType (targetClass );
257
- } catch (BCException ex ) {
258
- logger .debug (
259
- "Fallback PointcutExpression matching rejected target class" ,
260
- ex );
258
+ }
259
+ catch (BCException bce ) {
260
+ logger .debug ("Fallback PointcutExpression matching rejected target class" , bce );
261
261
return false ;
262
262
}
263
263
}
@@ -267,7 +267,7 @@ public boolean matches(Class targetClass) {
267
267
}
268
268
}
269
269
270
- public boolean matches (Method method , Class targetClass , boolean beanHasIntroductions ) {
270
+ public boolean matches (Method method , Class <?> targetClass , boolean beanHasIntroductions ) {
271
271
checkReadyToMatch ();
272
272
Method targetMethod = AopUtils .getMostSpecificMethod (method , targetClass );
273
273
ShadowMatch shadowMatch = getShadowMatch (targetMethod , method );
@@ -283,11 +283,19 @@ else if (shadowMatch.neverMatches()) {
283
283
}
284
284
else {
285
285
// the maybe case
286
- return (beanHasIntroductions || matchesIgnoringSubtypes (shadowMatch ) || matchesTarget (shadowMatch , targetClass ));
286
+ if (beanHasIntroductions ) {
287
+ return true ;
288
+ }
289
+ // A match test returned maybe - if there are any subtype sensitive variables
290
+ // involved in the test (this, target, at_this, at_target, at_annotation) then
291
+ // we say this is not a match as in Spring there will never be a different
292
+ // runtime subtype.
293
+ RuntimeTestWalker walker = getRuntimeTestWalker (shadowMatch );
294
+ return (!walker .testsSubtypeSensitiveVars () || walker .testTargetInstanceOfResidue (targetClass ));
287
295
}
288
296
}
289
297
290
- public boolean matches (Method method , Class targetClass ) {
298
+ public boolean matches (Method method , Class <?> targetClass ) {
291
299
return matches (method , targetClass , false );
292
300
}
293
301
@@ -296,7 +304,7 @@ public boolean isRuntime() {
296
304
return this .pointcutExpression .mayNeedDynamicTest ();
297
305
}
298
306
299
- public boolean matches (Method method , Class targetClass , Object [] args ) {
307
+ public boolean matches (Method method , Class <?> targetClass , Object [] args ) {
300
308
checkReadyToMatch ();
301
309
ShadowMatch shadowMatch = getShadowMatch (AopUtils .getMostSpecificMethod (method , targetClass ), method );
302
310
ShadowMatch originalShadowMatch = getShadowMatch (method , method );
@@ -336,14 +344,13 @@ public boolean matches(Method method, Class targetClass, Object[] args) {
336
344
if (!originalMethodResidueTest .testThisInstanceOfResidue (thisObject .getClass ())) {
337
345
return false ;
338
346
}
339
- }
340
- if ( joinPointMatch . matches () && pmi != null ) {
341
- bindParameters ( pmi , joinPointMatch );
347
+ if ( joinPointMatch . matches ()) {
348
+ bindParameters ( pmi , joinPointMatch );
349
+ }
342
350
}
343
351
return joinPointMatch .matches ();
344
352
}
345
353
346
-
347
354
protected String getCurrentProxiedBeanName () {
348
355
return ProxyCreationContext .getCurrentProxiedBeanName ();
349
356
}
@@ -353,29 +360,14 @@ protected String getCurrentProxiedBeanName() {
353
360
* Get a new pointcut expression based on a target class's loader, rather
354
361
* than the default.
355
362
*/
356
- private PointcutExpression getFallbackPointcutExpression (
357
- Class <?> targetClass ) {
363
+ private PointcutExpression getFallbackPointcutExpression (Class <?> targetClass ) {
358
364
ClassLoader classLoader = targetClass .getClassLoader ();
359
- return classLoader == null ? this .pointcutExpression : buildPointcutExpression (classLoader );
360
- }
361
-
362
- /**
363
- * A match test returned maybe - if there are any subtype sensitive variables
364
- * involved in the test (this, target, at_this, at_target, at_annotation) then
365
- * we say this is not a match as in Spring there will never be a different
366
- * runtime subtype.
367
- */
368
- private boolean matchesIgnoringSubtypes (ShadowMatch shadowMatch ) {
369
- return !(getRuntimeTestWalker (shadowMatch ).testsSubtypeSensitiveVars ());
370
- }
371
-
372
- private boolean matchesTarget (ShadowMatch shadowMatch , Class targetClass ) {
373
- return getRuntimeTestWalker (shadowMatch ).testTargetInstanceOfResidue (targetClass );
365
+ return (classLoader != null ? buildPointcutExpression (classLoader ) : this .pointcutExpression );
374
366
}
375
367
376
368
private RuntimeTestWalker getRuntimeTestWalker (ShadowMatch shadowMatch ) {
377
369
if (shadowMatch instanceof DefensiveShadowMatch ) {
378
- return new RuntimeTestWalker (((DefensiveShadowMatch )shadowMatch ).primary );
370
+ return new RuntimeTestWalker (((DefensiveShadowMatch ) shadowMatch ).primary );
379
371
}
380
372
return new RuntimeTestWalker (shadowMatch );
381
373
}
@@ -409,29 +401,31 @@ private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) {
409
401
try {
410
402
fallbackPointcutExpression = getFallbackPointcutExpression (methodToMatch .getDeclaringClass ());
411
403
shadowMatch = fallbackPointcutExpression .matchesMethodExecution (methodToMatch );
412
- } catch (ReflectionWorld .ReflectionWorldException e ) {
404
+ }
405
+ catch (ReflectionWorld .ReflectionWorldException ex2 ) {
413
406
if (targetMethod == originalMethod ) {
414
407
shadowMatch = new ShadowMatchImpl (org .aspectj .util .FuzzyBoolean .NO , null , null , null );
415
408
}
416
409
else {
417
410
try {
418
411
shadowMatch = this .pointcutExpression .matchesMethodExecution (originalMethod );
419
412
}
420
- catch (ReflectionWorld .ReflectionWorldException ex2 ) {
413
+ catch (ReflectionWorld .ReflectionWorldException ex3 ) {
421
414
// Could neither introspect the target class nor the proxy class ->
422
415
// let's simply consider this method as non-matching.
423
416
methodToMatch = originalMethod ;
424
417
fallbackPointcutExpression = getFallbackPointcutExpression (methodToMatch .getDeclaringClass ());
425
418
try {
426
419
shadowMatch = fallbackPointcutExpression .matchesMethodExecution (methodToMatch );
427
- } catch (ReflectionWorld .ReflectionWorldException e2 ) {
420
+ }
421
+ catch (ReflectionWorld .ReflectionWorldException ex4 ) {
428
422
shadowMatch = new ShadowMatchImpl (org .aspectj .util .FuzzyBoolean .NO , null , null , null );
429
423
}
430
424
}
431
425
}
432
426
}
433
427
}
434
- if (shadowMatch .maybeMatches () && fallbackPointcutExpression != null ) {
428
+ if (shadowMatch .maybeMatches () && fallbackPointcutExpression != null ) {
435
429
shadowMatch = new DefensiveShadowMatch (shadowMatch ,
436
430
fallbackPointcutExpression .matchesMethodExecution (methodToMatch ));
437
431
}
@@ -601,9 +595,11 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound
601
595
this .shadowMatchCache = new ConcurrentHashMap <Method , ShadowMatch >(32 );
602
596
}
603
597
598
+
604
599
private static class DefensiveShadowMatch implements ShadowMatch {
605
600
606
601
private final ShadowMatch primary ;
602
+
607
603
private final ShadowMatch other ;
608
604
609
605
public DefensiveShadowMatch (ShadowMatch primary , ShadowMatch other ) {
@@ -612,31 +608,30 @@ public DefensiveShadowMatch(ShadowMatch primary, ShadowMatch other) {
612
608
}
613
609
614
610
public boolean alwaysMatches () {
615
- return primary .alwaysMatches ();
611
+ return this . primary .alwaysMatches ();
616
612
}
617
613
618
614
public boolean maybeMatches () {
619
- return primary .maybeMatches ();
615
+ return this . primary .maybeMatches ();
620
616
}
621
617
622
618
public boolean neverMatches () {
623
- return primary .neverMatches ();
619
+ return this . primary .neverMatches ();
624
620
}
625
621
626
- public JoinPointMatch matchesJoinPoint (Object thisObject ,
627
- Object targetObject , Object [] args ) {
622
+ public JoinPointMatch matchesJoinPoint (Object thisObject , Object targetObject , Object [] args ) {
628
623
try {
629
- return primary .matchesJoinPoint (thisObject , targetObject , args );
630
- } catch (ReflectionWorldException e ) {
631
- return other .matchesJoinPoint (thisObject , targetObject , args );
624
+ return this .primary .matchesJoinPoint (thisObject , targetObject , args );
625
+ }
626
+ catch (ReflectionWorldException ex ) {
627
+ return this .other .matchesJoinPoint (thisObject , targetObject , args );
632
628
}
633
629
}
634
630
635
631
public void setMatchingContext (MatchingContext aMatchContext ) {
636
- primary .setMatchingContext (aMatchContext );
637
- other .setMatchingContext (aMatchContext );
632
+ this . primary .setMatchingContext (aMatchContext );
633
+ this . other .setMatchingContext (aMatchContext );
638
634
}
639
-
640
635
}
641
636
642
637
}
0 commit comments