目录
三、获取到AnnotationAwareAspectJAutoProxyCreator的beanName
四、创建AnnotationAwareAspectJAutoProxyCreator对象
五、注册AnnotationAwareAspectJAutoProxyCreator
三、将增强器放入BeanFactoryAspectJAdvisorsBuilder的advisorsCache集合中
五、放入singletonObjects中的是业务类的代理对象
前言
- Spring容器启动时,在AbstractApplicationContext的refresh方法的invokeBeanFactoryPostProcessors这一步骤中执行了ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
- 该方法会解析到@EnableAspectJAutoProxy注解上的@Import中的value为AspectJAutoProxyRegistrar.class
- 通过判断得知AspectJAutoProxyRegistrar是ImportBeanDefinitionRegistrar接口的实现类,进而调用到AspectJAutoProxyRegistrar的registerBeanDefinitions方法,将AnnotationAwareAspectJAutoProxyCreator对应的RootBeanDefinition对象放入容器中的beanDefinitionMap集合中
- AnnotationAwareAspectJAutoProxyCreator是一个BeanPostProcessor,它会在AbstractApplicationContext的refresh方法的registerBeanPostProcessors这一步骤中通过beanFactory的getBean方法进行实例化和初始化得到其对象,并存入AbstractBeanFactory的beanPostProcessors集合中
- 该BeanPostProcessor将会作用于后续其他bean的getBean的流程
定义切面类
- 自定义注解
java
package spring.aop;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该注解只能用在方法上
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}
- 切面类(切入点+增强逻辑)
java
package spring.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* 切面
*/
@Aspect
@Component
public class LogAspect {
/**
* 切入点表达式
* 增强有@Log注解的方法
*/
@Pointcut("@annotation(spring.aop.Log)")
public void pointCut() {
}
/**
* 定义前置增强逻辑
*/
@Before("pointCut()")
public void before() {
System.out.println("Log...before...");
}
/**
* 定义后置增强逻辑
*/
@After("pointCut()")
public void after() {
System.out.println("Log...after...");
}
}
registerBeanPostProcessors
一、注册Bean后置处理器,拦截Bean的创建过程

二、使用后置处理器委托执行注册Bean后置处理器的逻辑

三、获取到AnnotationAwareAspectJAutoProxyCreator的beanName

四、创建AnnotationAwareAspectJAutoProxyCreator对象


五、注册AnnotationAwareAspectJAutoProxyCreator


构建Advisors
此时容器中已经有AnnotationAwareAspectJAutoProxyCreator这个后置处理器,它就会作用于接下来Bean的创建过程,在它之后的第一个Bean的getBean过程中,其就会构建Advisors并放入BeanFactoryAspectJAdvisorsBuilder的advisorsCache集合中
一、AbstractAutowireCapableBeanFactory的createBean方法中会执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法回调



二、AnnotationAwareAspectJAutoProxyCreator是InstantiationAwareBeanPostProcessor,所以这里会执行到它的postProcessBeforeInstantiation方法(在它的父类AbstractAutoProxyCreator中定义)






三、将增强器放入BeanFactoryAspectJAdvisorsBuilder的advisorsCache集合中

定义一个需要被增强的业务类
- 业务类的register方法添加了自定义的@Log注解
java
package spring.aop;
import org.springframework.stereotype.Service;
@Service
public class AccountService {
/**
* 需要被增强的方法
*/
@Log
public void register() {
System.out.println("AccountService#register...");
}
}
创建业务类的代理对象放入单例池中
Bean组件在实例化之后会执行初始化逻辑,初始化逻辑中在执行完初始化方法后会执行BeanPostProcessor的postProcessAfterInitialization方法,也就是会执行AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization方法
一、业务类的实例化
- getBean

- doGetBean

- createBean

- doCreateBean


二、业务类的初始化
- Bean属性填充

- Bean的初始化逻辑


三、Bean后置处理器的初始化后方法回调
- 执行AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization方法



- 为Bean获取增强逻辑


四、创建业务类的代理对象
- 根据拿到的增强逻辑createProxy


- 这里是通过CGLIB创建代理对象

- 拿到了业务类的代理对象,这里可以看到代理对象中既保存了增强逻辑,同时也保存了目标对象

五、放入singletonObjects中的是业务类的代理对象
- 执行完AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization方法(实际定义在其父类中)后返回的是Bean的代理对象

- 将代理对象放入singletonObjects集合中



从容器中获取业务类对象,并执行其添加了@Log注解的方法
一、测试结果
- 从容器中获取到的是代理对象
java
package spring.aop;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AopMain {
public static void main(String[] args) {
// 容器启动
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
// 从容器中获取业务类对象
AccountService accountService = applicationContext.getBean(AccountService.class);
// 执行其@Log的方法
accountService.register();
}
}

- 执行了增强逻辑

二、通过源码分析其运行流程
- 开始执行代理对象的方法

- 执行到CglibAopProxy的intercept方法

- 获取到目标方法

- 获取到拦截器链

- 通过代理对象、目标对象、目标类、目标方法、拦截器链创建ReflectiveMethodInvocation对象



- 调用proceed方法,currentInterceptorIndex用于记录下标,因为拦截器链是一个List,执行一个可以通过下标++获取下一个


- 调用MethodInterceptor的invoke方法


- 拿到前置增强器

- 执行前置增强逻辑(通过反射调用切面的before方法)



- 执行目标方法(通过反射调用目标方法)



- 执行后置增强逻辑(同样是通过反射执行切面类的后置增强逻辑)


