首先通过方法得到所有的增强,这里我们看下基于注解的 AOP,所以来到 AnnotationAwareAspectJAutoProxyCreator。

  1. 首先调用了父类的查找增强的方法,也就是定义在xml中的增强;
  2. 然后查找基于注解的增强,也就是说这里既包含注解配置的增强也包含xml配置的增强;
    1. @Override
    2. protected List<Advisor> findCandidateAdvisors() {
    3. // Add all the Spring advisors found according to superclass rules.
    4. // 调用父类的方法,这里是xml配置的增强
    5. List<Advisor> advisors = super.findCandidateAdvisors();
    6. // Build Advisors for all AspectJ aspects in the bean factory.
    7. // 得到基于注解的增强
    8. if (this.aspectJAdvisorsBuilder != null) {
    9. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    10. }
    11. return advisors;
    12. }

接下来进入提取注解增强:
进入 buildAspectJAdvisors 方法

  1. public List<Advisor> buildAspectJAdvisors() {
  2. List<String> aspectNames = this.aspectBeanNames;
  3. if (aspectNames == null) {
  4. synchronized (this) {
  5. aspectNames = this.aspectBeanNames;
  6. if (aspectNames == null) {
  7. List<Advisor> advisors = new ArrayList<>();
  8. aspectNames = new ArrayList<>();
  9. // 给类型Object.class相当于查询所有的
  10. String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
  11. this.beanFactory, Object.class, true, false);
  12. for (String beanName : beanNames) {
  13. // 不合法的 bean 则略过,由子类定义规则,默认返回 true
  14. if (!isEligibleBean(beanName)) {
  15. continue;
  16. }
  17. // We must be careful not to instantiate beans eagerly as in this case they
  18. // would be cached by the Spring container but would not have been weaved.
  19. Class<?> beanType = this.beanFactory.getType(beanName, false);
  20. if (beanType == null) {
  21. continue;
  22. }
  23. // 判断是否为增强类。表现为:包括Aspect注解以及不是生成的代理类
  24. if (this.advisorFactory.isAspect(beanType)) {
  25. aspectNames.add(beanName);
  26. // 生成增强类的元数据
  27. AspectMetadata amd = new AspectMetadata(beanType, beanName);
  28. if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
  29. MetadataAwareAspectInstanceFactory factory =
  30. new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
  31. // 获得增强的方法
  32. List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
  33. if (this.beanFactory.isSingleton(beanName)) {
  34. this.advisorsCache.put(beanName, classAdvisors);
  35. } else {
  36. this.aspectFactoryCache.put(beanName, factory);
  37. }
  38. advisors.addAll(classAdvisors);
  39. } else {
  40. // Per target or per this.
  41. if (this.beanFactory.isSingleton(beanName)) {
  42. throw new IllegalArgumentException("Bean with name '" + beanName +
  43. "' is a singleton, but aspect instantiation model is not singleton");
  44. }
  45. MetadataAwareAspectInstanceFactory factory =
  46. new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
  47. this.aspectFactoryCache.put(beanName, factory);
  48. advisors.addAll(this.advisorFactory.getAdvisors(factory));
  49. }
  50. }
  51. }
  52. this.aspectBeanNames = aspectNames;
  53. return advisors;
  54. }
  55. }
  56. }
  57. // 判断空
  58. if (aspectNames.isEmpty()) {
  59. return Collections.emptyList();
  60. }
  61. List<Advisor> advisors = new ArrayList<>();
  62. for (String aspectName : aspectNames) {
  63. List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
  64. if (cachedAdvisors != null) {
  65. advisors.addAll(cachedAdvisors);
  66. } else {
  67. MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
  68. advisors.addAll(this.advisorFactory.getAdvisors(factory));
  69. }
  70. }
  71. return advisors;
  72. }

isAspect

  1. @Override
  2. public boolean isAspect(Class<?> clazz) {
  3. return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
  4. }
  5. private boolean hasAspectAnnotation(Class<?> clazz) {
  6. return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
  7. }
  8. /**
  9. * We need to detect this as "code-style" AspectJ aspects should not be
  10. * interpreted by Spring AOP.
  11. */
  12. private boolean compiledByAjc(Class<?> clazz) {
  13. // The AJTypeSystem goes to great lengths to provide a uniform appearance between code-style and
  14. // annotation-style aspects. Therefore there is no 'clean' way to tell them apart. Here we rely on
  15. // an implementation detail of the AspectJ compiler.
  16. for (Field field : clazz.getDeclaredFields()) {
  17. if (field.getName().startsWith(AJC_MAGIC)) {
  18. return true;
  19. }
  20. }
  21. return false;
  22. }

这段代码用来判断是否为增强类,通过两个方面来判断:

  • 包含注解,Aspect ;
  • 检查给定的Class对象是否由 AspectJ 编译器编译过。它通过检查Class对象中是否存在以“AJC_MAGIC (ajc$)”字符串开头的私有字段来实现。

如果包含注解,并且没有被AspectJ 编译过那么就返回 TRUE.

🔥 getAdvisors

获取增强器,也就是增强的方法。

  1. @Override
  2. public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
  3. // 获取增强类Class
  4. Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
  5. // 获取类名称
  6. String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
  7. // 验证下
  8. validate(aspectClass);
  9. // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
  10. // so that it will only instantiate once.
  11. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
  12. new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
  13. List<Advisor> advisors = new ArrayList<>();
  14. for (Method method : getAdvisorMethods(aspectClass)) {
  15. // Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
  16. // to getAdvisor(...) to represent the "current position" in the declared methods list.
  17. // However, since Java 7 the "current position" is not valid since the JDK no longer
  18. // returns declared methods in the order in which they are declared in the source code.
  19. // Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
  20. // discovered via reflection in order to support reliable advice ordering across JVM launches.
  21. // Specifically, a value of 0 aligns with the default value used in
  22. // AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
  23. Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
  24. if (advisor != null) {
  25. advisors.add(advisor);
  26. }
  27. }
  28. // If it's a per target aspect, emit the dummy instantiating aspect.
  29. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
  30. // 如果寻找的增强器不为空而且又配置了增强延迟初始化,那么需要在首位加人同步实例化增强器
  31. Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
  32. advisors.add(0, instantiationAdvisor);
  33. }
  34. // Find introduction fields.
  35. // 获取 DeclareParents 注解
  36. for (Field field : aspectClass.getDeclaredFields()) {
  37. Advisor advisor = getDeclareParentsAdvisor(field);
  38. if (advisor != null) {
  39. advisors.add(advisor);
  40. }
  41. }
  42. return advisors;
  43. }

主要流程:

  1. 首先获取增强类的Class;
  2. 获取增强类的名称;
  3. 验证下增强类;
  4. 获得增强类中的增强方法;
  5. 通过方法 getAdvisor 将增强方法包装成 Advisor

    getAdvisorMethods

    1. private List<Method> getAdvisorMethods(Class<?> aspectClass) {
    2. final List<Method> methods = new ArrayList<>();
    3. ReflectionUtils.doWithMethods(aspectClass, method -> {
    4. // Exclude pointcuts
    5. if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
    6. methods.add(method);
    7. }
    8. }, ReflectionUtils.USER_DECLARED_METHODS);
    9. if (methods.size() > 1) {
    10. methods.sort(METHOD_COMPARATOR);
    11. }
    12. return methods;
    13. }

    获取增强类中的方法。利用 ReflectionUtils.doWithMethods 方法,方法的后两个参数为两个函数式接口。MethodCallback 用于查找方法,MethodFilter 用于过滤方法。

    getAdvisor

    1. @Override
    2. @Nullable
    3. public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
    4. int declarationOrderInAspect, String aspectName) {
    5. // 验证
    6. validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
    7. // 切点信息
    8. AspectJExpressionPointcut expressionPointcut =
    9. getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    10. if (expressionPointcut == null) {
    11. return null;
    12. }
    13. // 根据切点信息生成增强器
    14. return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
    15. this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    16. }

    在上一步得到增强类的方法后:
    主要过程:

  6. 验证下增强类的信息;

  7. 获得切点的信息;
  8. 根据切点生成增强器。所有的增强都由 Advisor 的实现类 InstantiationModelAwarePointcutAdvisorImpl 统一封装。

获取切点信息。

  1. @Nullable
  2. private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
  3. // 获取切点信息,如:@Pointcut(value = "execution(* cn.lichenghao.aop.jdk.service.impl.*.*(..))")
  4. AspectJAnnotation<?> aspectJAnnotation =
  5. AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
  6. if (aspectJAnnotation == null) {
  7. return null;
  8. }
  9. // 封装信息到 AspectJExpressionPointcut
  10. AspectJExpressionPointcut ajexp =
  11. new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
  12. ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
  13. if (this.beanFactory != null) {
  14. ajexp.setBeanFactory(this.beanFactory);
  15. }
  16. return ajexp;
  17. }

根据切点把增强方法封装。
最终都封装成 InstantiationModelAwarePointcutAdvisorImpl 对象。
如下代码,操作都是属性赋值。

  1. public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
  2. Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
  3. MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
  4. this.declaredPointcut = declaredPointcut;
  5. this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
  6. this.methodName = aspectJAdviceMethod.getName();
  7. this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
  8. this.aspectJAdviceMethod = aspectJAdviceMethod;
  9. this.aspectJAdvisorFactory = aspectJAdvisorFactory;
  10. this.aspectInstanceFactory = aspectInstanceFactory;
  11. this.declarationOrder = declarationOrder;
  12. this.aspectName = aspectName;
  13. if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
  14. // Static part of the pointcut is a lazy type.
  15. Pointcut preInstantiationPointcut = Pointcuts.union(
  16. aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
  17. // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
  18. // If it's not a dynamic pointcut, it may be optimized out
  19. // by the Spring AOP infrastructure after the first evaluation.
  20. this.pointcut = new PerTargetInstantiationModelPointcut(
  21. this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
  22. this.lazy = true;
  23. }
  24. else {
  25. // A singleton aspect.
  26. this.pointcut = this.declaredPointcut;
  27. this.lazy = false;
  28. this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
  29. }
  30. }

最终有个方法 instantiateAdvice 实例化增强方法。

  1. private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
  2. Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
  3. this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
  4. return (advice != null ? advice : EMPTY_ADVICE);
  5. }
  1. @Override
  2. @Nullable
  3. public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
  4. MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
  5. // 得到增强类Class
  6. Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
  7. // 验证
  8. validate(candidateAspectClass);
  9. // 得到注解信息
  10. AspectJAnnotation<?> aspectJAnnotation =
  11. AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
  12. if (aspectJAnnotation == null) {
  13. return null;
  14. }
  15. // If we get here, we know we have an AspectJ method.
  16. // Check that it's an AspectJ-annotated class
  17. if (!isAspect(candidateAspectClass)) {
  18. throw new AopConfigException("Advice must be declared inside an aspect type: " +
  19. "Offending method '" + candidateAdviceMethod + "' in class [" +
  20. candidateAspectClass.getName() + "]");
  21. }
  22. if (logger.isDebugEnabled()) {
  23. logger.debug("Found AspectJ method: " + candidateAdviceMethod);
  24. }
  25. AbstractAspectJAdvice springAdvice;
  26. // 判断注解的类型,实例化不同的增强方法对象
  27. switch (aspectJAnnotation.getAnnotationType()) {
  28. case AtPointcut:
  29. if (logger.isDebugEnabled()) {
  30. logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
  31. }
  32. return null;
  33. case AtAround:
  34. springAdvice = new AspectJAroundAdvice(
  35. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  36. break;
  37. case AtBefore:
  38. springAdvice = new AspectJMethodBeforeAdvice(
  39. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  40. break;
  41. case AtAfter:
  42. springAdvice = new AspectJAfterAdvice(
  43. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  44. break;
  45. case AtAfterReturning:
  46. springAdvice = new AspectJAfterReturningAdvice(
  47. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  48. AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
  49. if (StringUtils.hasText(afterReturningAnnotation.returning())) {
  50. springAdvice.setReturningName(afterReturningAnnotation.returning());
  51. }
  52. break;
  53. case AtAfterThrowing:
  54. springAdvice = new AspectJAfterThrowingAdvice(
  55. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  56. AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
  57. if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
  58. springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
  59. }
  60. break;
  61. default:
  62. throw new UnsupportedOperationException(
  63. "Unsupported advice type on method: " + candidateAdviceMethod);
  64. }
  65. // Now to configure the advice...
  66. springAdvice.setAspectName(aspectName);
  67. springAdvice.setDeclarationOrder(declarationOrder);
  68. String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
  69. if (argNames != null) {
  70. springAdvice.setArgumentNamesFromStringArray(argNames);
  71. }
  72. springAdvice.calculateArgumentBindings();
  73. return springAdvice;
  74. }

主要流程:

  1. 得到增强类的Class,并验证;
  2. 得到方法上的注解信息;
  3. 根据注解类型实例化不同增强方法对象;
  4. 完善上面增强方法对象。

我们会得到 AspectJAroundAdviceAspectJMethodBeforeAdviceAspectJAfterAdviceAspectJAfterReturningAdviceAspectJAfterThrowingAdvice _5种类型的增强器。他们会被运用在不同的拦截器中,比如:
_MethodBeforeAdviceInterceptor
AfterReturningAdviceInterceptor 等。

SyntheticInstantiationAdvisor

如果寻找的增强器不为空而且又配置了增强延迟初始化,那么就需要在首位加人同步实例化增强器。

  1. @SuppressWarnings("serial")
  2. protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor {
  3. public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {
  4. super(aif.getAspectMetadata().getPerClausePointcut(), (MethodBeforeAdvice)
  5. (method, args, target) -> aif.getAspectInstance());
  6. }
  7. }

DeclareParents 的增强

  1. for (Field field : aspectClass.getDeclaredFields()) {
  2. Advisor advisor = getDeclareParentsAdvisor(field);
  3. if (advisor != null) {
  4. advisors.add(advisor);
  5. }
  6. }
  7. @Nullable
  8. private Advisor getDeclareParentsAdvisor(Field introductionField) {
  9. DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
  10. if (declareParents == null) {
  11. // Not an introduction field
  12. return null;
  13. }
  14. if (DeclareParents.class == declareParents.defaultImpl()) {
  15. throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents");
  16. }
  17. return new DeclareParentsAdvisor(
  18. introductionField.getType(), declareParents.value(), declareParents.defaultImpl());
  19. }

DeclareParents 主要用于引介增强的注解形式的实现,而其实现方式与普通增强很类似,只不过使用 DeclareParentsAdvisor 对功能进行封装。