基本概念
AOP 是面向切面|面向方面编程的简称,Aspect-Oriented Programming。 Aspect 是一种模块化机制,是用来描述分散在对象,类,函数中的横切关注点。从关注点分离出横切关注点是面向切面的程序设计的核心概念。分离关注点使解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不在含有针对特定领域问题的代码调用,业务逻辑和特定领域的问题的关系通过切面来封装,维护,这样原本分散在整个程序中的变动就可以很好的管理起来了。
基础: 待增强对象或者目标对象
切面: 包含对基础的增强应用
配置: 可以看成一种编织,通过在AOP体系中提供这个配置环境,将基础和切面结合起来,从而完成切面对目标对象的编织实现
Advice(通知): 定义在连接点做什么,为切面增强提供织入接口。在Spring AOP 中,它主要描述Spring AOP 围绕方法调用而注入的切面行为。
Pointcut(切点):决定Advice通知应该作用于哪个连接点,也就是说通过Pointcut来定义需要增强的方法集合。
Advisor(通知器):完成对目标方法的切面增强设计(advice)和关注点的设计以后,需要一个对象把它们结合起来,完成这个作用的就是Advisor(通知器)。通过Advisor ,可以定义应该使用那个通知并在哪个关注点使用它。
源码分析
### 启动过程
在Sprint Boot 启动类上加入 注解 @EnableAspectJAutoProxy(proxyTargetClass = true)
,注解源码为:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
该注解使用 @Import 注解引入 AspectJAutoProxyRegistrar
, 跟踪 AspectJAutoProxyRegistrar
类:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata ,
BeanDefinitionRegistry registry) {
/*
往容器中注入AnnotationAwareAspectJAutoProxyCreator类,bean名称为 org.springframework.aop.config.internalAutoProxyCreator
*/
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
/*
读取主配置类的 EnableAspectJAutoProxy的注解的属性
*/
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata,
EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
通过源码发现,AspectJAutoProxyRegistrar
类 实现了ImportBeanDefinitionRegistrar
接口,在容器启动的时候会调用所有实现ImportBeanDefinitionRegistrar
的 bean 的registerBeanDefinitions
方法。在方法内部:
1.调用 org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
a. 在`registerAspectJAnnotationAutoProxyCreatorIfNecessary` 方法内部:
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}
- 最终调用
org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired
方法, 参数cls 为AnnotationAwareAspectJAutoProxyCreator.class
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(
"org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition(
"org.springframework.aop.config.internalAutoProxyCreator");
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(
apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
} else {
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
registry.registerBeanDefinition(
"org.springframework.aop.config.internalAutoProxyCreator",
beanDefinition);
return beanDefinition;
}
}
在方法内部, 首先检查容器中是否包含名称为 org.springframework.aop.config.internalAutoProxyCreator
的bean ,容器第一次启动总不包含该bean,进入else 逻辑,创建一个 AnnotationAwareAspectJAutoProxyCreator.class
的bean定义,并且注册bean的名称为AnnotationAwareAspectJAutoProxyCreator.class
2.调用org.springframework.context.annotation.AnnotationConfigUtils#attributesFor(org.springframework.core.type.AnnotatedTypeMetadata, java.lang.Class<?>)
该类主要完成 读取主配置类的 EnableAspectJAutoProxy
的注解的属性。 主要检查 proxyTargetClass
和 exposeProxy
属性的值
AnnotationAwareAspectJAutoProxyCreator
在容器启动的过程中, AOP 向容器中注入了一个 AnnotationAwareAspectJAutoProxyCreator
的 bean , 我们来分析一下这个bean 。
类的继承体系 :
通过 类的继承体系,我们发现 AnnotationAwareAspectJAutoProxyCreator
实现了 BeanFactoryAware ,BeanClassLoaderAware, SmartInstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor , BeanPostProcessor , BeanClassLoaderAware 等接口 来介入容器启动过程容Bean的生命周期。
类的接口实现:
在 AnnotationAwareAspectJAutoProxyCreator
的接口实现中:
BeanFactoryAware接口:
定义了setBeanFactory 接口, 在容器启动的时候调用org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#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);
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 创建增强器探索工具
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
其中initBeanFactory 最终调用org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#initBeanFactory
:
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 调用父类的initBeanFactory方法
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
// 创建Aspect增强器工厂
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
// 创建一个增强器的构建器
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
InstantiationAwareBeanPostProcessor接口:
我们知道在spring 容器创建任意一个bean的过程中。在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
的方法中:
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// ... 省略代码
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
//... 省略代码
}
在调用真正创建bean的方法doCreateBean
之前, 先调用了 resolveBeforeInstantiation
方法。 我们跟踪org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
方法:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 当容器中存在InstantiationAwareBeanPostProcessors 时,调用InstantiationAwareBeanPostProcessors 的 postProcessBeforeInstantiation 方法和 postProcessAfterInitialization 方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
当容器中存在InstantiationAwareBeanPostProcessors
的bean时
1.先调用applyBeanPostProcessorsBeforeInstantiation
方法,
2.然后在调用applyBeanPostProcessorsAfterInitialization
方法
跟踪 applyBeanPostProcessorsBeforeInstantiation
方法
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
// 获取容器中所有BeanPostProcessor, 若BeanPostProcessor 是InstantiationAwareBeanPostProcessor ,则调用其 postProcessBeforeInstantiation 方法
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
在applyBeanPostProcessorsBeforeInstantiation
方法内部,首先获取容器中所有BeanPostProcessor
,
若BeanPostProcessor
是InstantiationAwareBeanPostProcessor
,
则调用其 postProcessBeforeInstantiation
方法 。
然后我们在容器启动的时候,在容器中注册了AnnotationAwareAspectJAutoProxyCreator
并且这个bean
实现的InstantiationAwareBeanPostProcessor
接口,所以在容器创建bean的时候,会触发AnnotationAwareAspectJAutoProxyCreator
的applyBeanPostProcessorsBeforeInstantiation
方法。
这个是Spring AOP 的真正入口。
接下来我们详细分析:
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
(AnnotationAwareAspectJAutoProxyCreator
继承了 AbstractAutoProxyCreator
)
postProcessBeforeInstantiation
调用链:
详细分析:
在postProcessBeforeInstantiation 中查找所有的增强器org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation
的源码如下,在容器创建任何一个bean的时候触发:
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
//1.先获取 bean的key
Object cacheKey = getCacheKey(beanClass, beanName);
//2. 判断bean是否已经处理过,处理过的bean被放入targetSourcedBeans 集合中。
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//3.判断是否已经包含bean的增强器
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//4.判断bean类型 和 是否应该跳过
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass,
beanName, targetSource);
// 创建代理bean
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
1.先获取 bean的key
2.判断bean是否已经处理过,处理过的bean被放入targetSourcedBeans 集合中。
3.判断是否已经包含bean的增强器
4.判断是否是需要增强的bean
a.判断bean的类型是否为基础类:Advice,Pointcut,Advisor,AopInfrastructureBean进入isInfrastructureClass源码:
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("");
}
return retVal;
}
b.判断是否跳过处理,进入shouldSkip方法源码
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 查找容器中所有的候选的增强器列表
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 若列表中包含当前bean的增强器,返回true
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
跟踪findCandidateAdvisors 方法内部:
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 容器中所有实现Advisor接口的bean组件,熟悉 Spring 事物的都知道,Advisor接口是为Spring事务服务的
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 查找容器是标注@Aspect 组件的bean ,并解析bean的标注 @Before, @After, @AfterReturning, @AfterThrowing 的方法,即查找增强器。并加入缓存中。
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
5.后续第一次执行不到
postProcessAfterInitialization
调用链:
详细过程:
跟踪org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization源码:
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 必要的话,包装代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
进入wrapIfNecessary方法:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 判断是否生成代理对象
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取通知和增强器
// 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;
}
跟踪getAdvicesAndAdvisorsForBean()方法最终调用:org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 找到候选的增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 筛选可用的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 扩展
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
跟踪: findCandidateAdvisors():
@Override
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) {
// 查找所有Aspect ,查找容器是标注@Aspect 组件的bean ,并解析bean的标注 @Before, @After, @AfterReturning, @AfterThrowing 的方法,即查找增强器。并加入缓存中。
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
跟踪:findAdvisorsThatCanApply 并最终调用:org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
进入 canApply方法: 最终调用:org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean)方法:
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
// 创建方法匹配器
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
// 匹配切面的方法
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
getAdvicesAndAdvisorsForBean 方法逻辑分析结束。
跟踪createProxy 方法:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 设置使用JDK代理还是使用CGLIB代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 织入增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 创建代理对象, 代理对象持有 增强器。
return proxyFactory.getProxy(getProxyClassLoader());
}
这样 postProcessAfterInitialization 的逻辑就分析。
总结
在分析了Spring AOP的启动过程,总结一下总体过程:
1.setBeanFacotry 接口,在容器启动的时候,创建了 BeanFactoryAdvisorRetrievalHelperAdapter 增强器探索更具和BeanFactoryAspectJAdvisorsBuilderAdapter 增强器的构建器
2.postProcessBeforeInstantiation 接口: 查找所有的切面和Advisor,并将切面的通知解析,构建成初步的增强器,加入到缓存中来。
3.postProcessAfterInitialization 接口,从缓存取出所有的将所有的增强器,创建代理工厂,并织入增强器,创建代理对象
调用过程:
待更新...