今天看啥  ›  专栏  ›  涣涣虚心0215

Spring AOP(2)代理类的创建ProxyFactoryBean

涣涣虚心0215  · 简书  ·  · 2021-01-04 22:17

文章预览

ProxyFactory

Spring IOC(9) 里面介绍了三级缓存的时候,提到了AOP创建代理类的内容,有两个地方会去调用AbstractAutoProxyCreator.wrapIfNecessary()去创建代理类。

  1. 在解析wrapIfNecessary之前先看一下上面的图,分析一些基础的类:
  • Advised
    Advised要提供了Advice和Advisor的管理。
Advised
  • AdvisedSupport
    Advised的实现类,从代码里就能看出Advice会被封装成DefaultIntroductionAdvisor。
public void addAdvice(int pos, Advice advice) throws AopConfigException {
    Assert.notNull(advice, "Advice must not be null");
    if (advice instanceof IntroductionInfo) {
        // We don't need an IntroductionAdvisor for this kind of introduction:
        // It's fully self-describing.
        addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice));
    }
    else if (advice instanceof DynamicIntroductionAdvice) {
        // We need an IntroductionAdvisor for this kind of introduction.
        throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor");
    }
    else {
        addAdvisor(pos, new DefaultPointcutAdvisor(advice));
    }
}
private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException {
    Assert.notNull(advisor, "Advisor must not be null");
    if (isFrozen()) {
        throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
    }
    if (pos > this.advisors.size()) {
        throw new IllegalArgumentException(
                "Illegal position " + pos + " in advisor list with size " + this.advisors.size());
    }
    this.advisors.add(pos, advisor);
    updateAdvisorArray();
    adviceChanged();
}
  • ProxyCreatorSupport
    实现了AdvisedSupport,同时定义了AopProxyFactory的成员变量(默认实现 DefaultAopProxyFactory ),所以ProxyCreatorSupport提供了通过AopProxy获得proxy的能力。
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.");
        }
        //如果目标类是有实现接口的,或者targetClass是由Proxy创建的(JDK代理)
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        //否则通过Cglib方式创建动态代理
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}
  • ProxyFactory
    在ProxyCreatorSupport提供了获取AopProxy能力之后,ProxyFactory就提供通过AopProxy获取Proxy实例的能力createAopProxy().getProxy()。


    ProxyFactory
  • ProxyFactoryBean
    ProxyFactoryBean不仅仅继承了ProxyCreatorSupport也有获得Proxy的能力,另外ProxyFactoryBean还实现了FactoryBean(FactoryBean的注意事项,FactoryBean在通过getBean()生成实例的时候,是默认调用getObject()创建需要的bean,如果想要FactoryBean本身的实例,需要加上&符号),所以这里默认调用getObject()方法来创建proxy对象。

  1. 正确的使用ProxyFactoryBean:
<bean id="subject" class="com.gary.spring.proxy.RealSubject" />
<bean id="testAdvice" class="com.gary.spring.proxy.TestAdvice" />
<bean id="subjectProxy" class="org.springframework.aop.framework.ProxyFactoryBean" >
    <property name="proxyInterfaces">
        <value>com.gary.spring.proxy.Subject</value>
    </property>
    <property name="interceptorNames">
        <list>
            <value>testAdvice</value>
        </list>
    </property>
    <property name="target">
        <ref bean="subject"/>
    </property>
</bean>
//这里直接通过getBean获取ProxyFactoryBean的实例,会默认调用getObject()方法生成代理对象
Subject subject = (Subject) beanFactory.getBean("subjectProxy");
subject.sayName();

这里面声明了三个bean,一个真实对象RealSubject,一个Advice,还有一个ProxyFactoryBean。
三个bean创建的时机是不一样的,测试main通过getBean()创建subjectProxy,在populateBean的时候,会去创建subject对应的bean,而testAdvice是在initializeAdvisorChain的过程中通过getBean()进行实例化。

  1. ProxyFactoryBean生成Proxy代码解析
  • FactoryBean.getObject()代码
public Object getObject() throws BeansException {
    //调用initializeAdvisorChain来初始化Advisor
    initializeAdvisorChain();
    if (isSingleton()) {
        return getSingletonInstance();
    }
    else {
        if (this.targetName == null) {
            logger.info("Using non-singleton proxies with singleton targets is often undesirable. " +
                    "Enable prototype proxies by setting the 'targetName' property.");
        }
        return newPrototypeInstance();
    }
}   
  • initializeAdvisorChain解析:
    这里主要涉及Advice实例的创建,如果是单例的,就通过this.beanFactory.getBean(name)创建Advice实例。
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
    //在xml里面设置了interceptorNames
    if (!ObjectUtils.isEmpty(this.interceptorNames)) {
        //所以这里会遍历interceptorNames,创建所需要的Advisor
        // Materialize interceptor chain from bean names.
        for (String name : this.interceptorNames) {
            //处理全局的Advisor
            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()));
            }
            //处理对应的Advisor
            else {
                // If we get here, we need to add a named interceptor.
                // We must check if it's a singleton or prototype.
                Object advice;
                if (this.singleton || this.beanFactory.isSingleton(name)) {
                    // Add the real Advisor/Advice to the chain.
                    //如果是单例的,就通过getBane(beanName)获得Advice
                    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.
                    //否则就通过property方式创建Advisor
                    advice = new PrototypePlaceholderAdvisor(name);
                }
                //将Advice,Advisor或者object添加到interceptor 列表
                addAdvisorOnChainCreation(advice, name);
            }
        }
    }

    this.advisorChainInitialized = true;
}
  • 创建完Advice实例之后,调用addAdvisorOnChainCreation将Advice转换成Advisor。
    advisorAdapterRegistry默认是DefaultAdvisorAdapterRegistry。

//将Advice,Advisor或者object添加到interceptor 列表
private void addAdvisorOnChainCreation(Object next, String name) {
    // We need to convert to an Advisor if necessary so that our source reference
    // matches what we find from superclass interceptors.
    Advisor advisor = namedBeanToAdvisor(next);
    if (logger.isTraceEnabled()) {
        logger.trace("Adding advisor with name '" + name + "'");
    }
    addAdvisor(advisor);
}
//通过advisorAdapterRegistry将Advice转换或者wrapper成Advisor
private Advisor namedBeanToAdvisor(Object next) {
    try {
        return this.advisorAdapterRegistry.wrap(next);
    }
    catch (UnknownAdviceTypeException ex) {
        // We expected this to be an Advisor or Advice,
        // but it wasn't. This is a configuration error.
        throw new AopConfigException("Unknown advisor type " + next.getClass() +
                "; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
                "which may also be target or TargetSource", ex);
    }
}
//将Advice包装wrapper成Advisor
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
    //如果adviceObject就是Advisor,就直接返回,不需要包装
    if (adviceObject instanceof Advisor) {
        return (Advisor) adviceObject;
    }
    //如果adviceObject不是Advice类型,就报错,因为MethodInteceptor也是Advice的子类
    if (!(adviceObject instanceof Advice)) {
        throw new UnknownAdviceTypeException(adviceObject);
    }
    Advice advice = (Advice) adviceObject;
    //如果是MethodInteceptor,就直接包装成DefaultPointcutAdvisor
    if (advice instanceof MethodInterceptor) {
        // So well-known it doesn't even need an adapter.
        return new DefaultPointcutAdvisor(advice);
    }
    //如果是正常的Advice实现,就需要通过adapters来验证是不是支持该Advice
    for (AdvisorAdapter adapter : this.adapters) {
        // Check that it is supported.
        if (adapter.supportsAdvice(advice)) {
            return new DefaultPointcutAdvisor(advice);
        }
    }
    throw new UnknownAdviceTypeException(advice);
}
  • Advisor都加载好之后,调用getSingletonInstance来创建代理类。
    需要注意的是JdkDynamicAopProxy内部有AdvisedSupport advised成员变量,所以在通过ProxyCreatorSupport构建JdkDynamicAopProxy的时候需要传入this,因为ProxyCreatorSupport继承自AdvisedSupport。
    AdvisedSupport内部有List<Advisor> advisors,所以Advice以及Advisor都会被转化成Advisor保存在该list内部。
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);
        //调用ProxyCreatorSupport.createAopProxy()来获取AopProxy,再通过AopProxy获取Proxy实例
        this.singletonInstance = getProxy(createAopProxy());
    }
    return this.singletonInstance;
}
//父类ProxyCreatorSupport.createAopProxy()创建AopProxy
protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        activate();
    }
     //注意这里是将this传入,即AdvisedSupport实例
    return getAopProxyFactory().createAopProxy(this);
}
protected Object getProxy(AopProxy aopProxy) {
    return aopProxy.getProxy(this.proxyClassLoader);
}

再回顾一下FactoryBean的getObject流程:
正常beanFactory.getBean("subjectProxy")创建的是ProxyFactoryBean,在populateBean的过程中,创建subject的实例,在这之后会调用getObjectForBeanInstance()方法,这里面就是Bean和FactoryBean的区别之处:

protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

    // Don't let calling code try to dereference the factory if the bean isn't a factory.
    //isFactoryDereference会检查beanName是不是&打头的,如果是,就直接返回FactoryBean实例,而不是getObject()生成的实例
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
        }
    }

    // Now we have the bean instance, which may be a normal bean or a FactoryBean.
    // If it's a FactoryBean, we use it to create a bean instance, unless the
    // caller actually wants a reference to the factory.
    //  如果不是FactoryBean,就直接返回
    // 或者isFactoryDereference,即beanName是&打头的,也就直接返回bean
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }
    //如果是FactoryBean,就通过getObject()方法,返回真正需要的实例对象
    Object object = null;
    if (mbd == null) {
        object = getCachedObjectForFactoryBean(beanName);
    }
    if (object == null) {
        // Return bean instance from factory.
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // Caches object obtained from FactoryBean if it is a singleton.
        if (mbd == null && containsBeanDefinition(beanName)) {
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

上述流程简述了利用ProxyFactoryBean来创建代理对象的过程,通过XML来演示会比较直白,下面就通过spring aop配置看看是如何创建代理对象。

………………………………

原文地址:访问原文地址
快照地址: 访问文章快照
总结与预览地址:访问总结与预览