AOP
定义:
Spring AOP是Spring用来增强bean的一种方式,他基于动态代理实现。有分为基于接口实现的JDK动态代理和基于继承实现的CGLIB动态代理
概念术语:
术语 | 解释 |
---|---|
目标对象 target | 要增强的对象,包含主业务逻辑的类对象 |
连接点 Join point | 代表要增强的方法 |
切面 Aspect | 切面是指切面类 管理增强的公共行为代码(通知)和切入方式(切点) |
切点 Pointcut | 用于匹配连接点 决定要不要织入的表达式 匹配规则:AspectJ |
通知 Advice | 在某个连接点执行的动作 增强方法 分为“around”,“before”,“after”… 以拦截器作为通知模型 |
织入 Weaving | 将 通知切入连接点 的过程 |
顾问 Advisor | 用于管理 切点和通知 |
引入 Introductions | 将其他接口和实现 动态引入 到targetClass中 |
例子
静态代理例子
- 首先定义target类和接口
/**
* 计算类接口
*/
public interface Calculate {
/**
* 加法
*/
int add(int numA, int numB);
/**
* 减法
*/
int sub(int numA, int numB);
/**
* 除法
*/
int div(int numA, int numB);
/**
* 乘法
*/
int multi(int numA, int numB);
}
/**
* 计算器实例target
*/
@Component
public class TulingCalculate implements Calculate {
public int add(int numA, int numB) {
System.out.println("执行目标方法:add");
System.out.println(1/0);
return numA+numB;
}
public int sub(int numA, int numB) {
System.out.println("执行目标方法:reduce");
return numA-numB;
}
public int div(int numA, int numB) {
System.out.println("执行目标方法:div");
return numA/numB;
}
public int multi(int numA, int numB) {
System.out.println("执行目标方法:multi");
return numA*numB;
}
}
- 定义advice或Interceptor 增强的公共代码
/**
* 定义增强的公共代码,记录日志为例
*/
public class TulingLogAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
String methodName = method.getName();
System.out.println("执行目标方法【"+methodName+"】的<前置通知>,参数"+ Arrays.asList(args));
}
}
/**
* 定义拦截器,来增强方法
*/
public class TulingLogInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println(getClass()+"调用方法前");
Object ret=invocation.proceed();
System.out.println(getClass()+"调用方法后");
return ret;
}
}
- 通过配置类创建一个==静态代理==
@Configuration
@EnableAspectJAutoProxy
public class EalyAopMainConfig {
// 被代理对象,注入IOC
@Bean
public Calculate myCalculate() {
return new MyCalculate();
}
// Advice 方式
@Bean
public TulingLogAdvice tulingLogAdvice(){
return new TulingLogAdvice();
}
// Interceptor方式 , 类似环绕通知
@Bean
public TulingLogInterceptor tulingLogInterceptor() {
return new TulingLogInterceptor();
}
// 注入一个静态代理!
@Bean
public ProxyFactoryBean calculateProxy(){
ProxyFactoryBean userService=new ProxyFactoryBean();
// 设置**切面** 就是增强的代码
userService.setInterceptorNames("tulingLogAdvice","tulingLogInterceptor");
// 设置**目标对象** 就是要增强的类
userService.setTarget(tulingCalculate());
return userService;
}
}
- 执行
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EalyAopMainConfig.class);
// 还要知道代理的名字calculateProxy,才能获得代理对象
Calculate calculateProxy = ctx.getBean("calculateProxy",Calculate.class);
// 调用目标方法
calculateProxy.div(1,1);
}
缺点:
- bean单一目标 —— 通过静态代理的方式,导致 只能指定单一target 的AOP,多个bean要手动创建多个ProxyFactoryBean
- 拦截粒度大 —— 通过这种方式,导致拦截了目标类中的所有方法
细粒度拦截:
// 配置类修改为
@Bean
public NameMatchMethodPointcutAdvisor tulingLogAspect() {
// 通知者(Advisor):是经过包装后的细粒度控制方式。
NameMatchMethodPointcutAdvisor advisor=new NameMatchMethodPointcutAdvisor();
// 通知(Advice) :有增强方法的那个类
advisor.setAdvice(tulingLogAdvice());
// 匹配目标类的方法
advisor.setMappedNames("div");
return advisor;
}
/**
* FactoryBean方式单个: ProxyFactoryBean
* 控制粒度到方法
*/
@Bean
public ProxyFactoryBean calculateProxy(){
ProxyFactoryBean userService=new ProxyFactoryBean();
// 设置 **切面**,增强的代码通过 **通知者** 来包装
userService.setInterceptorNames("tulingLogAspect");
// 设置目标类
userService.setTarget(tulingCalculate());
return userService;
}
执行
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EalyAopMainConfig.class);
// 还要知道代理的名字calculateProxy,才能获得代理对象
Calculate calculateProxy = ctx.getBean("calculateProxy",Calculate.class);
// 调用目标方法
calculateProxy.div(1,1);
}
好处:
通过通知者Advisor配置,可以将拦截粒度从 类层面 降低到 方法层面,之拦截特定方法
缺点
- 每一个bean都配置一个静态代理
- getBean也需要获取代理类 【calculateProxy】
很不方便
动态代理
为了避免麻烦,每一个类都要创建一个代理而且getBean要去拿【calculateProxy】 反人类
我们可以通过autoproxy来让Spring自动生成代理来拦截方法
改进静态代理:
// 去掉原来的代理bean:calculateProxy 【ProxyFactoryBean这种静态配置】
// 用BeanNameAutoProxyCreator 这种动态配置
@Bean
public BeanNameAutoProxyCreator autoProxyCreator() {
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
// 这就是 **目标对象们targets** 设置需要代理的bean们
beanNameAutoProxyCreator.setBeanNames("tuling*");
//设置 **通知** (这些拦截器是有先后顺序的) 就是你动态代理要给他们执行的方法的bean咯~
beanNameAutoProxyCreator.setInterceptorNames("tulingLogInterceptor");
return beanNameAutoProxyCreator;
}
执行
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EalyAopMainConfig.class);
// 这时候只需要按bean名字来get就好了!!! 不需要再管是 三姑代理还是六婆代理 啊!! 方便得要死
Calculate tulingCalculate = ctx.getBean("tulingCalculate",Calculate.class);
tulingCalculate.div(1,1);
}
好处
- 获取bean代理方便 —— 想拿bean对应的代理,直接用bean名来获取就行,不需要再知道是哪个xx代理我了
- 给多个target创建代理 —— 一次性可以对符合正则表示式的目标对象target创建代理噢!不需要一个一个创建那么麻烦了
坏处
- 粒度大 —— 拦截整个类,不能拦截到具体方法
加强版
// RegexpMethodPointcutAdvisor 按正则匹配类
@Bean
public RegexpMethodPointcutAdvisor tulingLogAspectInterceptor() {
RegexpMethodPointcutAdvisor advisor=new RegexpMethodPointcutAdvisor();
// 设置 **advice**
advisor.setAdvice(tulingLogInterceptor());
// 正则匹配 target们!
advisor.setPattern("tuling.TulingCalculate.*");
return advisor;
}
Spring AOP使用
-
开启AOP —— @EnableAspectJAutoProxy
-
编写切面类 —— @Aspect
-
编写切点表达式 —— @Pointcut(“execution(返回值 包名.类名.方法名(参数类型) )”)
@Pointcut("execution(* com.summer.circulardependencies.*Controller.*(..))")
-
编写通知 —— @Around、@Before、@After、@AfterReturning、@AfterThrowing
AOP原理
定义:
在Spring中,怎么给一个bean对象生成动态代理呢?
如果我们要对bean进行增强,那么我们是不是需要去找一个增强的处理器? 没错,就是BeanPostProcessor
BeanPostProcessor是一个接口,那么AOP动态代理由谁实现的呢?由AbstractAutoProxyCreator
类实现的
正常的AOP
初始化后进行AOP
- 初始化后 —— applyBeanPostProcessorsAfterInitialization() 里面调用BeanPostProcessor
源码:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 1. 循环取出所有Bean后置处理器,找到AOP的那个后置处理器
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
// AbstractAutoProxyCreator类
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 1. 这里是判断之前有没有创建AOP,就是循环依赖的时候
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 2. 如果没有创建,那么就去创建AOP
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果有 **通知者**,去创建
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 3. 创建AOP动态代理
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;
}
循环依赖的AOP
提前进行AOP —— 实例化后进行AOP
- 实例化后 —— getEarlyReference() 里面调用BeanPostProcessor
源码:
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
// 1. 获取早期引用
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}
// AbstractAutoProxyCreator类
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 2. 提供一个标识,告诉后面的正常AOP,我已经创建AOP了,你不要创建了
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
// 3. 循环依赖,那么它一定是先于正常创建AOP的,所以不用判断是否已经创建AOP,直接创建
return wrapIfNecessary(bean, beanName, cacheKey);
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果有 **通知者**,去创建
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 3. 创建AOP动态代理
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;
}
AOP怎么注入到容器中?
定义:
我们知道,AOP是通过@EnableAspectJAutoProxy
注解进行开启的,点进去会发现有@Import(AspectJAutoProxyRegistrar.class)
这个类的导入
是什么时候进行导入的?
它是通过配置类被解析的时候
配置类可以获取自己的**@Import注解并load**注册为Bean定义的这个时候导入的
源码
// 1. 配置类被解析时,通过reader来加载配置类上的注解的依赖
this.reader.loadBeanDefinitions(configClasses);
// Reader来读取
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
// 配置类有可能是一个set集合,就是不止一个,那么循环遍历
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
// Reader读取
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 2. 从ImportBeanDefinitionRegistrar里面加载bean定义
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
// Reader读取
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
// 3. 这里就是遍历所有实现了ImportBeanDefinitionRegistrar这个接口的实现类,然后去注册他们
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
}
// ImportBeanDefinitionRegistrar接口,
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
// 4. 调用实现类的registerBeanDefinitions()方法
registerBeanDefinitions(importingClassMetadata, registry);
}
- 在配置类被解析时,执行reader的
loadBeanDefinitions()
- 执行
loadBeanDefinitionsFromRegistrars()
- 含义是从Registrars里面加载bean定义,就是如果有实现了ImportBeanDefinitionRegistrar这个接口的,遍历这些实现类,获取他们的bean定义
- 遍历,注册实现了ImportBeanDefinitionRegistrar接口的实现类,AOP的类,刚好实现了这个接口
- 接口默认实现,调用实现类
registerBeanDefinitions()
方法
AOP的实现类
真正开始创建AOP这个类AspectJAutoProxyRegistrar
的逻辑
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 1. 关注这个方法,进行注册AOP
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
- 方法
registerAspectJAnnotationAutoProxyCreatorIfNecessary()
点进去是一个门面方法,一直进去,真正干活的方法为registerOrEscalateApcAsRequired()
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
// 1. 一开始Bean工厂肯定是没有这个AnnotationAwareAspectJAutoProxyCreator类的,现在才去创建
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 2. 去创建AnnotationAwareAspectJAutoProxyCreator类
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
- AUTO_PROXY_CREATOR_BEAN_NAME这个常量对应的类就是这个
AnnotationAwareAspectJAutoProxyCreator
类 - 因为方法一开始没有包含
AnnotationAwareAspectJAutoProxyCreator
类,所以要去注册这个类
实例化
AnnotationAwareAspectJAutoProxyCreator类经过上面步骤,已经注册为Bean定义了,它有两个特点
- 实现了BeanPostProcessor接口
- 实现了Ordered接口
- 实现了Aware接口
在看 AnnotationAwareAspectJAutoProxyCreator类 实例化之前,我们先看看它的继承结构
根据bean的生命周期,我们可以知道,Spring在初始化AnnotationAwareAspectJAutoProxyCreator这个类的时候,会调用BeanFactoryAware的setBeanFactory()方法支持程序员拿到 BeanFactory 并做相应的响应操作
源码:
// 父类 AbstractAdvisorAutoProxyCreator
// 在生命周期回调的时候,调用了setBeanFactory()这个方法
@Override
public void setBeanFactory(BeanFactory beanFactory) {
// 设置bean工厂
super.setBeanFactory(beanFactory);
// 1. 调用initBeanFactory()方法,由AnnotationAareAspectAutoProxyCreator实现
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
// 子类 AnnotationAareAspectAutoProxyCreator
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
- 调用setBeanFactory(),因为AnnotationAwareAspectJAutoProxyCreator没有重写该方法,所以往上找,找到实现该方法的AbstractAdvisorAutoProxyCreator
- 调用initBeanFactory(),因为AnnotationAwareAspectJAutoProxyCreator重写了该方法,所以直接执行本类的该方法
- BeanFactoryAspectJAdvisorsBuilderAdapter这里实例化了一个 Bean工厂切面通知建造者适配者!它是负责从bean工厂查找 切面类,并将其封装为一个一个Advisor的列表 很重要
小结:
这里就将我们需要的类AnnotationAareAspectAutoProxyCreator给他实例化出来了,接下来就是执行它
什么时候封装Advisors?
在第一次创建普通Bean的时候,也就是实例化剩下的bean时,会调用上面的AdvisorsBuilder去扫描bean,并且将切面类给扫描读取,封装Advisors
在创建bean的时候,会回调方法,再找候选通知者时findCandidateAdvisors()
方法中,缓存无法找到Advisors,就会去创建Advisors
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
// 1. 第一次进来,肯定没有切面类被创建
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 2. 获取所有的Bean定义名字
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 3. 判断类是否有 @Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
// 3.1 有注解,开始处理
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 3.2 开始封装advisors!这里getAdvisors和getBean的操作差不多
// 都是找不到就去创建
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 3.3 加入advisorsCache缓存
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
// 4. 记录所有切面类的名字
this.aspectBeanNames = aspectNames;
// 5. 返回所有的advisors
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
getAdvisors()方法,在指定切面类上获取它的所有Advisors
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 1. 获取切面类的名字
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
for (Method method : getAdvisorMethods(aspectClass)) {
// 2. 【重要方法!】 遍历切面类的方法,判断上面有没有注解,封装**Advisor**
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
**getAdvisor()**方法,真正的去封装Advisor
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 1. 获取切点表达式!然后去匹配方法咯~
AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 2. 实例化Advisor,Advisor的组成是 {切点、方法、切面名字...}
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
总结
AOP到底是怎么实现的?
-
首先AOP是通过**@EnableAspectJAutoProxy注解来开启AOP的,如果跟进这个注解会发现,注解上有@Import(AspectJAutoProxyRegistrar.class),它导入了一个AspectJAutoProxyRegistrar的类,由于这个类实现了ImportBeanDefinitionRegistrar**接口;当配置类被ConfigurationClassPostProcessor解析的时候,它会执行这个接口下的实现类方法,注册一个重要的类 AnnotationAwareAspectJAutoProxyCreator
@EnableAspectJAutoProxy -> @Import(AspectJAutoProxyRegistrar.class) -> 配置类解析 -> 执行方法 -> 注册AnnotationAwareAspectJAutoProxyCreator
-
AnnotationAwareAspectJAutoProxyCreator这个类实现了BeanPostProcessor接口,所以在注册BeanPostProcessor的时候,会实例化该类,而实例化该类时,它实现了BeanFactoryAware接口,所以在执行初始化方法前,它会执行Aware接口下的一个回调方法,通过这个方法,他实例化了一个重要的类BeanFactoryAspectJAdvisorsBuilderAdapter
AnnotationAwareAspectJAutoProxyCreator -> 实现BeanPostProcessor -> 在regist的时候实例化 -> 实现BeanFactoryAware -> 初始化回调方法 -> 实例化BeanFactoryAspectJAdvisorsBuilderAdapter
-
AOP重要的是通知(Advice)和切点(PointCut),什么时候封装他们的呢?在剩余的普通Bean的第一次createBean的时候,会调用resolveBeforeInstantiation()方法 给AOP一个机会去封装Advisor。而AOP会去调用BeanFactoryAspectJAdvisorsBuilderAdapter这个建造者去建造Advisors,建造者会扫描所有bean,找到Aspect切面类,然后进行方法遍历,封装每一个Advice+PointCut => Advisors;最后返回一个所有拥有的Advisors列表
createBean -> resolveBeforeInstantiation() -> 调用builder -> 扫描所有bean -> 切面类 -> 扫描所有方法 -> 封装Advisor -> 汇总为Advisors
至此,AOP实例完成!接下来要做的就是在bean初始化之后或者实例化之后判断是否要进行AOP,如果要,给他动态代理就好!