根据Spring AOP源码解析一 里面所讲的内容,在Spring容器启动时,会先创建所有的bean的后置处理器,然后再创建普通bean的时候,在合适的地方调用bean的后置处理器执行相应的逻辑,而对于普通bean在Spring执行的生命周期的initializeBean方法中进行完成AOP动态代理的功能工作。
说源码前首先需要有个案例:
Config 配置类,定义扫描规则和注入AOP切面处理类
package com.luban.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan("com.luban.aop")
@EnableAspectJAutoProxy
public class Config {
}
UserService 类,该类为要代理的类
package com.luban.aop.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public String getName(){
System.out.println("getName");
return "wj";
}
public void sayHello(){
System.out.println("hello");
}
}
MyAspect 类,该类为切换类,定义的切点,这个切面类之所以写的这么复杂,是因为最大可能的还原真实场景,但是也是有差距的,getPointcut这个切点是作用在com.luban.aop.service包或者是子包下面所有类以get开头的所有方法,而pointcut切点会作用在com.luban.aop.service包或者是子包下面所有类的所有方法。
package com.luban.aop;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(* com.luban.aop.service..*.get*(..))")
public void getPointcut() {
}
@Before("getPointcut()")
public void before() {
System.out.println("before advice");
}
@After("getPointcut()")
public void after() {
System.out.println("after advice");
}
@Pointcut("execution(* com.luban.aop.service..*.*(..))")
public void pointcut() {
}
@AfterReturning("pointcut()")
public void AfterReturning() {
System.out.println("AfterReturning advice");
}
@Pointcut("execution(* com.luban.aop.service1..*.*(..))")
public void pointcut1() {
}
@AfterReturning("pointcut1()")
public void AfterReturning1() {
System.out.println("AfterReturning advice");
}
@After("pointcut1()")
public void after1() {
System.out.println("after advice");
}
}
测试类,主要是启动类,用来测试
package com.luban.aop;
import com.luban.aop.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test01 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
UserService bean = context.getBean(UserService.class);
bean.getName();
}
}
定义之后,在后面的讲解中会使用到上面案例作为说明,这样能够讲的更清晰。
关于Spring bean创建的流程这里就不再细说了,感兴趣的先参考:Spring中bean的生命周期(最详细),这里仅对Spring AOP进行分析,那么我们的切入点就从initializeBean方法讲起,具体看代码块1。
代码块1:AbstractAutowireCapableBeanFactory#initializeBean方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//1.以安全的方式执行Aware接口的回调方法,进行设置bean工厂、bean的类加载器、bean的名称
//具体看invokeAwareMethods方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
//2.执行所有的bean的后置处理的postProcessBeforeInitialization方法
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//3.执行bean的初始化
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//4.执行所有的bean的后置处理的postProcessorsAfterInitialization方法,也是在此步骤完成bean的动态代理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
关于第1、2、3不是本次讲解的重要,如果真要细说的话,就这三个步骤就可以讲解一篇博客,主要是第4步,这一步会调用所有的bean的后置处理的postProcessorsAfterInitialization方法,也就是在此步完成AOP动态代理的操作,关于第4步的请看代码块2.
代码块2:AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
//1.已存在bean,这个bean是没有代理之前的bean
Object result = existingBean;
//2.拿到所有的bena的后置处理器,依次进行遍历
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//3.执行其postProcessAfterInitialization方法
Object current = processor.postProcessAfterInitialization(result, beanName);
//4.如果有其中一个返回空,则就直接返回了,不再进行遍历
if (current == null) {
return result;
}
result = current;
}
return result;
}
第3步执行后置处理器的postProcessAfterInitialization方法,并将返回的current 对象赋值给result,也就是会替换原来的bean对象。而对于bean后置处理器的postProcessAfterInitialization方法,如果不做处理的话,都是直接将传递过来的bean给直接返回,而不进行任何处理。
对于上篇文章提到的AnnotationAwareAspectJAutoProxyCreator也是一个bean后置处理器,而AnnotationAwareAspectJAutoProxyCreator间接的继承AbstractAutoProxyCreator类,在AbstractAutoProxyCreator类中实现了postProcessAfterInitialization方法,具体看代码块3.
代码块3:AbstractAutoProxyCreator#postProcessAfterInitialization方法
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* 如果子类将bean标识为一个要代理的bean,则使用配置的拦截器创建一个代理
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, St