主要流程
1 找到所有的候选切面 findCandidateAdvisors
1.1 获取所有的 BeanDefinition 的名称,进而获取所有的 Class 对象
1.2 将 Class 里有 @Aspect 注解信息的收集起来
1.3 根据有 @Aspect 注解信息的类获取切面 getAdvisors
1.3.1 找到所有没有 @PointCut 注解的方法 getAdvisorMethods
1.3.1.1 每一个找到的方法都可以创建一个切面 getAdvisor
1.3.1.1.1 找到这个 Advisor 里的切点 getPointCut
1.3.1.1.1.1 获取方法上面的注解,封装成 AspectJAnnotation 对象 findAspectJAnnotationOnMethod
1.3.1.1.1.2 创建 AspectJExpressionPointcut 对象,把 AspectJAnnotation 中的表达式设置进去
1.3.1.1.2 创建 InstantiationModelAwarePointCutAdvisorImpl 对象
1.3.1.1.2.1 实例化增强 instantiateAdvice 拿到增强 getAdvice
1.3.1.1.2.1.1 找到方法上的注解,封装成 AspectJAnnotation 对象
1.3.1.1.2.1.2 根据注解类型的不同,创建不同的 Advice对象
2 利用 Advisor 里的 PointCut 和当前 bean 进行模糊匹配 findAdvisorsThatCanApply
3 对作用在该 bean 上的切面进行排序 sortAdvisors
@Aspect 的使用
@Component
@Aspect
public class AspectAnnotation {
@Pointcut("execution(public * com.aop.service.*.*(..))")
public void pc1(){}
@Around("pc1()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("=========AspectAnnotation around前置通知=========");
//可以通过下面的方法拿到入参
//Object[] args = joinPoint.getArgs();
Object result = joinPoint.proceed();
System.out.println("=========AspectAnnotation around后置通知=========");
return result;
//如果方法上有@ReturnValue(name = "returnValue")注解,可以拿到返回值
//@ReturnValue是自定义的
@AfterReturning(value = "@annotation(returnValue)",returning = "retVal")
public void afterReturning(JoinPoint joinPoint, ReturnValue returnValue, Object retVal) {
System.out.println("==============AspectAnnotation 后置通知 拿返回值=========" + retVal);
}
}
跟源码
类AbstractAutoProxyCreator
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//找到合格的切面,重点看
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
跟 findEligibleAdvisors:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//找到候选的切面,其实就是一个寻找所有有@Aspect注解的过程,把工程中所有有这个注解的类封装成Advisor返回
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//判断候选的切面是否作用在当前beanClass上面,就是一个匹配过程。现在就是一个匹配
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//对有@Order@Priority进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
跟 findCandidateAdvisors:
类 AnnotationAwareAspectJAutoProxyCreator
@Override
protected List<Advisor> findCandidateAdvisors() {
//可以不看
// Add all the Spring advisors found according to superclass rules.
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;
}
跟 buildAspectJAdvisors:
类 BeanFactoryAspectJAdvisorsBuilder
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<>();
//获取spring容器中的所有bean的名称BeanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
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.
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//判断类上是否有@Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//创建获取有@Aspect注解类的实例工厂,负责获取有@Aspect注解类的实例
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//创建切面advisor对象
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
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;
}
跟 getAdvisors:
类 AspectJAdvisorFactory
类 ReflectiveAspectJAdvisorFactory
@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 lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
//这里循环没有@Pointcut注解的方法
for (Method method : getAdvisorMethods(aspectClass)) {
//非常重要重点看看,重要程度 5
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.
for (Field field : aspectClass.getDeclaredFields()) {
//判断属性上是否有DeclareParents注解,如果有返回切面
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
跟 getAdvisor:
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//获取pointCut对象,最重要的是从注解中获取表达式
//见3.1.1
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut 2、advice
//这里pointCut是expressionPointcut, advice 增强方法是 candidateAdviceMethod
//见 3.1.2
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
3.1.1 getPointcut
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//从候选的增强方法里面 candidateAdviceMethod 找有有注解
//Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
//并把注解信息封装成AspectJAnnotation对象
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
//创建一个PointCut类,并且把前面从注解里面解析的表达式设置进去
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;
}
跟 findAspectJAnnotationOnMethod:
@SuppressWarnings("unchecked")
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
//找到Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
//注解的方法,并且把注解里面的信息封装成AspectJAnnotation对象
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
3.1.2 InstantiationModelAwarePointcutAdvisorImpl
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
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:
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
//创建Advice对象
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
跟 getAdvice:
类 AspectJAdvisorFactory
类 ReflectiveAspectJAdvisorFactory
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取有@Aspect注解的类
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象,这个对象中就有注解类型
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;
//根据不同的注解类型创建不同的advice类实例
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
//实现了MethodInterceptor接口
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
//实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
//实现了MethodInterceptor接口
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
//实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
//实现了MethodInterceptor接口
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...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
//计算argNames和类型的对应关系
springAdvice.calculateArgumentBindings();
return springAdvice;
}