Spring专题- AOP-源码级别的AspectJ类的注入与使用过程

本文使用Annotation实现配置,介绍了registerBeanPostProcessors注册BeanPostProcessor的顺序,getBean方法的主要工作。重点分析了IOC容器中AOP切面管理类解析切面类的过程,以及被Aspect修饰的类进行动态代理的阶段,还提及AspectJ执行通知的顺序等内容。

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

直接源码走一波:我这里使用Annotation 实现配置

registerBeanPostProcessors 顾名思义,就是注册BeanPostProcessor, 这里有顺序,实现了 priorityOrder的类 > Order >none 按照这个顺序 创建 -初始化 BeanPostProcessor类

getBean方法那这里就不单独展开了,主要的工作就是创建Bean,初始化Bean(循环已经注册的BeanPostProcessor , 对bean进行 applyBefore /after 处理) 将创建的bean 插入到 BeanFactory这么一个concurrentHashMap中

   public void preInstantiateSingletons() throws BeansException {
         ... 省略部分代码

                    if (this.isFactoryBean(beanName)) {
                        bean = this.getBean("&" + beanName);
                        break;
                    }
                    //获取Bean---我们要继续跟进的方法
                    this.getBean(beanName);
                }
            } while(!(bean instanceof FactoryBean));

          ... 省略部分代码
        }
    }

 protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    ...省略代码

                if (mbd.isSingleton()) {
                    sharedInstance = this.getSingleton(beanName, () -> {
                        try {
                            //AspectJ类和切面修饰类都是单例 那createBean就是我们需要跟进的方法
                            return this.createBean(beanName, mbd, args);
                        } catch (BeansException var5) {
                            this.destroySingleton(beanName);
                            throw var5;
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
  ...省略代码
    }

先讨论第一个:debug--一旦IOC容器中已经存在AOP-切面管理类-AnnoationAwareAspectJAutoProxyCreator(rootBeanDefinaton注入的名字叫internalAutoProxyCreator),再第一次执行resolveBeforeInstantiation 的时候,会将系统中的切面类(使用@AspectJ)给解析到切面管理类中:也就是下图中这些参数:

到这里我们就有必要去看一下Aspect给我们创建的是一个什么BeanPostProcessor==》

 

 

回到我们刚才讨论的 调用  postProcessBeforeInstantiation()方法,那我们重点要关注的就是AspectJ-> BeanPostProcess-> postProcessBeforeInstantiation() ----->

getAdvice这个方法就是我们最终获取advisor的地方了 里面用了一个switch case 给每一种通知方法 before/after/afterReturn/afterthrowing/around 都设置了一个实现类 

接下来要开始讨论第二阶段,创建被Aspect修饰的类是哪儿进行的动态代理:聪明的大佬肯定知道了没错: postProcessAfterInitialization 

走进源码,悄悄靠近

 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
       ...代码省略
           
        if (instanceWrapper == null) {
           //创建Bean
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

      ...代码省略

        try {
            //属性设置
            this.populateBean(beanName, mbd, instanceWrapper);
            //初始化内容
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }
     ...代码省略
    }

进入到初始化内容阶段

好前三个留给读者细细品味,来讲下第四个,既然调用所有已经注册到BeanPostProcessorFactory里的方法那肯定有AspectJ的BeanPostProcessor啦,那就是调用它的after方法,我们来看一下它的after方法

当然AspectJ执行通知是有顺序的,相信细跟一遍定能发现:这里在贴一张最终代理类的详情:

END

补充:再AspectJ的源码中要注意一点:下图的方法的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值