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

spring中有两种产生代理对象的方式:

AopProxy的子类:Cglib2AopProxyJdkDynamicAopProxy

1. Jdk主要是:Proxy.newProxyInstance(classLoader, proxiedInterfaces, InvocationHandler);

  1. 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<Object> 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 <code>null</code>. 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<Object> 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<Object> 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. }

猜你喜欢

转载自m635674608.iteye.com/blog/1715244
今日推荐