|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2008 the original author or authors. |
| 2 | + * Copyright 2002-2009 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.
|
|
17 | 17 | package org.springframework.aop.aspectj;
|
18 | 18 |
|
19 | 19 | import java.lang.reflect.Method;
|
20 |
| -import java.util.HashMap; |
21 | 20 | import java.util.HashSet;
|
22 | 21 | import java.util.Map;
|
23 | 22 | import java.util.Set;
|
| 23 | +import java.util.concurrent.ConcurrentHashMap; |
24 | 24 |
|
25 | 25 | import org.aopalliance.intercept.MethodInvocation;
|
26 | 26 | import org.apache.commons.logging.Log;
|
27 | 27 | import org.apache.commons.logging.LogFactory;
|
28 | 28 | import org.aspectj.weaver.BCException;
|
29 | 29 | import org.aspectj.weaver.patterns.NamePattern;
|
30 | 30 | import org.aspectj.weaver.reflect.ReflectionWorld;
|
| 31 | +import org.aspectj.weaver.reflect.ShadowMatchImpl; |
31 | 32 | import org.aspectj.weaver.tools.ContextBasedMatcher;
|
32 | 33 | import org.aspectj.weaver.tools.FuzzyBoolean;
|
33 | 34 | import org.aspectj.weaver.tools.JoinPointMatch;
|
@@ -92,7 +93,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
92 | 93 |
|
93 | 94 | private static final Log logger = LogFactory.getLog(AspectJExpressionPointcut.class);
|
94 | 95 |
|
95 |
| - private final Map<Method, ShadowMatch> shadowMatchCache = new HashMap<Method, ShadowMatch>(); |
| 96 | + private final Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32); |
96 | 97 |
|
97 | 98 | private PointcutParser pointcutParser;
|
98 | 99 |
|
@@ -243,15 +244,7 @@ public boolean matches(Class targetClass) {
|
243 | 244 | public boolean matches(Method method, Class targetClass, boolean beanHasIntroductions) {
|
244 | 245 | checkReadyToMatch();
|
245 | 246 | Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
|
246 |
| - ShadowMatch shadowMatch = null; |
247 |
| - try { |
248 |
| - shadowMatch = getShadowMatch(targetMethod, method); |
249 |
| - } |
250 |
| - catch (ReflectionWorld.ReflectionWorldException ex) { |
251 |
| - // Could neither introspect the target class nor the proxy class -> |
252 |
| - // let's simply consider this method as non-matching. |
253 |
| - return false; |
254 |
| - } |
| 247 | + ShadowMatch shadowMatch = getShadowMatch(targetMethod, method); |
255 | 248 |
|
256 | 249 | // Special handling for this, target, @this, @target, @annotation
|
257 | 250 | // in Spring - we can optimize since we know we have exactly this class,
|
@@ -279,17 +272,8 @@ public boolean isRuntime() {
|
279 | 272 |
|
280 | 273 | public boolean matches(Method method, Class targetClass, Object[] args) {
|
281 | 274 | checkReadyToMatch();
|
282 |
| - ShadowMatch shadowMatch = null; |
283 |
| - ShadowMatch originalShadowMatch = null; |
284 |
| - try { |
285 |
| - shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method); |
286 |
| - originalShadowMatch = getShadowMatch(method, method); |
287 |
| - } |
288 |
| - catch (ReflectionWorld.ReflectionWorldException ex) { |
289 |
| - // Could neither introspect the target class nor the proxy class -> |
290 |
| - // let's simply consider this method as non-matching. |
291 |
| - return false; |
292 |
| - } |
| 275 | + ShadowMatch shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method); |
| 276 | + ShadowMatch originalShadowMatch = getShadowMatch(method, method); |
293 | 277 |
|
294 | 278 | // Bind Spring AOP proxy to AspectJ "this" and Spring AOP target to AspectJ target,
|
295 | 279 | // consistent with return of MethodInvocationProceedingJoinPoint
|
@@ -364,24 +348,31 @@ private void bindParameters(ProxyMethodInvocation invocation, JoinPointMatch jpm
|
364 | 348 | }
|
365 | 349 |
|
366 | 350 | private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) {
|
367 |
| - synchronized (this.shadowMatchCache) { |
368 |
| - ShadowMatch shadowMatch = this.shadowMatchCache.get(targetMethod); |
369 |
| - if (shadowMatch == null) { |
370 |
| - try { |
371 |
| - shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod); |
| 351 | + ShadowMatch shadowMatch = this.shadowMatchCache.get(targetMethod); |
| 352 | + if (shadowMatch == null) { |
| 353 | + try { |
| 354 | + shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod); |
| 355 | + } |
| 356 | + catch (ReflectionWorld.ReflectionWorldException ex) { |
| 357 | + // Failed to introspect target method, probably because it has been loaded |
| 358 | + // in a special ClassLoader. Let's try the original method instead... |
| 359 | + if (targetMethod == originalMethod) { |
| 360 | + shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null); |
372 | 361 | }
|
373 |
| - catch (ReflectionWorld.ReflectionWorldException ex) { |
374 |
| - // Failed to introspect target method, probably because it has been loaded |
375 |
| - // in a special ClassLoader. Let's try the original method instead... |
376 |
| - if (targetMethod == originalMethod) { |
377 |
| - throw ex; |
| 362 | + else { |
| 363 | + try { |
| 364 | + shadowMatch = this.pointcutExpression.matchesMethodExecution(originalMethod); |
| 365 | + } |
| 366 | + catch (ReflectionWorld.ReflectionWorldException ex2) { |
| 367 | + // Could neither introspect the target class nor the proxy class -> |
| 368 | + // let's simply consider this method as non-matching. |
| 369 | + shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null); |
378 | 370 | }
|
379 |
| - shadowMatch = this.pointcutExpression.matchesMethodExecution(originalMethod); |
380 | 371 | }
|
381 |
| - this.shadowMatchCache.put(targetMethod, shadowMatch); |
382 | 372 | }
|
383 |
| - return shadowMatch; |
| 373 | + this.shadowMatchCache.put(targetMethod, shadowMatch); |
384 | 374 | }
|
| 375 | + return shadowMatch; |
385 | 376 | }
|
386 | 377 |
|
387 | 378 |
|
|
0 commit comments