Spring AOP的总体流程 1、注册解析AOP的服务 2、解析和加载横切逻辑 3、将横切逻辑织入目标Bean中 AnnotationAwareAspectJAutoProxyCreator继承体系图 AnnotationAwareAspectJAutoProxyCreator既实现了SmartInsta
Spring AOP的总体流程
- 1、注册解析AOP的服务
- 2、解析和加载横切逻辑
- 3、将横切逻辑织入目标Bean中
AnnotationAwareAspectJAutoProxyCreator继承体系图
-
AnnotationAwareAspectJAutoProxyCreator既实现了SmartInstantiationAwareBeanPostProcessor 又实现了BeanFactoryAware。就可以对容器做一些事情。
-
AnnotationAwareAspectJAutoProxyCreator 实现了Order接口,所以先于普通的BeanPostProcessor注册,并对普通BeanPostProcessor也能起作用。
-
AnnotationAwareAspectJAutoProxyCreator 是InstantiationAwareBeanPostProcessor,会在Bean被创建之前,在resolveBeforeInstantiation中被调用。
-
Spring Aop主要是通过AbstractAutoProxyCreator实现的BeanPostProcessor、InstantiationAwareBeanPostProcessor以及SmartInstantiationAwareBeanPostProcessor接口里面的后置处理器方法,来介入到Spring IOC容器的Bean的实例化以及初始化的过程中对Bean进行AOP的处理的。
-
所以AbstractAutoProxyCreator类里面的实现的容器级别的后置处理器方法便是介入分析的点,而横切逻辑的加载主要是在AbstractAutoProxyCreator类中的的postProcessBeforeInstantiation方法中,该方法是在Bean的实例化之前被调用的。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
//当在实例化前置方法 postProcessBeforeInstantiation 中创建了代理类,
// 则在 targetSourcedBeans 中将添加 beanName,
// 也就是 targetSourcedBeans 中含有 beanName
// 则说明这个类被动态代理了
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
/**
* 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后)
* AOP解析切面以及事务解析事务注解都是在这里完成的
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
//获取BeanClass的缓存key
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//advisedBeans保存了所有已经做过动态代理的Bean
// 如果被解析过则直接返回
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 1. 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解)
// 2. 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息,
// 而事务在这里是不会解析的)
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 targetSource = getCustomTargetSource(beanClass, beanName);
//如果有自定义targetSource就要这里创建代理对象
//这样做的好处是被代理的对象可以动态改变,而不是值针对一个target对象(可以对对象池中对象进行代理,可以每次创建代理都创建新对象
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
//获取Advisors, 这个是交给子类实现的
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
//返回代理的对象
return proxy;
}
return null;
}
}
AbstractAutoProxyCreator的postProcessBeforeInstantiation方法是在AbstractAutowireCapableBeanFactory类中的createBean方法中的创建Bean实例方法doCreateBean方法的前一步方法resolveBeforeInstantiation方法中被最终调用的。
resolveBeforeInstantiation
- 实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
@Nullable
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.
//1.mbd不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//2.解析beanName对应的Bean实例的类型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//3.实例化前的后置处理器应用(处理InstantiationAwareBeanPostProcessor)
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//4.如果返回的bean不为空,会跳过Spring默认的实例化过程
//所以只能在这里调用BeanPostProcessor实现类的PostProcessorsAfterInitialization方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
//5.如果bean不为空,则将beforeInstantiationResolved赋值为true,代表在实例化之前已经解析
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
//1.遍历当前BeanFactory中的BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//2.应用InstantiationAwareBeanPostProcessor后置处理器,允许PostProcessorBeforeInstantiation方法返回bean对象的代理
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//3.执行postProcessBeforeInstantiation方法,在Bean实例化前操作,
//该方法可以返回一个构造完成的Bean实例,从而不会继续执行创建Bean实例的"正规流程"
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
//4.如果result不为null,也就是有后置处理器返回了bean实例对象,则会跳过Spring默认的实例化过程。
return result;
}
}
}
return null;
}
}
因为AbstractAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口,所以,resolveBeforeInstantiation方法中的applyBeanPostProcessorsBeforeInstantiation方法中的代码ibp.postProcessBeforeInstantiation(beanClass, beanName)方法最终调用的是AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法完成的AOP相关横切逻辑的加载与解析的。
TargetSource
postProcessBeforeInstantiation方法中出现了TargetSource。
TargetSource(目标源)是被代理的target(目标对象)实例的来源。TargetSource被用于获取当前MethodInvocation(方法调用)所需要的target(目标对象),这个target通过反射的方式被调用(如:method.invode(target,args))。换句话说,proxy(代理对象)代理的不是target,而是TargetSource,这点非常重要!!!
通常情况下,一个proxy(代理对象)只能代理一个target,每次方法调用的目标也是唯一固定的target。但是,如果让proxy代理TargetSource,可以使得每次方法调用的target实例都不同(当然也可以相同,这取决于TargetSource实现)。这种机制使得方法调用变得灵活,可以扩展出很多高级功能,如:target pool(目标对象池)、hot swap(运行时目标对象热替换),等等。
public interface TargetSource extends TargetClassAware {
/**
* 返回当前目标源的目标类型
* 可以返回null值,如:EmptyTargetSource(未知类会使用这个目标源)
*/
@Override
@Nullable
Class<?> getTargetClass();
/**
* 当前目标源是否是静态的。
* 如果为false,则每次方法调用结束后会调用releaseTarget()释放目标对象.
* 如果为true,则目标对象不可变,也就没必要释放了。
*/
boolean isStatic();
/**
* 获取一个目标对象。
* 在每次MethodInvocation方法调用执行之前获取。
*/
@Nullable
Object getTarget() throws Exception;
/**
* 释放指定的目标对象。
*/
void releaseTarget(Object target) throws Exception;
}
详细的TargetSource:
Spring5AOP——TargetSource
getCustomTargetSource
- 获取用户自定义的targetSource,如果存在则直接在对象实例化之前进行代理创建,避免了目标对象不必要的实例化。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Nullable
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
// We can't create fancy target sources for directly registered singletons.
if (this.customTargetSourceCreators != null &&
this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
TargetSource ts = tsc.getTargetSource(beanClass, beanName);
if (ts != null) {
// Found a matching TargetSource.
if (logger.isTraceEnabled()) {
logger.trace("TargetSourceCreator [" + tsc +
"] found custom TargetSource for bean with name '" + beanName + "'");
}
return ts;
}
}
}
// No custom TargetSource found.
return null;
}
}
- 如果获取到用户自定义的targetSource实例,那么就要会走后续的创建AOP的动态代理的流程。
- 成功创建代理之后,就将代理的类型放入到proxyTypes缓存中,便于后续的获取,之后将代理实例返回。
- 这就就完成了AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法的执行。
到这里AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法的下半部分就攻克了,现在回到上半部分。
!this.targetSourcedBeans.contains(beanName)
回到AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法中,如果此时传入的beanName没有出现在用户自定义的targetSourcedBeans缓存列表里面,则会进入到下面方法里面。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
//当在实例化前置方法 postProcessBeforeInstantiation 中创建了代理类,
// 则在 targetSourcedBeans 中将添加 beanName,
// 也就是 targetSourcedBeans 中含有 beanName
// 则说明这个类被动态代理了
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
/**
* 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后)
* AOP解析切面以及事务解析事务注解都是在这里完成的
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
//获取BeanClass的缓存key
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//advisedBeans保存了所有已经做过动态代理的Bean
// 如果被解析过则直接返回
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 1. 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解)
// 2. 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息,
// 而事务在这里是不会解析的)
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
......
return null;
}
}
isInfrastructureClass(beanClass)
- 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解)
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
}
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
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("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
}
如果beanClass是Spring AOP的基础服务类的话,将对应于该Bean的cacheKey作为key添加到advisedBeans里面,并且将其对应的值设置为false,以标识这个是已经处理过的不需要包装的Spring AOP基础服务Bean。
shouldSkip(beanClass, beanName)
- 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息,而事务在这里是不会解析的)
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
//找到候选的Advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
}
findCandidateAdvisors()
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 使用注解方式配置AOP的时候还是能够支持对XML配置的AOP的支持的.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
}
super.findCandidateAdvisors()
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@Nullable
private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
}
this.advisorRetrievalHelper.findAdvisorBeans()
public class BeanFactoryAdvisorRetrievalHelper {
private final ConfigurableListableBeanFactory beanFactory;
@Nullable
private volatile String[] cachedAdvisorBeanNames;
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
// 先尝试从缓存中获取容器中所有 Advisor bean 的名称
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
// 如果缓存为空,尝试从容器以及其父容器分析得到所有 Advisor bean 的名称
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
// 添加进缓存
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
// 创建中的 bean 会被忽略
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
}
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
- 以注解的形式尝试从容器加载注解形式的Advisors
aspectJAdvisorsBuilder.buildAspectJAdvisors()方法主要作用
- 从容器中获取所有的bean
- 遍历beanName,解析出被@Aspect标记的类
- 提取Aspect类里的Advisors
- 将提取的结果加入缓存
public class BeanFactoryAspectJAdvisorsBuilder {
private final ListableBeanFactory beanFactory;
private final AspectJAdvisorFactory advisorFactory;
@Nullable
private volatile List<String> aspectBeanNames;
private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>();
private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache = new ConcurrentHashMap<>();
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
//用于保存切面的名称的集合
aspectNames = new ArrayList<>();
//获取所有的beanName
// AOP功能中在这里传入的是Object对象,代表去容器中获取到所有的组件的名称,然后再
// 进行遍历,这个过程是十分的消耗性能的,所以说Spring会再这里加入了保存切面信息的缓存。
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//遍历我们从IOC容器中获取处的所有Bean的名称
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
//获取对应的bean的类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//提取@Aspect注解标记的Class
if (this.advisorFactory.isAspect(beanType)) {
//是切面类
//加入到缓存中
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//Aspect里面的advice和pointcut被拆分成一个个的advisor,
// advisor里的advice和pointcut是1对1的关系
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
//单例则直接将Advisor类存到缓存
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// 否则将其对应的工厂缓存
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
}
this.advisorFactory.getAdvisors(factory)
- Aspect里面的advice和pointcut被拆分成一个个的advisor。
- advisor里的advice和pointcut是1对1的关系。
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//获取Aspect的类Class
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//获取Aspect的类名
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
//校验切面类
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
//我们使用的是包装模式来包装我们的MetadataAwareAspectInstanceFactory
// 构建为MetadataAwareAspectInstanceFactory
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
//获取到切面类中的所有方法,但是该方法不会解析到标注了@PointCut注解的方法
for (Method method : getAdvisorMethods(aspectClass)) {
//循环解析切面中的方法
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
// 处理Introduction相关的Advice
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
}
getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
- 获取到切面类中的所有方法,但是该方法不会解析到标注了@PointCut注解的方法。
- 循环解析切面中的方法。
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//切面的方法上构建切点表达式
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//实例化我们的切面Advisor对象
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
}
getPointcut()
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//找到Advice注解标签,并解析注解标签里面的pointCut属性值存储在AspectJAnnotation里
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}
}
new InstantiationModelAwarePointcutAdvisorImpl()
final class InstantiationModelAwarePointcutAdvisorImpl
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//当前的Pointcut表达式
this.declaredPointcut = declaredPointcut;
//切面的class对象
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
//切面方法的名称
this.methodName = aspectJAdviceMethod.getName();
//切面方法的参数类型
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
//切面方法对象
this.aspectJAdviceMethod = aspectJAdviceMethod;
//aspectj的Advisor工厂
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
//aspect的实例工厂
this.aspectInstanceFactory = aspectInstanceFactory;
//切面的顺序
this.declarationOrder = declarationOrder;
//切面的名称
this.aspectName = aspectName;
//判断当前的切面对象是否需要延时加载
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
//将切面中的通知构造为advice通知对象
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
}
instantiateAdvice(this.declaredPointcut)
final class InstantiationModelAwarePointcutAdvisorImpl
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
}
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取我们的切面类的class对象
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//获取切面方法上的注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
//判断是否是注解切面对象
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
//判断标注在方法上的注解类型
switch (aspectJAnnotation.getAnnotationType()) {
//是PointCut注解 那么就抛出异常 因为在外面传递进来的方法已经排除了Pointcut的方法
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
//环绕通知 构建AspectJAroundAdvice
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//前置通知 构建AspectJMethodBeforeAdvice
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//后置通知 AspectJAfterAdvice
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//返回通知 AspectJAfterReturningAdvice
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
//异常通知 AspectJAfterThrowingAdvice
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
//设置我们构建出来的通知对象的相关属性比如DeclarationOrder,
// 在代理调用的时候,责任链顺序上会用
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
}
至此,就完成了Spring AOP横切逻辑的加载与解析。
参考:
https://segmentfault.com/a/1190000015830477
https://www.cnblogs.com/foreveravalon/p/8653832.html
https://www.cnblogs.com/qinzj/p/11415057.html