Spring AOP原理之建立AopProxy代理对象

导读:本篇文章讲解 Spring AOP原理之建立AopProxy代理对象,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

在Spring AOP实现中,使用的核心技术是动态代理,而这种动态代理实际上是JDK的一个特性(在JDK 1.3以上的版本里,实现了动态代理模式)。通过JDK的动态代理特性,可以为任意Java对象创建代理对象,对于具体使用来说,这个特性是通过Java Reflection API来完成的。

看此篇文章之前,可以先看看 JDK动态代理机制,对动态代理有个基础的了解先。

设计原理

ProxyFactory的设计为中心,可以看到相关的类继承关系如图所示:
Spring AOP原理之建立AopProxy代理对象

  • ProxyConfig里面封装了数据,为子类提供配置属性。
  • AdvisedSupport封装了AOP对通知Advice(Advice)和通知器(Advisor)的相关操作。这些操作对于不同的AOP的代理对象的生成都是一样的。但对于其体的AOP代理对象的创建,AdvisedSupport把它交始它的子类们去完成。
  • 对于ProxyCreatorSupport.可以将它看成是其子类创建AOP代理对象的一个辅助类。通过继承以上提到的‘类的功能实现。
  • 具体的AOP代理对象的生成,根据不同的需要,分别由ProxyFactoryBean, AspcctiProxyFactoryProxyFactory来完成。对于需要使用AspectJ的AOP应用,AspectJProxyFactory起到集成Spring和AspectJ的作用。对于使用Spring AOP的应用,ProxyFactoryBean和ProxyFactoy都提供了AOP功能的封装。

ProxyFactoryBean生成AopProxy代理对象

ProxyFactoryBean的^OP实现需要依翰JDK或者CGLIB提供的Proxy特性。从FactoryBean中获取对象.是以getObject()方法作为入口完成的。
先看AopProxy生成过程的时序图:
Spring AOP原理之建立AopProxy代理对象

ProxyFactoryBean的入口getObject()开始:

  public Object getObject() throws BeansException {
        //初始化通知链
        this.initializeAdvisorChain();
        //这里对Singleton和prototype的类型进行区分,生成对应的proxy
        if (this.isSingleton()) {
            return this.getSingletonInstance(); //生成singleton的代理对象
        } else {
            if (this.targetName == null) {
                this.logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
            }

            return this.newPrototypeInstance();  //生成prototype的代理对象
        }
    }

  //初始化通知链
  private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
        if (!this.advisorChainInitialized) {
            if (!ObjectUtils.isEmpty(this.interceptorNames)) {
                if (this.beanFactory == null) {
                    throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) - cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
                }

                if (this.interceptorNames[this.interceptorNames.length - 1].endsWith("*") && this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
                    throw new AopConfigException("Target required after globals");
                }

                String[] var1 = this.interceptorNames;
                int var2 = var1.length;

                //添加advisors 链的调用,通过interceptorNames属性进行配置,interceptorNames通过IoC从配置bean中读取而来
                for(int var3 = 0; var3 < var2; ++var3) {
                    String name = var1[var3];
                    if (this.logger.isTraceEnabled()) {
                        this.logger.trace("Configuring advisor or advice '" + name + "'");
                    }

                    if (name.endsWith("*")) {
                        if (!(this.beanFactory instanceof ListableBeanFactory)) {
                            throw new AopConfigException("Can only use global advisors or interceptors with a ListableBeanFactory");
                        }

                        this.addGlobalAdvisor((ListableBeanFactory)this.beanFactory, name.substring(0, name.length() - "*".length()));
                    } else {
                        Object advice;
                        if (!this.singleton && !this.beanFactory.isSingleton(name)) {
                            advice = new ProxyFactoryBean.PrototypePlaceholderAdvisor(name);
                        } else {
                            advice = this.beanFactory.getBean(name);
                        }

                        this.addAdvisorOnChainCreation(advice, name);
                    }
                }
            }

            this.advisorChainInitialized = true;
        }

    //生成singleton的代理对象
    private synchronized Object getSingletonInstance() {
        if (this.singletonInstance == null) {
            this.targetSource = this.freshTargetSource();
            if (this.autodetectInterfaces && this.getProxiedInterfaces().length == 0 && !this.isProxyTargetClass()) {
                //根据AOP框架来判断需要代理的接口
                Class<?> targetClass = this.getTargetClass();
                if (targetClass == null) {
                    throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
                }
                //设置代理对象的接口
                this.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
            }

            super.setFrozen(this.freezeProxy);
            //使用ProxyFactory来生成需要的Proxy,  createAopProxy是其父亲中实现的方法
            this.singletonInstance = this.getProxy(this.createAopProxy());
        }

        return this.singletonInstance;
    }   

    //通过createAopProxy返回的AopProxy来得到代理对象
     protected Object getProxy(AopProxy aopProxy) {
        return aopProxy.getProxy(this.proxyClassLoader);
    }

看看ProxyCreatorSupport的创建AopProxy对象:

    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            this.activate();
        }
        //使用AopProxyFactory来取得AopProxy对象,AopProxyFactory是在构造函数中定义的,用的是DefaultAopProxyFactory
        return this.getAopProxyFactory().createAopProxy(this);
    }   

     public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

接着是DefaultAopProxyFactory中的createAopProxy

 public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            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.");
            } else {
            //如果targetClass是接口,使用JDK来生成,否者使用CGLIB来生成
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

通过上面的时序图和源码分析,可以看出ProxyFactoryBean生成AopProxy代理对象的基本过程。

前面介绍的ProxyFactoryBeanAopProxy代理对象和IoC容器配置之间起到了桥梁的作用。AopProxy代理对象可以由JDKCGLIB来生成。而JdkDynamicAopProxyCglibAopProxy实现的都是通过AopProxy接口。他们的继承关系如下:

Spring AOP原理之建立AopProxy代理对象

JDK生成AopProxy代理对象

源码如下:

 public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }

        //从advised对象中取得代理对象的代理接口配置
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        //调用JDK生成代理对象
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

在生成代理对象时,需要指明三个参数,一个是类装载器,一个是代理接口,另外一个就是Proxy回调方法所在的对象,这个对象需要实现InvocationHandler接口。

CGLIB生成AopProxy代理对象

源码如下:


public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
        }
        //从advised中取得在IoC容器中配里的target对象
        try {
            Class<?> rootClass = this.advised.getTargetClass();
            Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
            Class<?> proxySuperClass = rootClass;
            int x;
            if (ClassUtils.isCglibProxyClass(rootClass)) {
                proxySuperClass = rootClass.getSuperclass();
                Class<?>[] additionalInterfaces = rootClass.getInterfaces();
                Class[] var5 = additionalInterfaces;
                int var6 = additionalInterfaces.length;

                for(x = 0; x < var6; ++x) {
                    Class<?> additionalInterface = var5[x];
                    this.advised.addInterface(additionalInterface);
                }
            }

            this.validateClassIfNecessary(proxySuperClass, classLoader);
            //验证代理对象的接口设置
            //创建并配置CGLIB的Enhancer.这个Enhancer对象是CGLIB的主要操作类
            Enhancer enhancer = this.createEnhancer();
            if (classLoader != null) {
                enhancer.setClassLoader(classLoader);
                if (classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) {
                    enhancer.setUseCache(false);
                }
            }
            //设置Enhancer对象,包括设置代理接口,回调方法
            //来自advised的IoC配置,比如使用AOP的DynamicAdvisedlnterceptor拦截器
            enhancer.setSuperclass(proxySuperClass);
            enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            enhancer.setStrategy(new CglibAopProxy.ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
            Callback[] callbacks = this.getCallbacks(rootClass);
            Class<?>[] types = new Class[callbacks.length];

            for(x = 0; x < types.length; ++x) {
                types[x] = callbacks[x].getClass();
            }

            enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);
            //通过Enhancer生成代理对象
            return this.createProxyClassAndInstance(enhancer, callbacks);
        } catch (IllegalArgumentException | CodeGenerationException var9) {
            throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", var9);
        } catch (Throwable var10) {
            throw new AopConfigException("Unexpected AOP exception", var10);
        }
    }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16066.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!