spring aop 自动创建代理BeanNameAutoProxyCreator详解

本文详细解析了Spring AOP中BeanNameAutoProxyCreator的工作原理。通过XML配置示例展示了如何设置自动代理,并解释了从配置到执行目标方法过程中,Spring如何处理包括BeanPostProcessor在内的各个步骤,以及代理的创建过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码示例

<?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”)时就是调用代理后的方法了,就跟责任链差不多了

参考
BeanPostProcessor

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值