次要内容
SpringBoot如何将AOP相干的类注入BeanFactory中,如何起作用呢?
梳理概要
- AopAutoConfiguration:主动注入AOP相干的配置类;AnnotationAwareAspectJAutoProxyCreator;
- 在populateBean的时候,每个bean都会扫描是否有切面,匹配一下;AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization;
- 匹配胜利,则会通过cglib动静代理生成一个新的代理类;
具体的源码过程
1.1 主动配置类加载AOP相干的类;
- 加载AopAutoConfiguration
在加载CglibAutoProxyFactory的时候,外面有注解@EnableAspectJAutoProxy的时候有一个@Import注解,AspectJAutoProxyRegistrar;这个Registrar很重要!!!
其在ConfigurationClassPostProcessor类扫描加载bean的时候,解决loadBeanDefinitionsFromRegistrars的时候;加载进去;public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);.....
registerAspectJAnnotationAutoProxyCreatorIfNecessary()的时候,
把AnnotationAwareAspectJAutoProxyCreator封装成BeanDefinition,对应的key=internalAutoProxyCreator;@Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) {// 把AnnotationAwareAspectJAutoProxyCreator封装成一个BeanDefinition; return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
1.2 应用代理类(AnnotationAwareAspectJAutoProxyCreator)
InitializeBean -- 初始化bean的时候,会对立调用所有的BeanPostProcessor.postProcessAfterInitialization;其中就会调用到AnnotationAwareAspectJAutoProxyCreator;进行查看是否有符合要求的切面办法;
调用办法如下:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { ......// 重点如下:找到这个bean的所有切面办法,而后调用createProxy创立代理类;返回即可。 // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); 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; }
1.3 找所有的适合的告诉
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {// 1 找到所有的候选告诉 List<Advisor> candidateAdvisors = findCandidateAdvisors();// 2 进行匹配,查看是否适合 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) {// 3 这里排序Advisor? eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
1.3.1 findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules.// 从所有带@Advisor注解的切面类; List<Advisor> advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. if (this.aspectJAdvisorsBuilder != null) {// 开始找@AspectJ的注解类; advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
次要逻辑:
- 遍历BeanDefinitionMap,查看是否有@AspectJ注解,
- 如果有,则会遍历method,查看是否是一个告诉,如果是一个告诉,则会封装成一个InstantiationModelAwarePointcutAdvisorImpl类;
而后封装返回;
在这个办法外面还有一个排序!! 在getAdvisorMethod中private List<Method> getAdvisorMethods(Class<?> aspectClass) { List<Method> methods = new ArrayList<>(); ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter); if (methods.size() > 1) { methods.sort(adviceMethodComparator); } return methods; }
依照什么排序呢?
private static final Comparator<Method> adviceMethodComparator; static { // Note: although @After is ordered before @AfterReturning and @AfterThrowing, // an @After advice method will actually be invoked after @AfterReturning and // @AfterThrowing methods due to the fact that AspectJAfterAdvice.invoke(MethodInvocation) // invokes proceed() in a `try` block and only invokes the @After advice method // in a corresponding `finally` block. Comparator<Method> adviceKindComparator = new ConvertingComparator<>( new InstanceComparator<>( Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class), (Converter<Method, Annotation>) method -> { AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method); return (ann != null ? ann.getAnnotation() : null); }); Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName); adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator); }
咱们发现,他是依照Around、Before、After、AfterReturning进行排序,如果有雷同,则依照methodName进行排序;
1.3.2 findAdvisorsThatCanApply
查看这个类是否和PointCut 匹配胜利,匹配胜利,即返回列表;
protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try {// 查看这个类是否和PointCut 匹配胜利,匹配胜利,即ok; return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } }
1.3.3 findAdvisorsThatCanApply
比拟两个类的order大小;
1.4 createProxy
这个不在细追,
主题逻辑:
- 找到所有的Advisor
- 创立指定的拦截器,比方:dynamicAdvisorInterceptor退出到callback办法中;
- Enhancer.create();
总结
- 先想好,再去做;
- 命名艺术,AutoProxyCreator、AspectJAdvisor、AspectJAdvisorBuilder、XXFactory
- 封装成对象,便于当前的扩大