首先通过方法得到所有的增强,这里我们看下基于注解的 AOP,所以来到 AnnotationAwareAspectJAutoProxyCreator。
- 首先调用了父类的查找增强的方法,也就是定义在xml中的增强;
 - 然后查找基于注解的增强,也就是说这里既包含注解配置的增强也包含xml配置的增强;
@Overrideprotected List<Advisor> findCandidateAdvisors() {// Add all the Spring advisors found according to superclass rules.// 调用父类的方法,这里是xml配置的增强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 方法
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<>();// 给类型Object.class相当于查询所有的String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);for (String beanName : beanNames) {// 不合法的 bean 则略过,由子类定义规则,默认返回 trueif (!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, false);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) {MetadataAwareAspectInstanceFactory factory =new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);// 获得增强的方法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;}
isAspect
@Overridepublic boolean isAspect(Class<?> clazz) {return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));}private boolean hasAspectAnnotation(Class<?> clazz) {return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);}/*** We need to detect this as "code-style" AspectJ aspects should not be* interpreted by Spring AOP.*/private boolean compiledByAjc(Class<?> clazz) {// The AJTypeSystem goes to great lengths to provide a uniform appearance between code-style and// annotation-style aspects. Therefore there is no 'clean' way to tell them apart. Here we rely on// an implementation detail of the AspectJ compiler.for (Field field : clazz.getDeclaredFields()) {if (field.getName().startsWith(AJC_MAGIC)) {return true;}}return false;}
这段代码用来判断是否为增强类,通过两个方面来判断:
- 包含注解,Aspect ;
 - 检查给定的Class对象是否由 AspectJ 编译器编译过。它通过检查Class对象中是否存在以“AJC_MAGIC (ajc$)”字符串开头的私有字段来实现。
 
如果包含注解,并且没有被AspectJ 编译过那么就返回 TRUE.
🔥 getAdvisors
获取增强器,也就是增强的方法。
@Overridepublic List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {// 获取增强类ClassClass<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();// 获取类名称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<>();for (Method method : getAdvisorMethods(aspectClass)) {// Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect// to getAdvisor(...) to represent the "current position" in the declared methods list.// However, since Java 7 the "current position" is not valid since the JDK no longer// returns declared methods in the order in which they are declared in the source code.// Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods// discovered via reflection in order to support reliable advice ordering across JVM launches.// Specifically, a value of 0 aligns with the default value used in// AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, 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.// 获取 DeclareParents 注解for (Field field : aspectClass.getDeclaredFields()) {Advisor advisor = getDeclareParentsAdvisor(field);if (advisor != null) {advisors.add(advisor);}}return advisors;}
主要流程:
- 首先获取增强类的Class;
 - 获取增强类的名称;
 - 验证下增强类;
 - 获得增强类中的增强方法;
 通过方法 getAdvisor 将增强方法包装成 Advisor;
getAdvisorMethods
private List<Method> getAdvisorMethods(Class<?> aspectClass) {final List<Method> methods = new ArrayList<>();ReflectionUtils.doWithMethods(aspectClass, method -> {// Exclude pointcutsif (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {methods.add(method);}}, ReflectionUtils.USER_DECLARED_METHODS);if (methods.size() > 1) {methods.sort(METHOD_COMPARATOR);}return methods;}
获取增强类中的方法。利用 ReflectionUtils.doWithMethods 方法,方法的后两个参数为两个函数式接口。MethodCallback 用于查找方法,MethodFilter 用于过滤方法。
getAdvisor
@Override@Nullablepublic 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;}// 根据切点信息生成增强器return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,this, aspectInstanceFactory, declarationOrderInAspect, aspectName);}
在上一步得到增强类的方法后:
主要过程:验证下增强类的信息;
- 获得切点的信息;
 - 根据切点生成增强器。所有的增强都由 Advisor 的实现类 InstantiationModelAwarePointcutAdvisorImpl 统一封装。
 
获取切点信息。
@Nullableprivate AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {// 获取切点信息,如:@Pointcut(value = "execution(* cn.lichenghao.aop.jdk.service.impl.*.*(..))")AspectJAnnotation<?> aspectJAnnotation =AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);if (aspectJAnnotation == null) {return null;}// 封装信息到 AspectJExpressionPointcutAspectJExpressionPointcut ajexp =new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);ajexp.setExpression(aspectJAnnotation.getPointcutExpression());if (this.beanFactory != null) {ajexp.setBeanFactory(this.beanFactory);}return ajexp;}
根据切点把增强方法封装。
最终都封装成 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;this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);}}
最终有个方法 instantiateAdvice 实例化增强方法。
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);}
@Override@Nullablepublic Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {// 得到增强类ClassClass<?> 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 classif (!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()) {case AtPointcut:if (logger.isDebugEnabled()) {logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");}return null;case AtAround:springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtBefore:springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtAfter:springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtAfterReturning:springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();if (StringUtils.hasText(afterReturningAnnotation.returning())) {springAdvice.setReturningName(afterReturningAnnotation.returning());}break;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...springAdvice.setAspectName(aspectName);springAdvice.setDeclarationOrder(declarationOrder);String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);if (argNames != null) {springAdvice.setArgumentNamesFromStringArray(argNames);}springAdvice.calculateArgumentBindings();return springAdvice;}
主要流程:
- 得到增强类的Class,并验证;
 - 得到方法上的注解信息;
 - 根据注解类型实例化不同增强方法对象;
 - 完善上面增强方法对象。
 
我们会得到 AspectJAroundAdvice、AspectJMethodBeforeAdvice、AspectJAfterAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice _5种类型的增强器。他们会被运用在不同的拦截器中,比如:
_MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor 等。
SyntheticInstantiationAdvisor
如果寻找的增强器不为空而且又配置了增强延迟初始化,那么就需要在首位加人同步实例化增强器。
@SuppressWarnings("serial")protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor {public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {super(aif.getAspectMetadata().getPerClausePointcut(), (MethodBeforeAdvice)(method, args, target) -> aif.getAspectInstance());}}
DeclareParents 的增强
for (Field field : aspectClass.getDeclaredFields()) {Advisor advisor = getDeclareParentsAdvisor(field);if (advisor != null) {advisors.add(advisor);}}@Nullableprivate Advisor getDeclareParentsAdvisor(Field introductionField) {DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);if (declareParents == null) {// Not an introduction fieldreturn null;}if (DeclareParents.class == declareParents.defaultImpl()) {throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents");}return new DeclareParentsAdvisor(introductionField.getType(), declareParents.value(), declareParents.defaultImpl());}
DeclareParents 主要用于引介增强的注解形式的实现,而其实现方式与普通增强很类似,只不过使用 DeclareParentsAdvisor 对功能进行封装。
