1. 程式人生 > >spring aop 自動建立代理BeanNameAutoProxyCreator詳解

spring aop 自動建立代理BeanNameAutoProxyCreator詳解

程式碼示例

<?xml version=”1.0” encoding=”UTF-8”?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:aop=”http://www.springframework.org/schema/aop”
xmlns:context=”http://www.springframework.org/schema/context”
xmlns:util=”http://www.springframework.org/schema/util”
xsi:schemaLocation=”

http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.2.xsd

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd“>
<context:component-scan base-package=”org.bear.bookstore.test.aop”></context:component-scan>
<!– 自動建立代理 –>
<bean class=”org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator”>
<property name=”beanNames”><value>aopS*</value></property>
<property name=”interceptorNames”>
<list>
<value>debugInterceptor</value>
</list>
</property>
</bean>
</beans>

@Component("aopService")
public class AopService {

    public void set(String name){
        System.out.println(name);
    }
}
```
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        locations={"file:src/test/resources/spring-aop.xml"}
        )
public class AopTest {

    @Autowired ApplicationContext ctx;

    //@Test
    public void debugTest(){
        AopService ser = (AopService)ctx.getBean("proxyFactory");
        ser.set("zh");
    }

    @Autowired AopService aopService;

    @Test
    public void debug1Test(){
        aopService.set("zh11");
    }
}

aopService.set(“zh11”);執行這一句前後spring幹了什麼事情

剖析

類關係
看到BeanPostProcessor後,心安了,知道咱們配置的BeanNameAutoProxyCreator是什麼時候執行什麼樣的方法了
BeanNameAutoProxyCreator.getAdvicesAndAdvisorsForBean決定是否需要建立代理,通過names過濾

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
        if (this.beanNames != null) {
            for (String mappedName : this.beanNames) {
                if (FactoryBean.class.isAssignableFrom(beanClass)) {
                    if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
                        continue;
                    }
                    mappedName = mappedName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
                }
                if (isMatch(beanName, mappedName)) {
                    return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
                }
                BeanFactory beanFactory = getBeanFactory();
                if (beanFactory != null) {
                    String[] aliases = beanFactory.getAliases(beanName);
                    for (String alias : aliases) {
                        if (isMatch(alias, mappedName)) {
                            return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
                        }
                    }
                }
            }
        }
        return DO_NOT_PROXY;
    }

AbstractAutoProxyCreator.wrapIfNecessary方法,暴露是否需要建立代理的方法供子類使用

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // 是否需要建立代理
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            //關鍵建立代理的地方
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

AbstractAutoProxyCreator.createProxy方法建立代理的準備工作

protected Object createProxy(
            Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
        //AopProxyUtils
    /**
     * Bean definition attribute that indicates the original target class of an
     * auto-proxied bean, e.g. to be used for the introspection of annotations
     * on the target class behind an interface-based proxy.
     * @since 4.2.3
     * @see #determineTargetClass
     */
    /*public static final String ORIGINAL_TARGET_CLASS_ATTRIBUTE =
            Conventions.getQualifiedAttributeName(AutoProxyUtils.class, "originalTargetClass");*/
        //儲存代理類真實的型別org.springframework.beans.factory.BeanFactory#getType(String)用
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        //初始化advisor,也就是interceptorNames
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        for (Advisor advisor : advisors) {
            proxyFactory.addAdvisor(advisor);
        }

        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        //真正建立代理方法
        return proxyFactory.getProxy(getProxyClassLoader());
    }
public Object getProxy(ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

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

//DefaultAopProxyFactory
@Override
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.");
        }
        //如果是介面類或者代理類則通過jdk動態代理來實現
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            //最後用的就是Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
            return new JdkDynamicAopProxy(config);
        }
        //用的就是使用的Cglib了
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

初始化完成後,執行aopService.set(“zh11”)時就是呼叫代理後的方法了,就跟責任鏈差不多了