您的位置:首页 > 编程语言 > Java开发

spring 代理对象方法增强源码解析

2016-03-10 16:05 615 查看
在spring中有两种产生代理对象的方式:
AopProxy的子类:Cglib2AopProxy和JdkDynamicAopProxy。
1. Jdk主要是:Proxy.newProxyInstance(classLoader, proxiedInterfaces, InvocationHandler);
2. Cglib则是通过Enhancer类来实现的。
它们有个相同点就是都有一个回调方法。我们可以在回调方法中对目标方法进行增强。
JDK代理对象的回调
1. public Object invoke(Object proxy, Method method, Object[]
2. args) throws Throwable {
3. MethodInvocation invocation = null;
4. Object oldProxy = null;
5. boolean setProxyContext = false;
6. TargetSource targetSource =
7. this.advised.targetSource;
8. Class targetClass = null;
9. Object target = null;
10. try {
11. if (!this.equalsDefined &&
12. AopUtils.isEqualsMethod(method)) {
13. // The target does not implement the
14. equals(Object) method itself.
15. return equals(args[0]);
16. }
17. if (!this.hashCodeDefined &&
18. AopUtils.isHashCodeMethod(method)) {
19. // The target does not implement the
20. hashCode() method itself.
21. return hashCode();
22. }
23. if (!this.advised.opaque &&
24. method.getDeclaringClass().isInterface() &&
25.
26. method.getDeclaringClass().isAssignableFrom(Advised.class))
27. {
28. // Service invocations on
29. ProxyConfig with the proxy config...
30. return
31. AopUtils.invokeJoinpointUsingReflection(this.advised,
32. method, args);
33. }
34. Object retVal = null;
35. if (this.advised.exposeProxy) {
36. // Make invocation available if
37. necessary.
38. oldProxy =
39. AopContext.setCurrentProxy(proxy);
40. setProxyContext = true;
41. }
42. /**
43. * May be null. Get as late as possible to
44. minimize the time we "own" the
45. * target, in case it comes from a pool.
46. */
47. //得到目标对象的地方。
48. target = targetSource.getTarget();
49. if (target != null) {
50. targetClass = target.getClass();
51. }
52. // Get the interception chain for this
53. method.
54. // 这里获得定义好的拦截器链。
55. List chain =
56. this.advised.getInterceptorsAndDynamicInterception
57. Advice(method, targetClass);
58. /**
59. * Check whether we have any advice. If we
60. don't, we can fallback on
61. * direct reflective invocation of the
62. target, and avoid creating a MethodInvocation.
63. */
64.
65. //
66. 如果没有设定拦截器,那么我们就直接调用target的对应方法。
67. if (chain.isEmpty()) {
68. /**
69. * We can skip creating a
70. MethodInvocation: just invoke the target directly
71. * Note that the final invoker must
72. be an InvokerInterceptor so we
73. * know it does nothing but a
74. reflective operation on the target, and no hot
75. * swapping or fancy proxying.
76. */
77. retVal =
78. AopUtils.invokeJoinpointUsingReflection(target, method,
79. args);
80. }
81. else {
82. // We need to create a method
83. invocation...
84. /**
85. *
86. 如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相
87. 应方法,
88. *
89. 通过构造一个ReflectiveMethodInvocation来实现,下面我们会看
90. *
91. 这个ReflectiveMethodInvocation类的具体实现。
92. */
93. invocation = new
94. ReflectiveMethodInvocation(proxy, target, method,
95. args, targetClass, chain);
96. // Proceed to the joinpoint through
97. the interceptor chain.
98. //沿着拦截器链继续前进。
99. retVal = invocation.proceed();
100. }
101.
102. // Massage return value if necessary.
103. if (retVal != null && retVal == target &&
104. method.getReturnType().
105. isInstance(Proxy) &&
106. !RawTargetAccess.class.isAssignableFrom
107. (method.getDeclaringClass())) {
108. /**
109. * Special case: it returned "this"
110. and the return type of the method
111. * is type-compatible. Note that we
112. can't help if the target sets
113. * a reference to itself in another
114. returned object.
115. */
116. retVal = Proxy;
117. }
118. return retVal;
119. }
120. finally {
121. if (target != null &&
122. !targetSource.isStatic()) {
123. // Must have come from TargetSource.
124. targetSource.releaseTarget(target);
125. }
126. if (setProxyContext) {
127. // Restore old proxy.
128.
129. AopContext.setCurrentProxy(oldProxy);
130. }
131. }
132. }
Cglib代理对象的回调方法:
1. public Object intercept(Object proxy, Method method,
2. Object[] args, MethodProxy
3. methodProxy) throws Throwable {
4. Object oldProxy = null;
5. boolean setProxyContext = false;
6. Class targetClass = null;
7. Object target = null;
8. try {
9. if (this.advised.exposeProxy) {
10. // Make invocation available if
11. necessary.
12. oldProxy =
13. AopContext.setCurrentProxy(proxy);
14. setProxyContext = true;
15. }
16. /**
17. * May be
null
. Get as late as
18. possible to minimize the time we
19. * "own" the target, in case it comes from a
20. pool.
21. */
22. target = getTarget();
23. if (target != null) {
24. targetClass = target.getClass();
25. }
26. //从advised中取得配置好的AOP通知。
27. List chain =
28. this.advised.getInterceptorsAndDynamicInterceptionAdvice
29. (method, targetClass);
30. Object retVal = null;
31. /**
32. * Check whether we only have one
33. InvokerInterceptor: that is,
34. * no real advice, but just reflective
35. invocation of the target.
36. */
37. //
38. 如果没有AOP通知配置,那么直接调用target对象的调用方法。
39. if (chain.isEmpty() &&
40. Modifier.isPublic(method.getModifiers())) {
41. /**
42. * We can skip creating a
43. MethodInvocation: just invoke the target directly.
44. * Note that the final invoker must
45. be an InvokerInterceptor, so we know
46. * it does nothing but a reflective
47. operation on the target, and no hot
48. * swapping or fancy proxying.
49. */
50. retVal = methodProxy.invoke(target,
51. args);
52. }
53. else {
54.
55. //通过CglibMethodInvocation来启动advice通知。
56. retVal = new
57. CglibMethodInvocation(proxy, target, method, args,
58. targetClass, chain, methodProxy).proceed();
59. }
60. retVal = massageReturnTypeIfNecessary(proxy,
61. target, method, retVal);
62. return retVal;
63. }
64. finally {
65. if (target != null) {
66. releaseTarget(target);
67. }
68. if (setProxyContext) {
69. // Restore old proxy.
70.
71. AopContext.setCurrentProxy(oldProxy);
72. }
73. }
74. }

在调用代理目标对象的方法时;都对方法进行了增强。
75. //从advised中取得配置好的AOP通知。
76. List chain =
77. this.advised.getInterceptorsAndDynamicInterceptionAdvice
(method, targetClass);
在这里可以设置不同的拦截器进行不同的业务处理。比如记录日志,事物的开启…
这就是Aop的核心。具体是由相关的拦截器完成的。

在jdk,cglib代理类中都有一个拦截链处理器,它们分别是
JDK代理类拦截链处理器:
133. 这个ReflectiveMethodInvocation类的具体实现。
134. */
135. ReflectiveMethodInvocation invocation = new
136. ReflectiveMethodInvocation(proxy, target, method,
137. args, targetClass, chain);
138. //沿着拦截器链继续前进。
retVal = invocation.proceed();
CGLIB代理类拦截链处理器:
78. //通过CglibMethodInvocation来启动advice通知。
79. retVal = new
80. CglibMethodInvocation(proxy, target, method, args,
81. targetClass, chain, methodProxy).proceed();
82. }
83. retVal = massageReturnTypeIfNecessary(proxy,
84. target, method, retVal);
JDK代理类拦截链处理器的proceed方法:
1. public Object proceed() throws Throwable {
2. // We start with an index of -1 and increment
3. early.
4. /**
5. *如果拦截器链中的拦截器迭代调用完毕,这里开始调用tar
6. get的函数,
7. *这个函数是通过反射机制完成的,具体实现在:AopUtils.
8. invokeJoinpointUsingReflection方法里面。
9. */
10. if (this.currentInterceptorIndex ==
11. this.interceptorsAndDynamicMethod
12. Matchers.size() - 1) {
13. return invokeJoinpoint();
14. }
15. //这里沿着定义好的
16. interceptorOrInterceptionAdvice链进行处理。
17. Object interceptorOrInterceptionAdvice =
18. this.interceptorsAndDynamicMethodMatchers.get(++this
19. .currentInterceptor
20. Index);
21. if (interceptorOrInterceptionAdvice instanceof
22. InterceptorAndDynamic
23. MethodMatcher) {
24. /**
25. * Evaluate dynamic method matcher here:
26. static part will already have
27. * been evaluated and found to match.
28. */
29. /**
30.
31. *这里对拦截器进行动态匹配的判断,还记得我们前面分析的pointcu
32. t吗?
33.
34. *这里是触发进行匹配的地方,如果和定义的pointcut匹配,那么这
35. 个advice将会得到执行。
36. */
37. InterceptorAndDynamicMethodMatcher dm =
38. (InterceptorAndDynamicMethodMatcher)
39. interceptorOrInterceptionAdvice;
40. if (dm.methodMatcher.matches(this.method,
41. this.targetClass, this.arguments)) {
42. return dm.interceptor.invoke(this);
43. }
44. else {
45. // Dynamic matching failed.
46. // Skip this interceptor and invoke
47. the next in the chain.
48. //
49. 如果不匹配,那么proceed会被递归调用,直到所有的拦截器都被运
50. 行过为止。
51. return proceed();
52. }
53. }



描述: 相关拦截器

大小: 91.4 KB

查看图片附件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: