前面我们分析了Spring AOP实现中得到Proxy对象的过程,下面我们看看在Spring AOP中拦截器链是怎样被调用的,也就是Proxy模式是怎样起作用的,或者说Spring是怎样为我们提供AOP功能的; 在JdkDynamicAopProxy中生成Proxy对象的时候: 代码
1. return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
这里的this参数对应的是InvocationHandler对象,这里我们的
JdkDynamicAopProxy实现了这个接口,也就是说当Proxy对象的函数被调用的时候,这个InvocationHandler的invoke方法会被作为回调函数调用,下面我们看看这个方法的实现: 代码
1. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
2. MethodInvocation invocation = null; 3. Object oldProxy = null;
4. boolean setProxyContext = false; 5.
6. TargetSource targetSource = this.advised.targetSource; 7. Class targetClass = null; 8. Object target = null; 9.
10. try {
11. // Try special rules for equals() method and implementation of the
12. // Advised AOP configuration interface. 13.
14. if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
15. // What if equals throws exception!?
16. // This class implements the equals(Object) method itself.
17. return equals(args[0]) ? Boolean.TRUE : Boolean.FALSE;
18. }
19. if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
20. // This class implements the hashCode() method itself.
21. return new Integer(hashCode());
22. }
23. if (Advised.class == method.getDeclaringClass()) { 24. // service invocations on ProxyConfig with the proxy config
25. return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); 26. } 27.
28. Object retVal = null; 29.
30. if (this.advised.exposeProxy) {
31. // make invocation available if necessary
32. oldProxy = AopContext.setCurrentProxy(proxy); 33. setProxyContext = true; 34. } 35.
36. // May be null. Get as late as possible to minimize the time we \37. // in case it comes from a pool.
38. // 这里是得到目标对象的地方,当然这个目标对象可能来自于一个实例池或者是一个简单的JAVA对象
39. target = targetSource.getTarget(); 40. if (target != null) {
41. targettargetClass = target.getClass(); 42. } 43.
44. // get the interception chain for this method 45. // 这里获得定义好的拦截器链
46. List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
47. this.advised, proxy, method, targetClass); 48.
49. // Check whether we have any advice. If we don't, we can fallback on direct
50. // reflective invocation of the target, and avoid creating a MethodInvocation.
51. // 如果没有设定拦截器,那么我们就直接调用目标的对应方法
52. if (chain.isEmpty()) {
53. // We can skip creating a MethodInvocation: just invoke the target directly
54. // Note that the final invoker must be an InvokerInterceptor so we know it does
55. // nothing but a reflective operation on the target, and no hot swapping or fancy proxying
56. retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); 57. }
58. else {
59. // We need to create a method invocation... 60. // invocation = advised.getMethodInvocationFactory().getMethodInvocation(
61. // proxy, method, targetClass, target, args, chain, advised);
62. // 如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相应方法
63. // 这里通过构造一个ReflectiveMethodInvocation来实现,下面我们会看这个ReflectiveMethodInvocation类
64. invocation = new ReflectiveMethodInvocation( 65. proxy, target, method, args, targetClass, chain); 66.
67. // proceed to the joinpoint through the interceptor chain
68. // 这里通过ReflectiveMethodInvocation来调用拦截器链和相应的目标方法
69. retVal = invocation.proceed(); 70. } 71.
72. // massage return value if necessary
73. if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy)) {
74. // Special case: it returned \type of the method is type-compatible
75. // Note that we can't help if the target sets 76. // a reference to itself in another returned object.
77. retVal = proxy; 78. }
79. return retVal; 80. }
81. finally {
82. if (target != null && !targetSource.isStatic()) { 83. // must have come from TargetSource 84. targetSource.releaseTarget(target); 85. } 86.
87. if (setProxyContext) { 88. // restore old proxy
89. AopContext.setCurrentProxy(oldProxy); 90. } 91. } 92.}
我们先看看目标对象方法的调用,这里是通过AopUtils的方法调用 - 使用反射机制来对目标对象的方法进行调用: 代码
1. public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args) 2. throws Throwable { 3.
4. // Use reflection to invoke the method.
5. // 利用放射机制得到相应的方法,并且调用invoke 6. try {
7. if (!Modifier.isPublic(method.getModifiers()) || 8. !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
9. method.setAccessible(true); 10. }
11. return method.invoke(target, args); 12. }
13. catch (InvocationTargetException ex) {
14. // Invoked method threw a checked exception.
15. // We must rethrow it. The client won't see the interceptor.
16. throw ex.getTargetException(); 17. }
18. catch (IllegalArgumentException ex) {
19. throw new AopInvocationException(\ms to be invalid: tried calling method [\
20. method + \
21. }
22. catch (IllegalAccessException ex) {
23. throw new AopInvocationException(\d: \24. } 25.}
对拦截器链的调用处理是在ReflectiveMethodInvocation里实现的: 代码
1. public Object proceed() throws Throwable {
2. // We start with an index of -1 and increment early. 3. // 这里直接调用目标对象的方法,没有拦截器的调用或者拦截器已经调用完了,这个currentInterceptorIndex的初始值是0
4. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()) {
5. return invokeJoinpoint(); 6. } 7.
8. Object interceptorOrInterceptionAdvice =
9. this.interceptorsAndDynamicMethodMatchers.get(this.currentInterceptorIndex);
10. if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
11. // Evaluate dynamic method matcher here: static part will already have
12. // been evaluated and found to match.
13. // 这里获得相应的拦截器,如果拦截器可以匹配的上的话,那就调用拦截器的invoke方法
14. InterceptorAndDynamicMethodMatcher dm =
15. (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
16. if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
17. return dm.interceptor.invoke(nextInvocation()); 18. }
19. else {
20. // Dynamic matching failed.
21. // Skip this interceptor and invoke the next in the chain.
22. // 如果拦截器匹配不上,那就调用下一个拦截器,这个时候拦截器链的位置指示后移并迭代调用当前的proceed方法 23. this.currentInterceptorIndex++; 24. return proceed(); 25. } 26. }
27. else {
28. // It's an interceptor, so we just invoke it: The pointcut will have