spring源码学习之AOP(二)

  接着上一篇中的内容!

3、创建代理

在获取了所有的bean对应的增强器之后,便可以进行代理的创建了
org.springframework.aop.framework.autoproxy包下的AbstractAutoProxyCreator类中的createProxy方法

 1 protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
 2         @Nullable Object[] specificInterceptors, TargetSource targetSource) {
 3 
 4     if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
 5         AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
 6     }
 7 
 8     ProxyFactory proxyFactory = new ProxyFactory();
 9     // 获取当前类中的相关属性
10     proxyFactory.copyFrom(this);
11 
12     // 决定对于给定的bean是否应该使用targetClass属性,而不是他的接口代理,检查proxyTargetClass设置以及preserveTargetClass属性
13     if (!proxyFactory.isProxyTargetClass()) {
14         if (shouldProxyTargetClass(beanClass, beanName)) {
15             proxyFactory.setProxyTargetClass(true);
16         }
17         else {
18             // 添加代理接口
19             evaluateProxyInterfaces(beanClass, proxyFactory);
20         }
21     }
22 
23     Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
24     // 加入增强器
25     proxyFactory.addAdvisors(advisors);
26     // 设置要代理的类
27     proxyFactory.setTargetSource(targetSource);
28     // 定制代理
29     customizeProxyFactory(proxyFactory);
30     // 用来控制代理工厂被配置之后,是否还允许修改通知
31     // 缺省值为false(即在代理被设置之后,不允许修改代理的配置)
32     proxyFactory.setFrozen(this.freezeProxy);
33     if (advisorsPreFiltered()) {
34         proxyFactory.setPreFiltered(true);
35     }
36 
37     return proxyFactory.getProxy(getProxyClassLoader());
38 }

对于代理类的创建和处理,spring委托给ProxyFactory处理,而此函数中主要是对ProxyFactory的初始化操作,进而对真正的创建代理做准备,这些初始化操作如下:
(1)获取当前类中的属性
(2)添加代理接口
(3)封装advisor并加入到ProxyFactory中
(4)设置要代理的类
(5)当然spring中还为子类提供了定制的函数customizeProxyFactory,子类在此函数中对ProxyFactory进一步封装
(6)进行获取代理操作

其中封装advisor并加入到ProxyFactory中以及创建代理是两个相对繁琐的过程,可以通过ProxyFactory提供的addAdvisor方法直接将增强器置入代理创建工厂中,
但是将拦截器封装成增强器还是需要一定的逻辑的

org.springframework.aop.framework.autoproxy包下的AbstractAutoProxyCreator类

 1 protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
 2     // Handle prototypes correctly...
 3     // 解析注册的所有的InterceptorName
 4     Advisor[] commonInterceptors = resolveInterceptorNames();
 5 
 6     List<Object> allInterceptors = new ArrayList<>();
 7     if (specificInterceptors != null) {
 8         // 加入拦截器
 9         allInterceptors.addAll(Arrays.asList(specificInterceptors));
10         if (commonInterceptors.length > 0) {
11             if (this.applyCommonInterceptorsFirst) {
12                 allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
13             }
14             else {
15                 allInterceptors.addAll(Arrays.asList(commonInterceptors));
16             }
17         }
18     }
19     if (logger.isDebugEnabled()) {
20         int nrOfCommonInterceptors = commonInterceptors.length;
21         int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
22         logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
23                 " common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
24     }
25 
26     Advisor[] advisors = new Advisor[allInterceptors.size()];
27     for (int i = 0; i < allInterceptors.size(); i++) {
28         // 拦截器进行封装转化为Advisor
29         advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
30     }
31     return advisors;
32 }

wrap方法在org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry类中重写

 1 @Override
 2 public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
 3     // 如果要封装的对象本身就是Advisor类型的,无需做过多的处理
 4     if (adviceObject instanceof Advisor) {
 5         return (Advisor) adviceObject;
 6     }
 7     // 因为此封装方法只对Advisor和Advice两种类型有效,不是的话,就抛出异常
 8     if (!(adviceObject instanceof Advice)) {
 9         throw new UnknownAdviceTypeException(adviceObject);
10     }
11     Advice advice = (Advice) adviceObject;
12     if (advice instanceof MethodInterceptor) {
13         // So well-known it doesn't even need an adapter.
14         // 如果是MethodInterceptor类型,则使用DefaultPointcutAdvisor类封装
15         return new DefaultPointcutAdvisor(advice);
16     }
17     // 如果存在Advisor的适配器那么也同样需要进行封装
18     for (AdvisorAdapter adapter : this.adapters) {
19         // Check that it is supported.
20         if (adapter.supportsAdvice(advice)) {
21             return new DefaultPointcutAdvisor(advice);
22         }
23     }
24     throw new UnknownAdviceTypeException(advice);
25 }

由于spring中涉及过多的拦截器、增强器、增强方法等方式来对逻辑进行增强,所以非常有必要统一封装成Advisor来进行代理的创建,完成了增强的封装过程,那么解析的
最重要的一步就是代理的创建和获取了

(1)创建代理

 1 // org.springframework.aop.framework.ProxyFactory类中的
 2 public Object getProxy(@Nullable ClassLoader classLoader) {
 3     return createAopProxy().getProxy(classLoader);
 4 }
 5 
 6 protected final synchronized AopProxy createAopProxy() {
 7     if (!this.active) {
 8         activate();
 9     }
10     // 创建代理
11     return getAopProxyFactory().createAopProxy(this);
12 }
13 // org.springframework.aop.framework.DefaultAopProxyFactory类对createAopProxy()方法进行了重写
14 
15 @Override
16 public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
17     if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
18         Class<?> targetClass = config.getTargetClass();
19         if (targetClass == null) {
20             throw new AopConfigException("TargetSource cannot determine target class: " +
21                     "Either an interface or a target is required for proxy creation.");
22         }
23         if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
24             return new JdkDynamicAopProxy(config);
25         }
26         return new ObjenesisCglibAopProxy(config);
27     }
28     else {
29         return new JdkDynamicAopProxy(config);
30     }
31 }

从源码可以看出,spring中存在着两种代理JdkDynamicAopProxy和ObjenesisCglibAopProxy两种
看一下createAopProxy方法中影响这spring使用何种代理的判断条件,也就是if中的条件
(1)isOptimize
用来控制通过CGLIB创建的代理是否使用激进的优化策略。除非了解AOP代理如何处理优化,否则不推荐使用这个设置,目前这个属性仅用于CGLIB代理,JDK代理无效
(2)isProxyTargetClass
这个属性为true时,目标类本身被代理而不是目标类的接口,如果这个属性设置为true,CGLIB代理将被创建,设置方式<aop:aspectj-autoproxy proxy-target-class="true" />
(3)hasNoUserSuppliedProxyInterfaces
是否存在代理接口

JDK代理与CGLIB代理的总结:
  如果目标对象实现了接口,默认情况下会使用JDK动态代理实现AOP
  如果目标对象实现了接口,可以强制使用CGLIB实现AOP
  如果目标对象没有实现接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB代理之前切换

(2)获取代理

  JDK代理使用案例

 1 // 创建业务接口,业务对外提供的接口,包含着业务可以对外提供的功能
 2 public interface UserService{
 3 
 4     // 目标方法
 5     public abstract void add();
 6 }
 7 
 8 // 创建业务接口实现类
 9 public class UserServiceImpl implements UserService {
10 
11     public void add(){
12         System.out.println("---------add()----------");
13     }
14 }
15 
16 // 创建自定义的InvocationHandler,用于对接口提供的方法进行增强
17 public class MyInvocationHandler implements InvocationHandler{
18     private Object target;
19     
20     public MyInvocationHandler(Object target){
21         super();
22         this.target = target;
23     }
24     
25     // 执行目标对象方法
26     public Object invoke(Obejct proxy, Method method, Object[] args) throws Throwable {
27         System.out.println("---------before()----------");
28         Obejct result = method.invoke(target, args);
29         System.out.println("---------after()----------");
30         return result;
31     }
32     
33     // 获取目标对象的代理对象
34     public Object getProxy(){
35         return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),target.getClass().getInterfaces(),this);
36     }
37 }
38 
39 // 测试类
40 public class ProxyTest{
41 
42     @Test
43     public void testProxy(){
44         UserService userService = new UserServiceImpl();
45         // 实例化InvocationHandler
46         MyInvocationHandler invocationHandler = new MyInvocationHandler(userService);
47         // 根据目标对象生成代理对象
48         UserService proxy = (UserService) invocationHandler.getProxy();
49         // 执行代理对象方法
50         proxy.add();
51     }
52 }

用起来很简单,这其实就是AOP的简单的实现,在目标方法的执行之前和执行之后进行了增强,spring的AOP实现其实也就是用了Proxy、InvocationHandler这两个类
再次回顾一下使用JDK代理的方式,在整个创建过程中,对于InvocationHandler的创建是最为核心的,在自定义的InvocationHandler中需要重写三个函数
  构造函数,将代理对象传入
  invoke方法,此方法中实现了AOP增强的所有逻辑
  getProxy方法

JdkDynamicAopProxy的getProxy()源码:
org.springframework.aop.framework.JdkDynamicAopProxy类中

1 @Override
2 public Object getProxy(@Nullable ClassLoader classLoader) {
3     if (logger.isDebugEnabled()) {
4         logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
5     }
6     Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
7     findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
8     return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
9 }

JDKProxy的使用关键是创建自定义的InvocationHandler,而InvocationHandler中包含了需要覆盖的函数getProxy,并且JdkDynamicAopProxy还实现了InvocationHandler接口,
因此,在该类中肯定存在一个重写的invoke方法,完成AOP的核心逻辑:invoke函数源码:

 1 @Override
 2 @Nullable
 3 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 4     Object oldProxy = null;
 5     boolean setProxyContext = false;
 6 
 7     TargetSource targetSource = this.advised.targetSource;
 8     Object target = null;
 9 
10     try {
11         // equals方法的处理
12         if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
13             // The target does not implement the equals(Object) method itself.
14             return equals(args[0]);
15         }
16         // hash方法的处理
17         else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
18             // The target does not implement the hashCode() method itself.
19             return hashCode();
20         }
21         else if (method.getDeclaringClass() == DecoratingProxy.class) {
22             // There is only getDecoratedClass() declared -> dispatch to proxy config.
23             return AopProxyUtils.ultimateTargetClass(this.advised);
24         }
25         else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
26                 method.getDeclaringClass().isAssignableFrom(Advised.class)) {
27             // Service invocations on ProxyConfig with the proxy config...
28             return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
29         }
30 
31         Object retVal;
32 
33         // 有时候目标对象内部的自我调用将无法实施切面中的增强,则需要此属性暴露代理
34         if (this.advised.exposeProxy) {
35             // Make invocation available if necessary.
36             oldProxy = AopContext.setCurrentProxy(proxy);
37             setProxyContext = true;
38         }
39 
40         // Get as late as possible to minimize the time we "own" the target,
41         // in case it comes from a pool.
42         target = targetSource.getTarget();
43         Class<?> targetClass = (target != null ? target.getClass() : null);
44 
45         // Get the interception chain for this method.
46         // 获取当前方法的拦截器链
47         List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(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         if (chain.isEmpty()) {
52             // We can skip creating a MethodInvocation: just invoke the target directly
53             // Note that the final invoker must be an InvokerInterceptor so we know it does
54             // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
55             // 如果没有发现拦截器链,那么直接调用切点方法
56             Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
57             retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
58         }
59         else {
60             // We need to create a method invocation...
61             // 将拦截器封装在ReflectiveMethodInvocation以便于其使用proceed进行链接表用拦截器
62             MethodInvocation invocation =
63                     new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
64             // Proceed to the joinpoint through the interceptor chain.
65             // 执行拦截器链
66             retVal = invocation.proceed();
67         }
68 
69         // Massage return value if necessary.
70         // 返回结果
71         Class<?> returnType = method.getReturnType();
72         if (retVal != null && retVal == target &&
73                 returnType != Object.class && returnType.isInstance(proxy) &&
74                 !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
75             // Special case: it returned "this" and the return type of the method
76             // is type-compatible. Note that we can't help if the target sets
77             // a reference to itself in another returned object.
78             retVal = proxy;
79         }
80         else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
81             throw new AopInvocationException(
82                     "Null return value from advice does not match primitive return type for: " + method);
83         }
84         return retVal;
85     }
86     finally {
87         if (target != null && !targetSource.isStatic()) {
88             // Must have come from TargetSource.
89             targetSource.releaseTarget(target);
90         }
91         if (setProxyContext) {
92             // Restore old proxy.
93             AopContext.setCurrentProxy(oldProxy);
94         }
95     }
96 }

上面的方法中最主要的就是创建了一个拦截器链,并使用ReflectiveMethodInvocation类进行了封装,而在ReflectiveMethodInvocation的proceed中实现了拦截器的逐一
调用,那继续看proceed方法的源码,如何实现前置增强与后置增强的:

此方法是在org.springframework.aop.framework.ReflectiveMethodInvocation类中进行重写的:

 1 @Override
 2 @Nullable
 3 public Object proceed() throws Throwable {
 4     //    We start with an index of -1 and increment early.
 5     // 执行完所有增强后,执行切点方法
 6     if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
 7         return invokeJoinpoint();
 8     }
 9 
10     // 获取下一个要执行的拦截器
11     Object interceptorOrInterceptionAdvice =
12             this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
13     if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
14         // Evaluate dynamic method matcher here: static part will already have
15         // been evaluated and found to match.
16         // 动态匹配
17         InterceptorAndDynamicMethodMatcher dm =
18                 (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
19         if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
20             return dm.interceptor.invoke(this);
21         }
22         else {
23             // Dynamic matching failed.
24             // Skip this interceptor and invoke the next in the chain.
25             // 不匹配则不执行拦截器
26             return proceed();
27         }
28     }
29     else {
30         // It's an interceptor, so we just invoke it: The pointcut will have
31         // been evaluated statically before this object was constructed.
32         /**
33          * 普通拦截器则直接调用拦截器
34          * 例如:
35          * MethodBeforeAdviceIntercepter
36          * AspectJAroundAdvice
37          * AspectJAfterAdvice
38          */
39         // 将this作为参数传递以保证当前实例中调用链的执行
40         return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
41     }
42 }

  CGLIB代理使用案例

CGLIB是一个强大的高性能的代码生成包。CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。
看如何使用CGLIB
需要导入外部net.sf.cglib.proxy包

 1 public class EnhancerDemo{
 2     public static void main(String[] args){
 3         Enhancer enhancer = new Enhancer();
 4         enhancer.setSupperclass(EnhancerDemo.class);
 5         enhancer.setCallback(new MethodInterceptorImpl());
 6         EnhancerDemo demo = (EnhancerDemo) enhancer.create();
 7         demo.test();
 8         System.out.println(demo);
 9     }
10     
11     public void test(){
12         System.out.println("EnhancerDemo test()");
13     }
14     
15     public static class MethodInterceptorImpl implements MethodInterceptor{
16         @Override
17         public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy){
18             System.out.println("Before invoke" + method);
19             Object result = proxy.invokeSuper(obj, args);
20             System.out.println("After invoke" + method);
21             return result;
22         }
23     }
24 }

完成CGLIB代理的类是委托给Cglib2AopProxy类去实现的,Cglib2AopProxy的入口应该是getProxy,也就是说Cglib2AopProxy类的getProxy中实现了Enhancer的创建和接口封装
我就有点搞不懂了,作者从哪里搞出来一个Cglib2AopProxy,明明是CglibAopProxy,看getProxy的源码
org.springframework.aop.framework.CglibAopProxy类中的getProxy

 1 @Override
 2 public Object getProxy(@Nullable ClassLoader classLoader) {
 3     if (logger.isDebugEnabled()) {
 4         logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
 5     }
 6 
 7     try {
 8         Class<?> rootClass = this.advised.getTargetClass();
 9         Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
10 
11         Class<?> proxySuperClass = rootClass;
12         if (ClassUtils.isCglibProxyClass(rootClass)) {
13             proxySuperClass = rootClass.getSuperclass();
14             Class<?>[] additionalInterfaces = rootClass.getInterfaces();
15             for (Class<?> additionalInterface : additionalInterfaces) {
16                 this.advised.addInterface(additionalInterface);
17             }
18         }
19 
20         // Validate the class, writing log messages as necessary.
21         // 验证Class
22         validateClassIfNecessary(proxySuperClass, classLoader);
23 
24         // Configure CGLIB Enhancer...
25         // 创建和配置Enhancer
26         Enhancer enhancer = createEnhancer();
27         if (classLoader != null) {
28             enhancer.setClassLoader(classLoader);
29             if (classLoader instanceof SmartClassLoader &&
30                     ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
31                 enhancer.setUseCache(false);
32             }
33         }
34         enhancer.setSuperclass(proxySuperClass);
35         enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
36         enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
37         enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
38 
39         // 设置拦截器
40         Callback[] callbacks = getCallbacks(rootClass);
41         Class<?>[] types = new Class<?>[callbacks.length];
42         for (int x = 0; x < types.length; x++) {
43             types[x] = callbacks[x].getClass();
44         }
45         // fixedInterceptorMap only populated at this point, after getCallbacks call above
46         enhancer.setCallbackFilter(new ProxyCallbackFilter(
47                 this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
48         enhancer.setCallbackTypes(types);
49 
50         // Generate the proxy class and create a proxy instance.
51         // 生成代理类和创建代理
52         return createProxyClassAndInstance(enhancer, callbacks);
53     }
54     catch (CodeGenerationException | IllegalArgumentException ex) {
55         throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
56                 ": Common causes of this problem include using a final class or a non-visible class",
57                 ex);
58     }
59     catch (Throwable ex) {
60         // TargetSource.getTarget() failed
61         throw new AopConfigException("Unexpected AOP exception", ex);
62     }
63 }

以上函数完成的说明了spring中创建Enhancer的过程,这里最重要的是getCallbacks设置拦截器链,看getCallbacks的源码:
org.springframework.aop.framework.CglibAopProxy类中:

 1 private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
 2     // Parameters used for optimization choices...
 3     // 对expose-proxy属性的处理
 4     boolean exposeProxy = this.advised.isExposeProxy();
 5     boolean isFrozen = this.advised.isFrozen();
 6     boolean isStatic = this.advised.getTargetSource().isStatic();
 7 
 8     // Choose an "aop" interceptor (used for AOP calls).
 9     // 将拦截器封装在DynamicAdvisedInterceptor中
10     Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
11 
12     // Choose a "straight to target" interceptor. (used for calls that are
13     // unadvised but can return this). May be required to expose the proxy.
14     Callback targetInterceptor;
15     if (exposeProxy) {
16         targetInterceptor = (isStatic ?
17                 new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
18                 new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
19     }
20     else {
21         targetInterceptor = (isStatic ?
22                 new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
23                 new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
24     }
25 
26     // Choose a "direct to target" dispatcher (used for
27     // unadvised calls to static targets that cannot return this).
28     Callback targetDispatcher = (isStatic ?
29             new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
30 
31     Callback[] mainCallbacks = new Callback[] {
32             // 将拦截器链加入到Callback中
33             aopInterceptor,  // for normal advice
34             targetInterceptor,  // invoke target without considering advice, if optimized
35             new SerializableNoOp(),  // no override for methods mapped to this
36             targetDispatcher, this.advisedDispatcher,
37             new EqualsInterceptor(this.advised),
38             new HashCodeInterceptor(this.advised)
39     };
40 
41     Callback[] callbacks;
42 
43     // If the target is a static one and the advice chain is frozen,
44     // then we can make some optimizations by sending the AOP calls
45     // direct to the target using the fixed chain for that method.
46     if (isStatic && isFrozen) {
47         Method[] methods = rootClass.getMethods();
48         Callback[] fixedCallbacks = new Callback[methods.length];
49         this.fixedInterceptorMap = new HashMap<>(methods.length);
50 
51         // TODO: small memory optimization here (can skip creation for methods with no advice)
52         for (int x = 0; x < methods.length; x++) {
53             List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
54             fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
55                     chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
56             this.fixedInterceptorMap.put(methods[x].toString(), x);
57         }
58 
59         // Now copy both the callbacks from mainCallbacks
60         // and fixedCallbacks into the callbacks array.
61         callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
62         System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
63         System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
64         this.fixedInterceptorOffset = mainCallbacks.length;
65     }
66     else {
67         callbacks = mainCallbacks;
68     }
69     return callbacks;
70 }

在getCallbacks中spring考虑了很多情况,但是对于我们来说,只需要理解最常用的就可以了,比如将advised属性封装在DynamicAdvisedInterceptor并加入在
callbacks中,这么做的目的是什么,为什么会这么做?在前面的示例中,我们了解到CGLIB中对于方法的拦截是通过将自定义的拦截器(实现MethodInterceptor接口)加入
Callback中并在调用代理的时候直接激活拦截器中的intercept方法来实现的,那么在getCallback中正是实现了这样的一个目的,DynamicAdvisedInterceptor继承自MethodInterceptor
加入CallBack中后,再次调用代理时会直接调用DynamicAdvisedInterceptor中的intercept方法,所以,由此推断,对于CGLIB方式实现的代理,其核心逻辑在
DynamicAdvisedInterceptor中的intercept方法,DynamicAdvisedInterceptor作为CglibAopProxy内部封装私有类,其在org.springframework.aop.framework.CglibAopProxy类中:

 1 @Override
 2 @Nullable
 3 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
 4     Object oldProxy = null;
 5     boolean setProxyContext = false;
 6     Object target = null;
 7     TargetSource targetSource = this.advised.getTargetSource();
 8     try {
 9         if (this.advised.exposeProxy) {
10             // Make invocation available if necessary.
11             oldProxy = AopContext.setCurrentProxy(proxy);
12             setProxyContext = true;
13         }
14         // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
15         target = targetSource.getTarget();
16         Class<?> targetClass = (target != null ? target.getClass() : null);
17         // 获取拦截链
18         List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
19         Object retVal;
20         // Check whether we only have one InvokerInterceptor: that is,
21         // no real advice, but just reflective invocation of the target.
22         if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
23             // We can skip creating a MethodInvocation: just invoke the target directly.
24             // Note that the final invoker must be an InvokerInterceptor, so we know
25             // it does nothing but a reflective operation on the target, and no hot
26             // swapping or fancy proxying.
27             Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
28             // 如果拦截链为空则直接激活原方法
29             retVal = methodProxy.invoke(target, argsToUse);
30         }
31         else {
32             // We need to create a method invocation...
33             // 进入链中
34             retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
35         }
36         retVal = processReturnType(proxy, target, method, retVal);
37         return retVal;
38     }
39     finally {
40         if (target != null && !targetSource.isStatic()) {
41             targetSource.releaseTarget(target);
42         }
43         if (setProxyContext) {
44             // Restore old proxy.
45             AopContext.setCurrentProxy(oldProxy);
46         }
47     }
48 }

上述的实现与JDK方式实现代理中的invoke方法基本相同,都是首先构造链,然后封装此链进行串联调用,区别就是在JDK代理中直接构造ReflectiveMethodInvocation类,而在
CGLIB代理中使用CglibMethodInvocation,CglibMethodInvocation继承自ReflectiveMethodInvocation,但是process方法没有重写

注意:spring还支持静态代理,这里没有写!!!不想写了

原文地址:https://www.cnblogs.com/ssh-html/p/11296363.html