Spring注解驱动开发学习总结12:AOP原理 - @EnableAspectJAutoProxy注解作用分析

在上一篇博文Spring注解驱动开发学习总结11:AOP功能使用,我们学习了AOP的基本使用,下面开始来理解下AOP功能能实现的原理。注:本文用的spring-context是4.3.12.RELEASE版本的。

1、@EnableAspectJAutoProxy注解的作用

首先要能使用AOP,需要在配置类上添加@EnableAspectJAutoProxy注解,因此首先需要来看下@EnableAspectJAutoProxy注解干了点什么事?

1.1 导入AspectJAutoProxyRegistrar类

首先查看@EnableAspectJAutoProxy注解,可以看到112行,该类上面添加了一个@Import注解,该注解导入了一个AspectJAutoProxyRegistrar类。

因此接下来需要看下,AspectJAutoProxyRegistrar这个类干了点什么事?
在这里插入图片描述

1.2 容器中注册AnnotationAwareAspectJAutoProxyCreator类

查看AspectJAutoProxyRegistrar类,可以看到它实现了ImportBeanDefinitionRegistrar类的registerBeanDefinitions方法,因此我们可以猜测到,它应该是要给容器中主动注册一个beanDefinition
在这里插入图片描述
接着断点进入45行的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,通过方法栈可以看到,最后会进入到AopConfigUtils类的109行的registerOrEscalateApcAsRequired方法。
在这里插入图片描述
查看AopConfigUtils类的109行的registerOrEscalateApcAsRequired方法。
1)首先在118行,判断是否存在id为internalAutoProxyCreator的组件。由于容器刚创建,条件为false。其中:
AUTO_PROXY_CREATOR_BEAN_NAME = “org.springframework.aop.config.internalAutoProxyCreator”;
2)接下面在125行,给容器注册一个id为internalAutoProxyCreator,类型为org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator的组件。
在这里插入图片描述
因此可以看到,实际上就是给容器中注册了一个id为internalAutoProxyCreator,类型为.AnnotationAwareAspectJAutoProxyCreator的组件。

1.3 小结

1、在配置类上必须加@EnableAspectJAutoProxy注解,而@@EnableAspectJAutoProxy注解类上加了@Import(AspectJAutoProxyRegistrar.class),也就是导入了一个AspectJAutoProxyRegistrar类。

2、AspectJAutoProxyRegistrar类中的registerBeanDefinitions方法,最终给容器中注册了一个id为internalAutoProxyCreator,类型为.AnnotationAwareAspectJAutoProxyCreator的组件

2、AnnotationAwareAspectJAutoProxyCreator类的使用分析

由上一小结可以看到,配置类上加了@EnableAspectJAutoProxy注解,最终会给ioc容器注册一个类型为.AnnotationAwareAspectJAutoProxyCreator的组件。那么接下来就先分析下,注册这个组件大概有什么用?

2.1 继承关系分析

1、AnnotationAwareAspectJAutoProxyCreator类继承自AspectJAwareAdvisorAutoProxyCreator类。

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {}

2、AspectJAwareAdvisorAutoProxyCreator类继承自AbstractAdvisorAutoProxyCreator类。

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {}

3、AbstractAdvisorAutoProxyCreator类继承自AbstractAutoProxyCreator类。

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {}

4、AbstractAutoProxyCreator类实现了SmartInstantiationAwareBeanPostProcessor类、BeanFactoryAware

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {}

分析:
1)最终实现了SmartInstantiationAwareBeanPostProcessor接口,因此一定会调用某些postProcessorXxx方法,也就是后置处理方法。这个等会需要再分析下,spring容器使用aop功能,在运行时会调用哪些后置处理方法?
2)还实现了BeanFactoryAware接口,那么一定实现了该接口唯一的setBeanFactory方法。

public interface BeanFactoryAware extends Aware {
	void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

2.2 aop关键方法分析

上面已经分析了AnnotationAwareAspectJAutoProxyCreator类的继承关系,接下来重点看下,它在运行时会调用哪些后置处理方法,以及setBeanFactory方法是如何工作的?
1、查看AbstractAutoProxyCreator类:
可以看到其实现了
1)setBeanFactory方法、2)postProcessBeforeInstantiation方法,即实例化前的后置处理方法、3)postProcessAfterInitialization方法,即初始化后的后置处理方法。

比如AbstractAutoProxyCreator类的postProcessBeforeInstantiation方法的截图如下:在这里插入图片描述
因此,目前的继承关系,以及可能会用到的方法如下

继承关系后置处理方法setBeanFactory方法
AnnotationAwareAspectJAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator
AbstractAutoProxyCreator1、postProcessBeforeInstantiation;
2、postProcessAfterInitialization
1、setBeanFactory

2、查看AbstractAdvisorAutoProxyCreator类:
1)该类在54行重写了setBeanFactory方法,,同时在方法中的第60行,调用了initBeanFactory方法
在这里插入图片描述
因此,目前的继承关系,以及可能会用到的方法如下

继承关系后置处理方法setBeanFactory方法
AnnotationAwareAspectJAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator无重写1、setBeanFactory -> initBeanFactory
AbstractAutoProxyCreator1、postProcessBeforeInstantiation;
2、postProcessAfterInitialization
1、setBeanFactory

3、查看AspectJAwareAdvisorAutoProxyCreator类:
在该类中没有看到重写了后置处理方法,以及setBeanFactory方法。
3、查看 AnnotationAwareAspectJAutoProxyCreator 类:
1)该类在75行重写了initBeanFactory方法
在这里插入图片描述
因此,目前的继承关系,以及可能会用到的方法如下

继承关系后置处理方法setBeanFactory方法
AnnotationAwareAspectJAutoProxyCreator无重写1、initBeanFactory
AspectJAwareAdvisorAutoProxyCreator无重写无重写
AbstractAdvisorAutoProxyCreator无重写1、setBeanFactory -> initBeanFactory
AbstractAutoProxyCreator1、postProcessBeforeInstantiation;
2、postProcessAfterInitialization
1、setBeanFactory

2.3 测试理论分析

上面通过理论,分析出了该类在spring使用aop功能时,可能会运行的后置处理方法、以及setBeanFactory方法。

因此我们可以在以下这些类的方法上打上断点,这样调试aop功能的时候就可以看下,是不是调用了这些方法。

从下图可以看到,spring在使用aop容器时,的确都调用了对应类的方法。

1)AnnotationAwareAspectJAutoProxyCreator类的initBeanFactory方法
在这里插入图片描述
2)AbstractAdvisorAutoProxyCreator的setBeanFactory方法:
在这里插入图片描述
3)AbstractAutoProxyCreator类的postProcessBeforeInstantiation方法
在这里插入图片描述

2.4 小结

在给ioc容器注册一个类型为AnnotationAwareAspectJAutoProxyCreator的组件后,分析出该类的继父类中会运行后置处理方法、以及setBeanFactory方法。因此我们可以对这些方法打上调试的断点,方便之后进行aop的源码调用分析

继承关系后置处理方法setBeanFactory方法
AnnotationAwareAspectJAutoProxyCreator无重写1、initBeanFactory
AspectJAwareAdvisorAutoProxyCreator无重写无重写
AbstractAdvisorAutoProxyCreator无重写1、setBeanFactory -> initBeanFactory
AbstractAutoProxyCreator1、postProcessBeforeInstantiation;
2、postProcessAfterInitialization
1、setBeanFactory

3、小结

1、使用AOP功能,要在配置类上加@EnableAspectJAutoProxy注解,而@@EnableAspectJAutoProxy注解类上加了@Import(AspectJAutoProxyRegistrar.class),也就是导入了一个AspectJAutoProxyRegistrar类。

2、AspectJAutoProxyRegistrar类中的registerBeanDefinitions方法,最终给容器中注册了一个id为internalAutoProxyCreator,类型为AnnotationAwareAspectJAutoProxyCreator的组件

3、注册了类型为AnnotationAwareAspectJAutoProxyCreator的组件,我们理论上分析了该类的父类和所实现的接口,分析出该类在spring使用aop功能时,可能会运行的后置处理方法、以及setBeanFactory方法,并且也通过测试进行了验证。

继承关系后置处理方法setBeanFactory方法
AnnotationAwareAspectJAutoProxyCreator无重写1、initBeanFactory
AspectJAwareAdvisorAutoProxyCreator无重写无重写
AbstractAdvisorAutoProxyCreator无重写1、setBeanFactory -> initBeanFactory
AbstractAutoProxyCreator1、postProcessBeforeInstantiation;
2、postProcessAfterInitialization
1、setBeanFactory
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值