Spring可以以注解的方式使用AOP的原因就是在XML中<aop:aspectj-autoproxy/>,分析注解式AOP就要从这句话入手

动态AOP自定义标签

一旦遇到<aop:aspectj-autoproxy/>AopNamespaceHandler就会注册AspectJAutoProxyBeanDefinitionParser

注册AnnotationAwareAspectJAutoProxyCreator

AspectJAutoProxyBeanDefinitionParserparse中注册了AnnotationAwareAspectJAutoProxyCreator

  1. public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
  2. ParserContext parserContext, Element sourceElement) {
  3. BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
  4. parserContext.getRegistry(), parserContext.extractSource(sourceElement));
  5. useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
  6. registerComponentIfNecessary(beanDefinition, parserContext);
  7. }
  1. 注册或者升级AnnotationAwareAspectJAutoProxyCreator

    1. @Nullable
    2. private static BeanDefinition registerOrEscalateApcAsRequired(
    3. Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    4. Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    5. if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
    6. BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
    7. if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
    8. int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
    9. int requiredPriority = findPriorityForClass(cls);
    10. if (currentPriority < requiredPriority) {
    11. apcDefinition.setBeanClassName(cls.getName());
    12. }
    13. }
    14. return null;
    15. }
    16. RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    17. beanDefinition.setSource(source);
    18. beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    19. beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    20. registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    21. return beanDefinition;
    22. }

    实现了自动注册AnnotationAwareAspectJAutoProxyCreator类的功能

  2. 处理proxy-target-class以及expose-proxy属性

    1. private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
    2. if (sourceElement != null) {
    3. boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
    4. if (proxyTargetClass) {
    5. AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
    6. }
    7. boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
    8. if (exposeProxy) {
    9. AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
    10. }
    11. }
    12. }
  • proxy-target-class:设置为true,强制使用CGLIB
    • 无法通知final
    • 需要引入cglib包
    • CGLIB底层依靠ASM
  • expose-proxy:暴露代理对象,解决同类调用问题
    • ((AService)AopContext.currentProxy()).b();

创建AOP代理

AnnotationAwareAspectJAutoProxyCreator是用来创建AOP代理对象的,类结构如下:
image.png

类是实现了BeanPostProcessor的,主要是其postProcessAfterInitialization中的逻辑

  1. @Override
  2. public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  3. if (bean != null) {
  4. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  5. if (this.earlyProxyReferences.remove(cacheKey) != bean) {
  6. return wrapIfNecessary(bean, beanName, cacheKey);
  7. }
  8. }
  9. return bean;
  10. }
  11. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  12. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
  13. return bean;
  14. }
  15. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  16. return bean;
  17. }
  18. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  19. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  20. return bean;
  21. }
  22. // Create proxy if we have advice.
  23. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  24. if (specificInterceptors != DO_NOT_PROXY) {
  25. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  26. Object proxy = createProxy(
  27. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  28. this.proxyTypes.put(cacheKey, proxy.getClass());
  29. return proxy;
  30. }
  31. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  32. return bean;
  33. }
  1. 获取增强方法或者增强器
  2. 根据获取的增强器惊醒代理

image.png

  1. @Override
  2. @Nullable
  3. protected Object[] getAdvicesAndAdvisorsForBean(
  4. Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
  5. List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
  6. if (advisors.isEmpty()) {
  7. return DO_NOT_PROXY;
  8. }
  9. return advisors.toArray();
  10. }
  11. protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  12. List<Advisor> candidateAdvisors = findCandidateAdvisors();
  13. List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  14. extendAdvisors(eligibleAdvisors);
  15. if (!eligibleAdvisors.isEmpty()) {
  16. eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  17. }
  18. return eligibleAdvisors;
  19. }

主要做了两件事: findCandidateAdvisors findAdvisorsThatCanApply

获取增强器-findCandidateAdvisors

  1. @Override
  2. protected List<Advisor> findCandidateAdvisors() {
  3. // Add all the Spring advisors found according to superclass rules.
  4. List<Advisor> advisors = super.findCandidateAdvisors();
  5. // Build Advisors for all AspectJ aspects in the bean factory.
  6. if (this.aspectJAdvisorsBuilder != null) {
  7. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
  8. }
  9. return advisors;
  10. }
  11. @Override
  12. protected List<Advisor> findCandidateAdvisors() {
  13. // Add all the Spring advisors found according to superclass rules.
  14. List<Advisor> advisors = super.findCandidateAdvisors();
  15. // Build Advisors for all AspectJ aspects in the bean factory.
  16. if (this.aspectJAdvisorsBuilder != null) {
  17. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
  18. }
  19. return advisors;
  20. }

this.aspectJAdvisorsBuilder.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. String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
  10. this.beanFactory, Object.class, true, false);
  11. for (String beanName : beanNames) {
  12. if (!isEligibleBean(beanName)) {
  13. continue;
  14. }
  15. // We must be careful not to instantiate beans eagerly as in this case they
  16. // would be cached by the Spring container but would not have been weaved.
  17. Class<?> beanType = this.beanFactory.getType(beanName, false);
  18. if (beanType == null) {
  19. continue;
  20. }
  21. if (this.advisorFactory.isAspect(beanType)) {
  22. aspectNames.add(beanName);
  23. AspectMetadata amd = new AspectMetadata(beanType, beanName);
  24. if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
  25. MetadataAwareAspectInstanceFactory factory =
  26. new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
  27. List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
  28. if (this.beanFactory.isSingleton(beanName)) {
  29. this.advisorsCache.put(beanName, classAdvisors);
  30. }
  31. else {
  32. this.aspectFactoryCache.put(beanName, factory);
  33. }
  34. advisors.addAll(classAdvisors);
  35. }
  36. else {
  37. // Per target or per this.
  38. if (this.beanFactory.isSingleton(beanName)) {
  39. throw new IllegalArgumentException("Bean with name '" + beanName +
  40. "' is a singleton, but aspect instantiation model is not singleton");
  41. }
  42. MetadataAwareAspectInstanceFactory factory =
  43. new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
  44. this.aspectFactoryCache.put(beanName, factory);
  45. advisors.addAll(this.advisorFactory.getAdvisors(factory));
  46. }
  47. }
  48. }
  49. this.aspectBeanNames = aspectNames;
  50. return advisors;
  51. }
  52. }
  53. }
  54. if (aspectNames.isEmpty()) {
  55. return Collections.emptyList();
  56. }
  57. List<Advisor> advisors = new ArrayList<>();
  58. for (String aspectName : aspectNames) {
  59. List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
  60. if (cachedAdvisors != null) {
  61. advisors.addAll(cachedAdvisors);
  62. }
  63. else {
  64. MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
  65. advisors.addAll(this.advisorFactory.getAdvisors(factory));
  66. }
  67. }
  68. return advisors;
  69. }
  70. //上面代码的关键
  71. @Override
  72. public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
  73. Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
  74. String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
  75. validate(aspectClass);
  76. // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
  77. // so that it will only instantiate once.
  78. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
  79. new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
  80. List<Advisor> advisors = new ArrayList<>();
  81. for (Method method : getAdvisorMethods(aspectClass)) {
  82. // Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
  83. // to getAdvisor(...) to represent the "current position" in the declared methods list.
  84. // However, since Java 7 the "current position" is not valid since the JDK no longer
  85. // returns declared methods in the order in which they are declared in the source code.
  86. // Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
  87. // discovered via reflection in order to support reliable advice ordering across JVM launches.
  88. // Specifically, a value of 0 aligns with the default value used in
  89. // AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
  90. Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
  91. if (advisor != null) {
  92. advisors.add(advisor);
  93. }
  94. }
  95. // If it's a per target aspect, emit the dummy instantiating aspect.
  96. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
  97. Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
  98. advisors.add(0, instantiationAdvisor);
  99. }
  100. // Find introduction fields.
  101. for (Field field : aspectClass.getDeclaredFields()) {
  102. Advisor advisor = getDeclareParentsAdvisor(field);
  103. if (advisor != null) {
  104. advisors.add(advisor);
  105. }
  106. }
  107. return advisors;
  108. }

image.png

  1. 普通增强器的获取

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

  3. 获取DeclareParents注解

    寻找匹配增强器-findAdvisorsThatCanApply

    从所有增强器中寻找这个Bean可以用的上的

    1. protected List<Advisor> findAdvisorsThatCanApply(
    2. List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    3. ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    4. try {
    5. return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    6. }
    7. finally {
    8. ProxyCreationContext.setCurrentProxiedBeanName(null);
    9. }
    10. }
  4. AopUtils#findAdvisorsThatCanApply

  5. AopUtils#canApply

    创建代理

    1. protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
    2. @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    3. if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
    4. AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    5. }
    6. ProxyFactory proxyFactory = new ProxyFactory();
    7. proxyFactory.copyFrom(this);
    8. if (!proxyFactory.isProxyTargetClass()) {
    9. if (shouldProxyTargetClass(beanClass, beanName)) {
    10. proxyFactory.setProxyTargetClass(true);
    11. }
    12. else {
    13. evaluateProxyInterfaces(beanClass, proxyFactory);
    14. }
    15. }
    16. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    17. proxyFactory.addAdvisors(advisors);
    18. proxyFactory.setTargetSource(targetSource);
    19. customizeProxyFactory(proxyFactory);
    20. proxyFactory.setFrozen(this.freezeProxy);
    21. if (advisorsPreFiltered()) {
    22. proxyFactory.setPreFiltered(true);
    23. }
    24. // Use original ClassLoader if bean class not locally loaded in overriding class loader
    25. ClassLoader classLoader = getProxyClassLoader();
    26. if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
    27. classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
    28. }
    29. return proxyFactory.getProxy(classLoader);
    30. }

    Spring委托给ProxyFactory去处理

  6. 获取当前类中的属性

  7. 添加代理接口
  8. 封装Advisor并加入ProxyFactory
  9. 设置要代理的类
  10. Spring提供子类可拓展的方法customizeProxyFactory
  11. 进行获取代理操作

    创建代理

    ```java protected final synchronized AopProxy createAopProxy() {
    1. if (!this.active) {
    2. activate();
    3. }
    4. return getAopProxyFactory().createAopProxy(this);
    }
  1. @Override
  2. public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
  3. if (!NativeDetector.inNativeImage() &&
  4. (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
  5. Class<?> targetClass = config.getTargetClass();
  6. if (targetClass == null) {
  7. throw new AopConfigException("TargetSource cannot determine target class: " +
  8. "Either an interface or a target is required for proxy creation.");
  9. }
  10. if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
  11. return new JdkDynamicAopProxy(config);
  12. }
  13. return new ObjenesisCglibAopProxy(config);
  14. }
  15. else {
  16. return new JdkDynamicAopProxy(config);
  17. }
  18. }
  1. 1. `optimize`:用来控制通过CGLIB创建的代理是否使用激进优化,仅用于CGLIB
  2. 2. `proxyTargetClass`:为trueCGLIB被使用
  3. <a name="A7alH"></a>
  4. ### 获取代理
  5. 1. Spring中应用JDK动态代理
  6. `org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)`
  7. ```java
  8. @Override
  9. public Object getProxy(@Nullable ClassLoader classLoader) {
  10. if (logger.isTraceEnabled()) {
  11. logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
  12. }
  13. return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
  14. }

JdkDynamicAopProxyinvoke函数

  1. @Override
  2. @Nullable
  3. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  4. Object oldProxy = null;
  5. boolean setProxyContext = false;
  6. TargetSource targetSource = this.advised.targetSource;
  7. Object target = null;
  8. try {
  9. if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
  10. // The target does not implement the equals(Object) method itself.
  11. return equals(args[0]);
  12. }
  13. else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
  14. // The target does not implement the hashCode() method itself.
  15. return hashCode();
  16. }
  17. else if (method.getDeclaringClass() == DecoratingProxy.class) {
  18. // There is only getDecoratedClass() declared -> dispatch to proxy config.
  19. return AopProxyUtils.ultimateTargetClass(this.advised);
  20. }
  21. else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
  22. method.getDeclaringClass().isAssignableFrom(Advised.class)) {
  23. // Service invocations on ProxyConfig with the proxy config...
  24. return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
  25. }
  26. Object retVal;
  27. if (this.advised.exposeProxy) {
  28. // Make invocation available if necessary.
  29. oldProxy = AopContext.setCurrentProxy(proxy);
  30. setProxyContext = true;
  31. }
  32. // Get as late as possible to minimize the time we "own" the target,
  33. // in case it comes from a pool.
  34. target = targetSource.getTarget();
  35. Class<?> targetClass = (target != null ? target.getClass() : null);
  36. // Get the interception chain for this method.
  37. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  38. // Check whether we have any advice. If we don't, we can fallback on direct
  39. // reflective invocation of the target, and avoid creating a MethodInvocation.
  40. if (chain.isEmpty()) {
  41. // We can skip creating a MethodInvocation: just invoke the target directly
  42. // Note that the final invoker must be an InvokerInterceptor so we know it does
  43. // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
  44. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
  45. retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
  46. }
  47. else {
  48. // We need to create a method invocation...
  49. MethodInvocation invocation =
  50. new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
  51. // Proceed to the joinpoint through the interceptor chain.
  52. retVal = invocation.proceed();
  53. }
  54. // Massage return value if necessary.
  55. Class<?> returnType = method.getReturnType();
  56. if (retVal != null && retVal == target &&
  57. returnType != Object.class && returnType.isInstance(proxy) &&
  58. !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
  59. // Special case: it returned "this" and the return type of the method
  60. // is type-compatible. Note that we can't help if the target sets
  61. // a reference to itself in another returned object.
  62. retVal = proxy;
  63. }
  64. else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
  65. throw new AopInvocationException(
  66. "Null return value from advice does not match primitive return type for: " + method);
  67. }
  68. return retVal;
  69. }
  70. finally {
  71. if (target != null && !targetSource.isStatic()) {
  72. // Must have come from TargetSource.
  73. targetSource.releaseTarget(target);
  74. }
  75. if (setProxyContext) {
  76. // Restore old proxy.
  77. AopContext.setCurrentProxy(oldProxy);
  78. }
  79. }
  80. }

最主要的工作就是创建了一个拦截器链,并使用ReflectiveMethodInvocation类进行了链的封装,而在ReflectiveMethodInvocation类的proceed方法中实现了拦截器的逐一调用

  1. CGLIB方式