Spring AOP-BeanNameAutoProxyCreator原理

以BeanNameAutoProxyCreator为例,AOP源码解读 (4.1.14.RELEASE)

Demo如下

目标类

public interface HelloService {
   
    void sayHello();
}

public class HelloServiceImpl implements HelloService{
   
    public void sayHello() {
   
        System.out.println("Hello");
    }
}

拦截器

public class PrintInterceptor implements MethodInterceptor {
   

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
   
        System.out.println("print before");
        invocation.proceed();
        System.out.println("print after");
        return invocation;
    }
}

public class PrintInterceptor2 implements MethodBeforeAdvice {
   

    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
   
        System.out.println("before");
    }
}

配置

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="beanNames">
        <list>
            <value>helloService</value>
        </list>
    </property>
    <property name="interceptorNames">
        <list>
            <value>printInterceptor</value>
            <value>printInterceptor2</value>
        </list>
    </property>
<!--        <property name="optimize" value="true"/>-->
<!--        <property name="proxyTargetClass" value="true"/>-->
</bean>
<bean id="helloService" class="com.zww.spring.bean.HelloServiceImpl"/>
<bean id="printInterceptor" class="com.zww.spring.PrintInterceptor"/>
<bean id="printInterceptor2" class="com.zww.spring.PrintInterceptor2"/>

开始分析

分析之前先看核心类BeanNameAutoProxyCreator相关的UML图

image-20240327104656294

BeanNameAutoProxyCreator 继承自AbstractAutoProxyCreator 从而实现了 InstantiationAwareBeanPostProcessor和BeanPostProcessor。在bean实例化之前和bean初始化之后有两次机会将其包装成代理对象。

具体是bean的实例化过程会走到AbstractAutowireCapableBeanFactory#createBean方法, 在此方法内会给后置处理器一次生成代理类bean代替原bean的机会, 另外在bean的初始化过程中doCreateBean方法内部也会提供一次初始化后置处理器生成代理类的机会。(本文引用代码均已删减)

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args){
   
   // 第一次机会 实例化之前生成代理(自定义了TargetSource)
   Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
   if (bean != null) {
   
      return bean;
   }
   // 第二次机会 初始化之后生成代理
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   return beanInstance;
}

下面进正文源码分析

第一次机会

BeanNameAutoProxyCreator的动态代理类生成入口在AbstractAutoProxyCreator#postProcessBeforeInstantiation

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
   
   
   // 如果自定义了TargetSource, 那么会在这里创建代理对象
   if (beanName != null) {
   
      TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
      if (targetSource != null) {
   
         this.targetSourcedBeans.add(beanName);
         Object[] specificInterceptors 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值