1. 注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator。 就是本篇。
2. 扫描容器中的切面,创建Advisor对象【十一】Spring源码分析之AOP----AnnotationAwareAspectJAutoProxyCreator扫描@Aspect,创建Advisor
3. 目标bean和每个Advisor匹配,找出该bean在被代理的时候需要用到哪些Advisor
【十二】Spring源码分析之AOP----匹配出作用于被代理类Advisor
4. 创建代理对象
【十三】Spring源码分析之AOP----生成代理对象
5. 被代理类的方法一次调用流程。
【十四】Spring源码分析之AOP----JdkDynamicAopProxy代理对象invoke调用
这一篇主要是讲 注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator
SpringBoot启动时
ConfigurationClassProceesor类加载、解析、注册配置类的时候会加载注册spring-boot-autoconfigure-1.5.8RELEASE.jar包下META-INF/spring.factory文件中的允许自动配置的类的时候,即是该标注下的所有类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
则会加载注册AopAutoConfiguration类,并且会加载注册AopAutoConfiguration配置类中的配置类JdkDynamicAutoProxyConfiguration,而JdkDynamicAutoProxyConfiguration在处理@Import的时候会实例化AspectJAutoProxyRegistrar类
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
AopAutoConfiguration源码
package org.springframework.boot.autoconfigure.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.Advice;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)
public static class CglibAutoProxyConfiguration {
}
}
该类做了2件事
1.@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
AopAutoConfiguration创建前需要有EnableAspectJAutoProxy.class, Aspect.class, Advice.class。
2.AopAutoConfiguration该配置类会根据@EnableAspectJAutoProxy(proxyTargetClass = true)是为true还是为false来生成不同的自动代理配置类,JdkDynamicAutoProxyConfiguration 或CglibAutoProxyConfiguration 。默认生成的自动代理类是JdkDynamicAutoProxyConfiguration 。
源码:
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}.
*/
boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
* @since 4.3.1
*/
boolean exposeProxy() default false;
}
可以看到该注解@Import(AspectJAutoProxyRegistrar.class),所以在解析JdkDynamicAutoProxyConfiguration的时候处理@Import注解就会把AspectJautoProxyRegistrar实例化了。
源码:
package org.springframework.context.annotation;
import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册 AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//将 aop 代理方式相关的变量设置到 AopConfigUtils,创建代理类时会读取变量
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
做了2件事:
1.AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)方法注册 AnnotationAwareAspectJAutoProxyCreator
2.将 aop 代理方式相关(proxyTargetClass和exposeProxy)的设置到BeanFactory已注册的BeanDefinition中,创建代理类时会读取变量
先说一下AspectJAutoProxyRegistrar类的这个方法registerBeanDefinitions会在什么时候被调用,即是入口,从方法调用栈中可以看到:
在注册JdkDynamicAutoProxyConfiguration的时候,会调用AspectJAutoProxyRegistrar类的registerBeanDefinitions方法去注册AnnotationAwareAspectJAutoProxyCreator
源码:
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
//这里注册AnnotationAwareAspectJAutoProxyCreator类
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
做了1件事:
这里注册的AutoProxyCreator是AnnotationAwareAspectJAutoProxyCreator类,该方法跟进去调用的是registerOrEscalateApcAsRequired方法
1.3.1.1 registerOrEscalateApcAsRequired方法
源码:
private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
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);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
做了2件事:
1.autoProxyCreator类是否已注册到BeanFactory中,如果没有,则注册入参传进来的autoProxyCreator类。
2.如果已经注册了,就拿来出看比较一下是否跟入参传进来的autoProxyCreator类的名字一样,不一样并且已有的那个autoProxyCreator优先级低于入参才传进来的这个autoProxyCreator,那就升级成入参才传进来这个。
AnnotationAwareAspectJAutoProxyCreator看一下类图
它继承了BeanPostProcessor接口,在AbstractApplicationContest的refresh方法中调用registerBeanPostProcessors(beanFactory)方法时,会把所有继承了BeanPostProcessor接口的类提前实例化。
所以,实例化AnnotationAwareAspectJAutoProxyCreator的入口是:
(方法栈)
至于这里创建的详细过程请看另一篇博客专门讲getBean方法的:
【五】Spring源码分析之实例化Bean----DefaultListableBeanFactory的preInstantiateSingletons方法
该博客的第四部分就是将getBean方法的
实例化AnnotationAwareAspectJAutoProxyCreator后,会调用该对象的初始化方法
初始化方法调用栈,初始化入口:
可以看到初始化AnnotationAwareAspectJAutoProxyCreator对象的入口是AbstractAutoWireCapableBeanFactory类的InitializeBean方法,关于该方法另外有一篇博客中有提到过。
【七】Spring源码分析之实例化Bean----AbstractAutowireCapableBeanFactory的createBean方法
该博客的3.5就是讲InitializeBean方法
源码:
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) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
做了1件事:
发现AnnotationAwareAspectJAutoProxyCreator实现了BeanFactoryAware接口,则调用AnnotationAwareAspectJAutoProxyCreator类的setBeanFactory方法。
源码:
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
做了2件事:
1.把beanFactory设置到AnnotationAwareAspectJAutoProxyCreator中
2.给AnnotationAwareAspectJAutoProxyCreator中的成员(aspectJAdvisorFactory、aspectJAdvisorsBuilder、advisorRetrievalHelper)赋值