`
hotforcc
  • 浏览: 60602 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring ProxyFactoryBean是如何代理Class分析

阅读更多

1ProxyFactoryBean proxy的创建交给AopProxy去做。

ProxyFactoryBean.javajava 代码

java 代码
  1. public class ProxyFactoryBean extends AdvisedSupport   
  2.   
  3.     implements FactoryBean, BeanFactoryAware, AdvisedSupportListener {   
  4.   
  5.             public Object getObject() throws BeansException {   
  6.   
  7.                         //invoke AopProxy 去 创建proxy   
  8.   
  9.                         return this.singleton ? getSingletonInstance() : newPrototypeInstance();   
  10.   
  11.             }       
  12.   
  13.             //inherited from ProxyConfig   
  14.   
  15.             public void setAopProxyFactory(AopProxyFactory apf) {   
  16.   
  17.                         this.aopProxyFactory = apf;   
  18.   
  19.             }   
  20.   
  21.             //inherited from ProxyConfig   
  22.   
  23.             public AopProxyFactory getAopProxyFactory() {   
  24.   
  25.                         return this.aopProxyFactory;   
  26.   
  27.             }   
  28.   
  29. }   
  30.   

2.、那么AopProxy又如何获取?答案是从AopProxyFactory获得。这个AopProxyFactory已在ProxyFactoryBean掌控范围内,如上述代码所示。AopProxyFactory interface如下所示:

AopProxyFactory.java

java 代码

 

  1. public interface AopProxyFactory {      
  2.   
  3.             AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException;   
  4.   
  5.     
  6.   
  7. }  

3AopProxy是如何introduce Advised interface的?那要先从AopProxyFactoryimplementation说起。

AopProxyFactory的实现类目前只有DefaultAopProxyFactory。这个类的核心方法如下:

           

java 代码

 

  1. public AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException {   
  2.   
  3.           if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass() ||   
  4.   
  5.          advisedSupport.getProxiedInterfaces().length == 0) {   
  6.   
  7.                       if (!cglibAvailable) {   
  8.   
  9.                                  throw new AopConfigException(   
  10.   
  11.                                   "Cannot proxy target class because CGLIB2 is not available. " +   
  12.   
  13.                                   "Add CGLIB to the class path or specify proxy interfaces.");   
  14.   
  15.                       }   
  16.   
  17.                       return CglibProxyFactory.createCglibProxy(advisedSupport);   
  18.   
  19.             } else {   
  20.   
  21.                                     eturn new JdkDynamicAopProxy(advisedSupport);   
  22.   
  23.             }   
  24.   
  25.  }   
  26.   

这个方法主要是依赖CglibProxyFactory 类和JdkDynamicAopProxy类。这两个类是如何代理所有的接口的呢?

这两个类都是重要接口AopProxy的实现类,这个接口的核心方法是

java 代码
  1. public Object getProxy(ClassLoader classLoader)。   
  2.   
  3. 其中JdkDynamicAopProxy实现该方法用到的获取需要代理的接口的代码如下:   
  4.   
  5. public Object getProxy(ClassLoader classLoader) {   
  6.   
  7.           if (logger.isDebugEnabled()) {   
  8.   
  9.                       Class targetClass = this.advised.getTargetSource().getTargetClass();   
  10.   
  11.                       logger.debug("Creating JDK dynamic proxy" +   
  12.   
  13.                       (targetClass != null ? " for [" + targetClass.getName() + "]" : ""));   
  14.   
  15.            }   
  16.   
  17.            Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);   
  18.   
  19.            return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);   
  20. }   
  21.   
  22.     

           

java 代码

 

  1. public Object getProxy(ClassLoader classLoader) {   
  2.   
  3.           Enhancer enhancer = new Enhancer();                          
  4.   
  5.           enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));   
  6. }   
  7.   

 

从上面可以看出,这两个AopProxy实现方案在获取接口时都是通过AopProxyUtils.completeProxiedInterfaces(this.advised)获取的。该方法如下:

            Advised  interface的实现。前提是是否允许代理该interafce,这由isOpaque方法确定,该方法Return whether proxies created by this configuration should be prevented from being cast to Advised.

java 代码

 

  1. /**  
  2. * Get complete set of interfaces to proxy. This will always add the Advised interface  
  3.  
  4.  * unless the AdvisedSupport's "opaque" flag is true.  
  5.  
  6.  * @return the complete set of interfaces to proxy  
  7.  
  8.  */  
  9.   
  10.  public static Class[] completeProxiedInterfaces(AdvisedSupport advised) {   
  11.   
  12.              // Won't include Advised, which may be necessary.   
  13.   
  14.              Class[] specifiedInterfaces = advised.getProxiedInterfaces();   
  15.   
  16.              Class[] proxiedInterfaces = specifiedInterfaces;   
  17.   
  18.               if (!advised.isOpaque() && !advised.isInterfaceProxied(Advised.class)) {   
  19.   
  20.                         // We need to add the Advised interface.   
  21.   
  22.                          proxiedInterfaces = new Class[specifiedInterfaces.length + 1];   
  23.   
  24.                          proxiedInterfaces[0] = Advised.class;   
  25.   
  26.                          System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 1,specifiedInterfaces.length);   
  27.   
  28.               }   
  29.   
  30.               return proxiedInterfaces;   
  31.   
  32. }   
  33.   

从这可以看出,是在这强制加了对

4. 顺便提一下,Advised interface的具体实现又是怎样的,在哪呢?

4.1 JdkDynamicAopProxy里,

 

 

  1. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
  2.           if (Advised.class == method.getDeclaringClass()) {   
  3.                          // service invocations on ProxyConfig with the proxy config   
  4.                          return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);   
  5.            }   
  6. }   

注意第一个参数是

AdisedSupport extends ProxyConfig implements Advised,也就是说Advised的默认实现就是AdisedSupport

 

4.2 Cglib2AopProxy

 

           

  1. public Object getProxy(ClassLoader classLoader) {   
  2.   
  3. Enhancer enhancer = new Enhancer();   
  4.   
  5. enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised));   
  6.   
  7. Callback[] callbacks = getCallbacks(rootClass);   
  8.   
  9. }   
  10.   
  11. private Callback[] getCallbacks(Class rootClass) throws Exception {   
  12.   
  13.             Callback[] mainCallbacks = new Callback[]{   
  14.   
  15.             aopInterceptor, // for normal advice   
  16.   
  17.             targetInterceptor, // invoke target without considering advice, if optimized   
  18.   
  19.             new SerializableNoOp(), // no override for methods mapped to this   
  20.   
  21.             targetDispatcher, this.advisedDispatcher,   
  22.   
  23.             new EqualsInterceptor(this.advised)   
  24.   
  25.                };   
  26. }   
  27.   
  28.     
  29.   
  30. private class ProxyCallbackFilter implements CallbackFilter {   
  31.   
  32. public int accept(Method method) {   
  33.   
  34.              if (method.getDeclaringClass() == Advised.class) {   
  35.   
  36.                         if (logger.isDebugEnabled()) {   
  37.   
  38.                                       logger.debug("Method " + method + " is declared on Advised -    using      DISPATCH_ADVISED");   
  39.   
  40.                          }   
  41.   
  42.                          return DISPATCH_ADVISED;// DISPATCH_ADVISED 值为4.   
  43.   
  44.                }   
  45.   
  46. }   
  47.   
  48. }   
  49.   
  50.     
  51.   
  52. private final transient AdvisedDispatcher advisedDispatcher = new AdvisedDispatcher();   
  53.   
  54. /**  
  55.  * Dispatcher for any methods declared on the Advised class.  
  56. */  
  57.  private class AdvisedDispatcher implements Dispatcher, Serializable {   
  58.  public Object loadObject() throws Exception {   
  59.                                     return advised;   
  60.   }   
  61.   
  62.   }   
  63.   
  64.     

注意

 
Dispatcher extends Callback interface

java 代码
this.advised,其实就是ProxyFactoryBean本身,注意在我发表的其天的Spring文章里也曾提到,ProxyFactoryBean extends AdvisedSupport

java 代码
CglibProxyFactorygetProxy(ClassLoader classLoader)方法如下:

分享到:
评论
1 楼 yxgd 2008-06-12  

相关推荐

    Spring

    class="org.springframework.aop.framework.ProxyFactoryBean"> <!--这里的必须要指定接口 --> <value>org.nitpro.aop.BizInterface <!--业务处理节点名称和拦截器名称必须都要定义, 必须将拦截器的对象...

    Spring-Reference_zh_CN(Spring中文参考手册)

    7.5. 使用ProxyFactoryBean创建AOP代理 7.5.1. 基础 7.5.2. JavaBean属性 7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”advisor 7.6. 简化代理定义 7.7. 使用...

    Spring 2.0 开发参考手册

    7.5. 使用ProxyFactoryBean创建AOP代理 7.5.1. 基础 7.5.2. JavaBean属性 7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”advisor 7.6. 简化代理定义 7.7. ...

    spring aop 实现源代码--xml and annotation(带lib包)

    并定义了一个 org.springframework.aop.framework.ProxyFactoryBean对象(messageSender),FactoryBean或ApplicationContext将使用ProxyFactoryBean来建立代理对象,在这里就是messageSenderImpl建立代理对象。...

    Spring中文帮助文档

    7.5. 使用ProxyFactoryBean创建AOP代理 7.5.1. 基础 7.5.2. JavaBean属性 7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”通知器 7.6. 简化代理定义 7.7. 使用...

    spring chm文档

    7.5. 使用ProxyFactoryBean创建AOP代理 7.5.1. 基础 7.5.2. JavaBean属性 7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”advisor 7.6. 简化代理定义 7.7. ...

    spring-xmemcached

    <bean id="cacheProxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <value>cacheBeforeAdvice <value>cacheAfterAdvice <value>cacheInterceptor</value> ...

    Spring API

    7.5. 使用ProxyFactoryBean创建AOP代理 7.5.1. 基础 7.5.2. JavaBean属性 7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”通知器 7.6. 简化代理定义 7.7. 使用...

    SPRING API 2.0.CHM

    ProxyFactoryBean ProxyMethodInvocation QuartzJobBean QuickTargetSourceCreator RadioButtonTag RdbmsOperation ReaderContext ReaderEventListener RecordCreator RecordExtractor ...

    spring-framework-reference-4.1.2

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    spring-framework-reference4.1.4

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

Global site tag (gtag.js) - Google Analytics