AOP代理对象的生成

在声明式的AOP中,我们定义了一个ProxyFactoryBean来生成代理对象,在Spring配置文件中的配置如下:

<bean id="beanA" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="beanAImpl" />
    <property name="interceptorNames" value="testAdvisor" />
    <property name="proxyInterfaces" value="com.alibaba.khotyn.test.BeanInterface">
</property>

而ProxyFactoryBean之所以叫做ProxyFactoryBean是因为它继承了FactoryBean,所以要知道关于AOP的代理对象如何生成,只需要关注ProxyFactoryBean的getObeject()方法即可,我们先来看一下它的实现:

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.");
        }
        // 获取Prototype对象
        return newPrototypeInstance();
    }
}

这里面两个关键的方法是getSingletonInstance()和newPrototypeInstance(),看下这两个方法的实现:

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.
            setInterfaces(ClassUtils.getAllInterfacesForClass(this.targetSource.getTargetClass()));
        }
        // Eagerly initialize the shared singleton instance.
        super.setFrozen(this.freezeProxy);
        // 创建一个AopProxy,然后通过它获取到代理对象
        this.singletonInstance = getProxy(createAopProxy());
        // We must listen to superclass advice change events to recache the singleton
        // instance if necessary.
        addListener(this);
    }
    return this.singletonInstance;
}

从这段代码中看出,Spring是首先创建一个AopProxy对象(JdkDynamicAopProxy或者是Cglib2AopProxy),然后通过它来创建出真正的代理对象(JdkDynamicAopProxy,Cglib2AopProxy分别根据自己的方法来创建对象),而newPrototypeInstance()方法的实现和getSingletonInstance()的实现类似,这里不做赘述。