Spring 源码解析-AOP的实现





1、spring通过自带的插件机制实现NameSpaceHandler处理xml配置


    遇到<AOP:>标签,交给

    AopNameSpaceHandler进行执行


2、Spring解析BeanDefinition


    在AopNameSpaceHandler可以看到<aop:config>是交给org.springframework.aop.config.ConfigBeanDefinitionParser进行解析


    2.1 注册自动代理类创造者


         ConfigBeanDefinitionParser.configureAutoProxyCreator


        在spring的BeanFactory中注册一个名称为”org.springframework.aop.config.internalAutoProxyCreator”,


        类名为:AspectJAwareAdvisorAutoProxyCreator.class的BeanPostProcessors


    2.2 根据不同的标签进行解析


        2.2.1标签类型为<aop:pointcut>,进入parsePointcut分支


                    创建PointcutDefinition

                    RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);

                    beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);

                    beanDefinition.setSynthetic(true);

                    beanDefinition.getPropertyValues().add(EXPRESSION, expression);

                    其中expression即为配置的切入点,例如expression=”execution(* cn.kanmars.service.impl.DubboServiceImpl.exec(..))”

                    之后将PointcutDefinition注册到beanFactory中


        2.2.2标签类型为<aop:aspect>,进入parseAspect分支,按照Advistor进行解析,进入的方法为private AbstractBeanDefinition parseAdvice


                    2.2.2.1 创建method factory bean


                        new RootBeanDefinition(MethodLocatingFactoryBean.class);


                    2.2.2.2 创建instance factory definition


                        RootBeanDefinition aspectFactoryDef = new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class);


                        SimpleBeanFactoryAwareAspectInstanceFactory类继承自org.springframework.aop.aspectj.Ordered接口


                    2.2.2.3 创建 register the pointcut        此处spring的注释与代码有差异


                       AdviseClass   ConfigBeanDefinitionParser.getAdviceClass


                        按照不同的类型创建advistor

                        其中

                            BEFORE    AspectJMethodBeforeAdvice.class;

                            AFTER    AspectJAfterAdvice.class;

                            AFTER_RETURNING_ELEMENT    AspectJAfterReturningAdvice.class;

                            AFTER_THROWING_ELEMENT    AspectJAfterThrowingAdvice.class;

                            AROUND    AspectJAroundAdvice.class;

                        RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext));

                    2.2.2.3 配置advistor    configure the advisor

                        RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class);

                    2.2.2.4 创建切面组件

                       AspectComponentDefinition aspectComponentDefinition = createAspectComponentDefinition(aspectElement, aspectId, beanDefinitions, beanReferences, parserContext);

       2.2.3标签类型为<aop:advistor>,进入parseAdvisor分支

                解析AdvisorBeanDefinition

                注册到beanFactory中


3、AbstractApplicationContext.registerBeanPostProcessors。注册BeanPostProcessors


    3.1 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);



        获取到了org.springframework.aop.config.internalAutoProxyCreator

        由于AspectJAwareAdvisorAutoProxyCreator实现了Order接口,因此在第二顺序注册

4、AbstractApplicationContext.finishBeanFactoryInitialization,对象实例化


    4.1 获取到RootBeanDefinition


    4.2 在实例化AbstractAutowireCapableBeanFactory.createBean()448行,此处由于bean为空,所以并未执行


            try {

                // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.

                Object bean = resolveBeforeInstantiation(beanName, mbd);

                if (bean != null) {

                    return bean;

                }

            }

            catch (Throwable ex) {

                throw new BeanCreationException(mbd.getResourceDescription(), beanName,

                        ”BeanPostProcessor before instantiation of bean failed”, ex);

            }

            对代理类进行实例化

            执行AspectJAwareAdvisorAutoProxyCreator.postProcessBeforeInstantiation方法

            返回为空


    4.3 对对象进行实例化


    4.4 初始化Bean属性Initialize the bean instance.


                populateBean()

                InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))

                exposedObject = initializeBean(beanName, exposedObject, mbd)


               


    4.5 执行afterInitialization方法


                AspectJAwareAdvisorAutoProxyCreator.postProcessAfterInstantiation


                AspectJAwareAdvisorAutoProxyCreator.parent().parent()即AbstractAutoProxyCreator.postProcessAfterInitialization


                AbstractAutoProxyCreator.postProcessAfterInitialization


                AbstractAutoProxyCreator.wrapIfNecessary


                4.5.1 //获取所有的advistor

                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

                4.5.2 创建代理类

                Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));


                    4.5.2.1 创建一个ProxyFactory


                    Advised


                        ProxyConfig

                            AdvisedSupport                                                AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();

                                ProxyCreatorSupport                                        this.aopProxyFactory = new DefaultAopProxyFactory();

                                    ProxyFactory proxyFactory = new ProxyFactory();

                

                        

                    4.5.2.2 创建advistors   buildAdvisors

                        从specificInterceptors中创建Advisor数组

                        proxyFactory.addAdvisor(advisors);//将advistors放入proxyFactory中

                    

                    4.5.2.3 调用proxyFactory.getProxy

                        调用createAopProxy().getProxy

                            调用getAopProxyFactory().createAopProxy(this).getProxy

                                调用DefaultAopProxyFactory.createAopProxy(AdvisedSupport config).getProxy        –此处传递的config,即为proxyFactory————————–>在此处进行了JDK代理和CGLIB代理的选择

                    4.5.2.3.1 DefaultAopProxyFactory.createAopProxy(AdvisedSupport config)  –>    return CglibProxyFactory.createCglibProxy(config)

                    4.5.2.3.2 DefaultAopProxyFactory.createAopProxy(AdvisedSupport config)  –>    return new CglibAopProxy(advisedSupport);


                    4.5.2.3.3 cglibAopProxy.this.advised = config;


                                  cglibAopProxy.advisedDispatcher = new AdvisedDispatcher(this.advised);


                                  即获取到AopProxy为CglibAopProxy

                    4.5.2.3.4 调用CglibAopProxy.getProxy();  –>


                    4.5.2.3.4.1 生成代理类,代码如下


                        Enhancer enhancer = createEnhancer()

                        enhancer.setSuperclass(proxySuperClass);

                        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));

                        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);

                        enhancer.setStrategy(new MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class));

                        enhancer.setInterceptDuringConstruction(false);

                        

                        Callback[] callbacks = getCallbacks(rootClass);

                                Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised)

                                Callback[] mainCallbacks = new Callback[]{

                                    aopInterceptor, // for normal advice

                                    targetInterceptor, // invoke target without considering advice, if optimized

                                    new SerializableNoOp(), // no override for methods mapped to this

                                    targetDispatcher,

                                    this.advisedDispatcher,

                                    new EqualsInterceptor(this.advised),

                                    new HashCodeInterceptor(this.advised)

                                };

                                

                        Class<?>[] types = new Class<?>[callbacks.length];

                        for (int x = 0; x < types.length; x++) {

                            types[x] = callbacks[x].getClass();

                        }

                        enhancer.setCallbackFilter(new ProxyCallbackFilter(

                                this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));

                        enhancer.setCallbackTypes(types);


                        enhancer.setCallbacks(callbacks);


                        proxy = enhancer.create();//此处即为代理对象。

                        此时return 一个proxy,即为所需要的代理


                4.5.2.3.4.2 以上enhancer的代码可以参见CGLIB的相关文档,大意如下:


                     4.5.2.3.4.2.1  生成了一个Callback数组,该Callback为回调函数,用于在匹配到对应方法时执行。


                     4.5.2.3.5.2.2  在enhancer中有一个ProxyCallbackFilter类,该类用于“对callback数组进行匹配”


                                例如当运行ProxyCallbackFilter的accept方法返回0时,执行的是callback数组中的第0个回调函数(这是个很奇葩很与众不同的概念)


                                目前ProxyCallbackFilter返回值如下:


                                在CallbackFilter中配置的顺序为

                                private static final int AOP_PROXY = 0;                    普通代理

                                private static final int INVOKE_TARGET = 1;                invoke target without considering advice,直接执行目标的方法-在配置了pointcut,但是该对象并无通知的情况下

                                private static final int NO_OVERRIDE = 2;                finalize对象析构方法

                                private static final int DISPATCH_TARGET = 3;            想请求转向到另一个目标

                                private static final int DISPATCH_ADVISED = 4;            目标转向

                                private static final int INVOKE_EQUALS = 5;                执行equal方法

                                private static final int INVOKE_HASHCODE = 6;            执行hashCode方法


                                可以看到:


                                    a、当开始在运行时织入动态字节码时,


                                    b、ProxyCallbackFilter中会根据:“方法名称,方法是否是析构函数,方法是否有通知等种种不同的类型”,返回0,1,2,3,4,5,6这样七个数字


                                    c、cglib根据返回的0,1,2,3,4,5,6分别选择Callbacks中对应的回调函数,将回调函数织入字节码中。


    4.6 将proxy注入singleObject单例缓存,即为最终的代理对象








以上内容,即为SpringAOP的CGLIB实现。


众所周知,SpringAOP有两种实现方式,


方式一为CGLIB,即:没有实现接口的类的代理,用CGLIB实现


方法二为JDK自带代理,即实现了某接口的类的代理,用JDK自带代理实现





代码位于DefaultAopProxyFactory





     public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {

            Class targetClass = config.getTargetClass();

            if (targetClass == null) {

                throw new AopConfigException(“TargetSource cannot determine target class: “ +

                        ”Either an interface or a target is required for proxy creation.”);

            }

            if (targetClass.isInterface()) {

                return new JdkDynamicAopProxy(config);

            }

            return CglibProxyFactory.createCglibProxy(config);

        }

        else {

            return new JdkDynamicAopProxy(config);

        }

    }