Spring AOP获取Proxy对象的代码流程

前面一篇给出了一个模拟springAOP的小例子,大家可以看到大概流程,今天我们从spring源码中分析获取Proxy对象的代码流程

 

当我们有了advice和pointcut之后,需要一个通知器来通知在哪应用切点以及一些处理动作advice。

我们会通过ProxyFactoryBean来配置我们的代理对象和方面行为,获得代理对象即靠下面的代码

public Object getObject() throws BeansException { //初始化通知器链 initializeAdvisorChain(); if (isSingleton()) { return getSingletonInstance(); } else { if (this.targetName == null) { logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " + "Enable prototype proxies by setting the 'targetName' property."); } return newPrototypeInstance(); } }

 

生成单例代理对象getSingletonInstance

private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // Rely on AOP infrastructure to tell us what interfaces to proxy. Class targetClass = getTargetClass(); if (targetClass == null) { throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy"); } setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } // Initialize the shared singleton instance. super.setFrozen(this.freezeProxy); //生成我们需要的Proxy this.singletonInstance = getProxy(createAopProxy()); } return this.singletonInstance; }

 

我们接着看这个方法createAopProxy

/** * Subclasses should call this to get a new AOP proxy. They should <b>not</b> * create an AOP proxy with <code>this</code> as an argument. */ protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }

然后进入AopProxy org.springframework.aop.framework.AopProxyFactory.createAopProxy(AdvisedSupport config)

Create an AopProxy for the given AOP configuration.

 

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { //如果目标类不是接口,进入cglib的方法 if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class targetClass = config.getTargetClass(); //如果没有cglib的包 抛出异常 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); } if (!cglibAvailable) { throw new AopConfigException( "Cannot proxy target class because CGLIB2 is not available. " + "Add CGLIB to the class path or specify proxy interfaces."); } //返回cglib类型的AopProxy return CglibProxyFactory.createCglibProxy(config); } else { //如果目标类为接口,返回JDK类型的AopProxy return new JdkDynamicAopProxy(config); } }

 

JDK类型的AopProxy的方法如下

public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); //生成需要的Proxy实例 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }

 

 

下面为cglib类型的AopProxy方法

public static AopProxy createCglibProxy(AdvisedSupport advisedSupport) { return new Cglib2AopProxy(advisedSupport); } /** * Create a new Cglib2AopProxy for the given AOP configuration. * @param config the AOP configuration as AdvisedSupport object * @throws AopConfigException if the config is invalid. We try to throw an informative * exception in this case, rather than let a mysterious failure happen later. */ public Cglib2AopProxy(AdvisedSupport config) throws AopConfigException { Assert.notNull(config, "AdvisedSupport must not be null"); if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) { throw new AopConfigException("No advisors and no TargetSource specified"); } this.advised = config; this.advisedDispatcher = new AdvisedDispatcher(this.advised); }

 

      这样用Proxy包装target之后,通过ProxyFactoryBean得到对其方法的调用就被Proxy拦截了, ProxyFactoryBean的getObject()方法得到的
实际上是一个Proxy了,我们的target对象已经被封装了。对 ProxyFactoryBean这个工厂bean而言,其生产出来的对象是封装了目标对
象的代理对象。

 

参考资料:《Spring技术内幕 - 深入解析Spring架构与设计原理》 ,spring源码。

你可能感兴趣的:(spring,AOP,object,ClassLoader,null,Class)