SpringFramework的ProxyFactory和ProxyFactoryBean实现分析

    在此记录下,以便后面用到,再者,若是须要还能够继续更新此文。有些细节步骤被我省略了,建议读者本身去读源码。java

1.ProxyFactory

    getProxy()方法,依据咱们对Proxy属性的设置,生成JdkDynamicAopProxy或者CglibAopProxy,咱们这里分析JdkDynamicAopProxy的场景。原图在Gtihub上。git

  • 步骤7处,是JDK的动态代理,当咱们调用方法时,实际执行的是JdkDynamicAopProxy的invoke方法。
  • 步骤13处,将advice转为adviceInterceptor。
  • 步骤19处,有递归,不断的处理咱们定义的Advice(咱们的定义的Advice会被放到一个List中),到最后,才执行真正被代理对象的方法。
  • 调用链的设计,有点奥妙,我的以为,待仔细分析。为何这么说,请看下以下三个类的invoke(MethodInvocation)方法。这种方式我在Spring-tx(事物模块)模块中看到过。
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor
org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor

 

2.ProxyFactoryBean

    ProxyFactoryBean不一样于ProxyFactory,ProxyFactoryBean是个FactoryBean(若是是熟悉这个interface接口的同窗看到这个应该能想到点什么了吧,这里),它有个getObject()方法,Spring IOC在容器中由BeanDefinition生成bean对象时,会调用此方法,将getObject()的返回值做为bean对象。因此咱们从getObjects()开始分析起。github

     这里咱们分析JdkDynamicAopProxy时候的场景。原图在Github上。spring

  • 步骤14,咱们在调用被代理对象的方法时,调用的是JdkDynamicAopProxy的invoke(),以后的操做就和ProxyFactory的同样了,看上面ProxyFactory的分析。
  • 注意步骤2中的实现,关键代码以下,这里interceptorNames中的值多数状况下是Spring bean的ID。

 

for (String name : this.interceptorNames) {
    if (logger.isTraceEnabled()) {
        logger.trace("Configuring advisor or advice '" + name + "'");
    }

    if (name.endsWith(GLOBAL_SUFFIX)) {
        if (!(this.beanFactory instanceof ListableBeanFactory)) {
            throw new AopConfigException(
                    "Can only use global advisors or interceptors with a ListableBeanFactory");
        }
        addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
                name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
    } else {
        Object advice;
        if (this.singleton || this.beanFactory.isSingleton(name)) {
            //name是bean的Id,因此从beanFactory中直接getBean()便可。
            advice = this.beanFactory.getBean(name);
        } else {
            // It's a prototype Advice or Advisor: replace with a prototype.
            // Avoid unnecessary creation of prototype bean just for advisor chain initialization.
            advice = new PrototypePlaceholderAdvisor(name);
        }
        //将获得的advice加入到拦截器链中
        addAdvisorOnChainCreation(advice, name);
    }
}

 

    还有不少关键点没有写出来,我我的以为仍是本身去看源码比较好,有些地方很难用有限的语言清晰的描述出来。this

 

3.Reference

  • SpringFramework-3.2.8.RELEASE。
  • 精通Spring 3.x 企业应用开发实战(虽然我的不喜欢精通二字,可是本书仍是比较好的,相对其它Spring书籍)。
相关文章
相关标签/搜索