如果想使用AOP,我们需要在启动类上添加 @EnableAspectJAutoProxy 注解 所以从这个注解开始动刀
注意三个点
导入了一个 AspectJAutoProxyRegistrar 注册组件
@Import(AspectJAutoProxyRegistrar.class)
boolean proxyTargetClass() default false; //是否使用CGLB创建代理对象
boolean exposeProxy() default false; //是否将代理对象放入ThreadLocal ,如果为true,可以通过 AopContext 获取代理对象
看 AspectJAutoProxyRegistrar 组件注册了什么 点进去
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
实现了 ImportBeanDefinitionRegistrar 接口 ,看重写的 registerBeanDefinitions 方法
注册了AnnotationAwareAspectJAutoProxyCreator
看下 AnnotationAwareAspectJAutoProxyCreator 是什么
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
发现 AnnotationAwareAspectJAutoProxyCreator 继承了 BeanPostProcessor 后置处理器 那么,也就是说SpringIOC初始化每一个bean后,都会执行这个BeanPostProcessor 的实现类 ,而postProcessAfterInitialization的重写方法 在 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator中
首先看
Object cacheKey = getCacheKey(bean.getClass(), beanName);
跟进
wrapIfNecessary(bean, beanName, cacheKey)
`Advice Pointcut Advisor AopInfrastructureBean 这四种类型的bean直接返回原对象,不需要进行AOP
` shouldSkip() 方法留给程序员决定那些bean不需要AOP
如下面这个bean 将不会被AOP代理
@Component(value = "com.sgg.proxy.bean.MyBean.ORIGINAL")
public class MyBean {
@MyAop
public void method()
{
System.out.println("方法执行了");
}
}
接下来我们看 getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null) 这个方法
跟进来到 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean
跟进 findEligibleAdvisors(beanClass, beanName) 方法
先看 findCandidateAdvisors() 是怎么拿到所有的advice的
跟进来到 org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()
跟进
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false)
注意方法的四个参数
拿到所有类型为 Advisor 的beanName 注意只是名字 如果有父容器,也取出父容器中的实现了Advisor 接口的bean的Name
拿到所有的beanName后,遍历,
判断是不是正在创建中,如果正在创建中,跳过 然后调用 this.beanFactory.getBean(name, Advisor.class) 获取(没有就创建bean),放到集合List advisors 中然后返回 至此,拿到了Spring容器中所有的advisor的子类
回到org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors
通常我们都是使用@Aspect定义一个切面类,这种就需要通过this.aspectJAdvisorsBuilder.buildAspectJAdvisors()去找
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
从容器中取出所有类型为Object的bean 也就是取出所有的bean
拿到class,判断是否有@Aspect注解
调用 List classAdvisors = this.advisorFactory.getAdvisors(factory) 方法 拿到不同的advisor
首先找到类中所有非定义切入点的方法
看adviceMethodFilter过滤器
如果注解类型是PointCut,返回null
回到getAdvisors方法,拿到所有的非@PonitCut的方法后
调用 getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName) 创建 advisor
至此,所有的advisor查找完毕 进行下一步过滤操作
回到 findEligibleAdvisors 方法 看如何筛选的
是不是实现了 IntroductionAdvisor 接口,然后调用 canApply(candidate, clazz) 判断是否能应用
跟进canApply(candidate, clazz) 方法
如果当前advisor 是属于 IntroductionAdvisor ,按Class过滤
如果当前advisor 是属于 PointcutAdvisor
调用 canApply(pca.getPointcut(), targetClass, hasIntroductions) 方法
与当前正在创建的bean匹配的advisor最终都存到了List eligibleAdvisors 中
查找所有的advisor与过滤筛选完成后,进行代理类的创建
回到 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary 方法
拿到所有的advice的流程已经走完,接下来就是创建代理类了,画张图,整理下流程