spring_aop

Spring AOP的实现原理

1. 简介

  • Aspect/Advisor切面:拦截器类,其中会定义切点以及通知 (区别:advisor只持有一个Pointcut和一个advice,而aspect可以多个pointcut和多个advice)
  • PointCut切点:具体拦截的某个业务点。
  • Advice通知:切面当中的方法,声明通知方法在目标业务层的执行位置,通知类型如下:
    • 前置通知:@Before 在目标业务方法执行之前执行 (Advice)
    • 后置通知:@After 在目标业务方法执行之后执行 (Advice)
    • 返回通知:@AfterReturning 在目标业务方法返回结果之后执行 (Advice)
    • 异常通知:@AfterThrowing 在目标业务方法抛出异常之后 (Advice)
    • 环绕通知:@Around 功能强大,可代替以上四种通知,还可以控制目标业务方法是否执行以及何时执行 (Advice)

2. JDK动态代理与CGLIB代理

public class JDKProxyFactory implements InvocationHandler {
    private Object target;

    public JDKProxyFactory(Object target) {
        super();
        this.target = target;
    }

    // 创建代理对象
    public Object createProxy() {
        // 1.得到目标对象的类加载器
        ClassLoader classLoader = target.getClass().getClassLoader();
        // 2.得到目标对象的实现接口
        Class<?>[] interfaces = target.getClass().getInterfaces();
        // 3.第三个参数需要一个实现invocationHandler接口的对象
        Object newProxyInstance = Proxy.newProxyInstance(classLoader, interfaces, this);
        return newProxyInstance;
    }


    // 第一个参数:代理对象.一般不使用;第二个参数:需要增强的方法;第三个参数:方法中的参数
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("这是增强方法前......");
        Object invoke = method.invoke(target, args);
        System.out.println("这是增强方法后......");
        return invoke;
    }

    public static void main(String[] args) {
        // 1.创建对象
        FoodServiceImpl foodService = new FoodServiceImpl();
        // 2.创建代理对象
        JDKProxyFactory proxy = new JDKProxyFactory(foodService);
        // 3.调用代理对象的增强方法,得到增强后的对象
        FoodService createProxy = (FoodService) proxy.createProxy();
        createProxy.makeChicken();
    }

}
public class CglibProxyFactory implements MethodInterceptor {
    //得到目标对象
    private Object target;

    //使用构造方法传递目标对象
    public CglibProxyFactory(Object target) {
        super();
        this.target = target;
    }

    //创建代理对象
    public Object createProxy(){
        //1.创建Enhancer
        Enhancer enhancer = new Enhancer();
        //2.传递目标对象的class
        enhancer.setSuperclass(target.getClass());
        //3.设置回调操作
        enhancer.setCallback(this);

        return enhancer.create();
    }


    //参数一:代理对象;参数二:需要增强的方法;参数三:需要增强方法的参数;参数四:需要增强的方法的代理
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("这是增强方法前......");
        Object invoke = methodProxy.invoke(target, args);
        System.out.println("这是增强方法后......");
        return invoke;
    }

    public static void main(String[] args) {
        // 1.创建对象
        FoodServiceImpl foodService = new FoodServiceImpl();
        // 2.创建代理对象
        CglibProxyFactory proxy = new CglibProxyFactory(foodService);
        // 3.调用代理对象的增强方法,得到增强后的对象
        FoodService createProxy = (FoodService) proxy.createProxy();
        createProxy.makeChicken();
    }
}

3. 简单实现

@Aspect   //该注解声明这个类为一个切面类
@Component
class HandlerAspect{
 
    @Autowired
    private lateinit var handlerService: HandlerService

    @Pointcut("execution(* com.winsafe.business.task..*Task.*(..))") // (PointCut)
    public void taskPointCut(){}
  
    @Around("taskPointCut")   //当有函数注释了注解,将会在函数正常返回后在执行我们定义的方法 (Advice)
    public Object doAroundTranceIdLog(ProceedingJoinPoint joinPoint) throws Throwable {
        return handleTranceId(joinPoint); // joinPoint
    }
}

4. 开启AOP的方式

  1. 注解方式:任意Configuration类中添加@EnableAspectJAutoProxy注解,注入 AspectJAutoProxyRegistrar.class
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

}
// Aop开启实际逻辑 调用 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAJAutoProxy.getBoolean("proxyTargetClass")) {
			AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
		}
	}

}
  1. xml方式:主配置文件中添加aop:aspectj-autoproxy/

5. AspectJ 源码实现

  1. 核心实现类 AnnotationAwareAspectJAutoProxyCreator 实现 BeanPostProcessor#postProcessAfterInitialization,在Bean初始化结束会根据需要返回代理对象

  2. 调用核心方法wrapIfNecessary

    1. getAdvicesAndAdvisorsForBean获取当前bean匹配的增强器 (Advisor.class && @Aspect @Pointcut @Before 动态生成Advisor)
      1. findEligibleAdvisors
        1. 找所有增强器 && 生成增强器Advisor
          1. @Aspect注解的Bean
            1. 先获取无@PointCut注解的method;
            2. 从中找到有@Before、@After、@Around等上面的表达式;
            3. 生产advisor含有pointcut和调用org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice(根据不同注解@Before、@After、@Around生成不同类型的Advice)
          2. 直接在容器中所有Advisor.class
        2. 找匹配的增强器,也就是根据@Before,@After等注解上的表达式,与当前bean进行匹配,暴露匹配上的,并根据 @Before、@After、@Around 生成不同的springAdvice
        3. 对匹配的增强器进行扩展和排序,就是按照@Order或者PriorityOrdered的getOrder的数据值进行排序,越小的越靠前。
    2. 创建代理对象 (org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy) -> proxyFactory.getProxy(classLoader)根据不同条件获取Jdk还是cglib AopProxy
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!NativeDetector.inNativeImage() &&
                (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }
    
    1. JdkDynamicAopProxy创建代理 JdkDynamicAopProxy执行逻辑转变为 -> 最终转变为ReflectiveMethodInvocation执行代理逻辑
    2. ObjenesisCglibAopProxy创建代理 由DynamicAdvisedInterceptor执行代理逻辑-> 最终转变为ReflectiveMethodInvocation执行代理逻辑

6. Spring Advisors源码实现

  1. getAdvicesAndAdvisorsForBean获取当前bean匹配的增强器 Advisor.class

7. 参考链接

  1. https://www.cnblogs.com/yb-ken/p/15988854.html

@Transactional实现原理(SpringAOP应用)

1. @EnableTransactionManagement 注解驱动

利用@Import注入TransactionManagementConfigurationSelector.class(通过ConfigurationClassPostProcessor类的postProcessorBeanFactory()解析到BeanDefinitions中)

// 启动Spring事务配置
@Configuration
@EnableTransactionManagement
public class TransactionManagerConfig implements TransactionManagementConfigurer {

    @Resource
    DataSource dataSource;

    @Override
    public TransactionManager annotationDrivenTransactionManager() {
        // 返回一个事务管理器,设置数据源
        return new DataSourceTransactionManager(dataSource);
    }
}

//
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;
}

2. TransactionManagementConfigurationSelector.class 调用selectImports()获取需要注入的BeanName数组

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
	/**
	 * {@inheritDoc}
	 * @return {@link ProxyTransactionManagementConfiguration} or
	 * {@code AspectJTransactionManagementConfiguration} for {@code PROXY} and
	 * {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, respectively
	 */
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
			default:
				return null;
		}
	}
}

1. Spring AutoProxyRegistrar,

注册一个 InfrastructureAdvisorAutoProxyCreator extends AbstractAutoProxyCreator 对象,主要目的是创建代理对象ProxyTransactionManagementConfiguration Spring 事务代理配置类

2. Spring 事务管理配置类 ProxyTransactionManagementConfiguration

创建 BeanFactoryTransactionAttributeSourceAdvisor (由InfrastructureAdvisorAutoProxyCreator创建代理对象),根据JDK动态代理可知Transaction具体执行是有TransactionInterceptor执行

// Spring事务管理配置类 BeanFactoryTransactionAttributeSourceAdvisor  TransactionInterceptor TransactionAttributeSource
       @Configuration
       public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

           @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
           @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
           public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
               BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
               advisor.setTransactionAttributeSource(transactionAttributeSource());
               advisor.setAdvice(transactionInterceptor());
               advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
               return advisor;
           }

           @Bean
           @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
           public TransactionAttributeSource transactionAttributeSource() {
               return new AnnotationTransactionAttributeSource();
           }

           @Bean
           @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
           public TransactionInterceptor transactionInterceptor() {
               TransactionInterceptor interceptor = new TransactionInterceptor();
               interceptor.setTransactionAttributeSource(transactionAttributeSource());
               if (this.txManager != null) {
                   interceptor.setTransactionManager(this.txManager);
               }
               return interceptor;
           }
       }
   
       // 具体执行事务逻辑 invoke() -> TransactionAspectSupport#invokeWithinTransaction
       @SuppressWarnings("serial")
       public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
           @Override
           public Object invoke(final MethodInvocation invocation) throws Throwable {
               // Work out the target class: may be {@code null}.
               // The TransactionAttributeSource should be passed the target class
               // as well as the method, which may be from an interface.
               Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

               // Adapt to TransactionAspectSupport's invokeWithinTransaction...
               return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
                   @Override
                   public Object proceedWithInvocation() throws Throwable {
                       return invocation.proceed();
                   }
               });
           }
       }

       // 事务执行核心方法 invokeWithinTransaction
       protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
   			throws Throwable {

   		// If the transaction attribute is null, the method is non-transactional.
   		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
   		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
   		final String joinpointIdentification = methodIdentification(method, targetClass);

   		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
   			// Standard transaction demarcation with getTransaction and commit/rollback calls.
   			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
   			Object retVal = null;
   			try {
   				// This is an around advice: Invoke the next interceptor in the chain.
   				// This will normally result in a target object being invoked.
   				retVal = invocation.proceedWithInvocation();
   			}
   			catch (Throwable ex) {
   				// target invocation exception
   				completeTransactionAfterThrowing(txInfo, ex);
   				throw ex;
   			}
   			finally {
   				cleanupTransactionInfo(txInfo);
   			}
   			commitTransactionAfterReturning(txInfo);
   			return retVal;
   		}

   		else {
   			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
   			try {
   				Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
   						new TransactionCallback<Object>() {
   							@Override
   							public Object doInTransaction(TransactionStatus status) {
   								TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
   								try {
   									return invocation.proceedWithInvocation();
   								}
   								catch (Throwable ex) {
   									if (txAttr.rollbackOn(ex)) {
   										// A RuntimeException: will lead to a rollback.
   										if (ex instanceof RuntimeException) {
   											throw (RuntimeException) ex;
   										}
   										else {
   											throw new ThrowableHolderException(ex);
   										}
   									}
   									else {
   										// A normal return value: will lead to a commit.
   										return new ThrowableHolder(ex);
   									}
   								}
   								finally {
   									cleanupTransactionInfo(txInfo);
   								}
   							}
   						});

   				// Check result: It might indicate a Throwable to rethrow.
   				if (result instanceof ThrowableHolder) {
   					throw ((ThrowableHolder) result).getThrowable();
   				}
   				else {
   					return result;
   				}
   			}
   			catch (ThrowableHolderException ex) {
   				throw ex.getCause();
   			}
   		}
   	    }

3. AspectJTransactionManagementConfiguration ApectJ 配置类

创建 AnnotationTransactionAspect 父类包含了@Aspect注解 可以由Spring AnnotationAwareAspectJAutoProxyCreator 解析返回代理对象,其父类 包含@Around->TransactionAspectSupport#invokeWithinTransaction()具体实现事务逻辑

public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport implements DisposableBean {
	protected AbstractTransactionAspect(TransactionAttributeSource tas) {
		setTransactionAttributeSource(tas);
	}

	@Override
	public void destroy() {
		clearTransactionManagerCache(); // An aspect is basically a singleton
	}

	@SuppressAjWarnings("adviceDidNotMatch")
	Object around(final Object txObject): transactionalMethodExecution(txObject) {
		MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		try {
			return invokeWithinTransaction(methodSignature.getMethod(), txObject.getClass(), new InvocationCallback() {
				public Object proceedWithInvocation() throws Throwable {
					return proceed(txObject);
				}
			});
		}
		catch (RuntimeException ex) {
			throw ex;
		}
		catch (Error err) {
			throw err;
		}
		catch (Throwable thr) {
			Rethrower.rethrow(thr);
			throw new IllegalStateException("Should never get here", thr);
		}
	}
}

spring aop 中@Around,@Before,@After,@AfterReturning和@AfterThrowing的执行顺序

@Component
@Aspect
@Order(1)
public class AspectJTest1 {
	@Pointcut("execution(public * com.winsafe.spring.aspect.TargetTest.testAop(..))")
	public void performance() {
	}

	@Before("performance()")
	public void before() {
		System.out.println("AspectJTest1-Before");
	}

	@AfterReturning("performance()")
	public void afterReturn() {
		System.out.println("AspectJTest1-AfterReturning");
	}

	@After("performance()")
	public void after() {
		System.out.println("AspectJTest1-After");
	}

	@Around("performance()")
	public Object around(ProceedingJoinPoint joinPoint) {
		Object obj = null;
		try {
			System.out.println("AspectJTest1-AroundFirst");
			obj = joinPoint.proceed();
			System.out.println("AspectJTest1-AroundSecond");
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return obj;
	}

	public void testAop(){
		System.out.println("test aop");
	}
}

@Component
@Aspect
@Order(2)
public class AspectJTest2 {
	@Pointcut("execution(public * com.winsafe.spring.aspect.TargetTest.testAop(..))")
	public void performance() {
	}

	@Before("performance()")
	public void before() {
		System.out.println("AspectJTest2-Before");
	}

	@AfterReturning("performance()")
	public void afterReturn() {
		System.out.println("AspectJTest2-AfterReturning");
	}

	@After("performance()")
	public void after() {
		System.out.println("AspectJTest2-After");
	}

	@Around("performance()")
	public Object around(ProceedingJoinPoint joinPoint) {
		Object obj = null;
		try {
			System.out.println("AspectJTest2-AroundFirst");
			obj = joinPoint.proceed();
			System.out.println("AspectJTest2-AroundSecond");
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return obj;
	}
}

结论:

  1. 同一个Aspect下多个@Around,@Before,@After,@AfterReturning和@AfterThrowing执行顺序
    AspectJTest1-AroundFirst
    AspectJTest1-Before
    test aop
    AspectJTest1-AroundSecond
    AspectJTest1-After
    AspectJTest1-AfterReturning
  2. 不同Aspect下的@Around,@Before,@After,@AfterReturning和@AfterThrowing执行顺序
    AspectJTest1-AroundFirst
    AspectJTest1-Before
    AspectJTest2-AroundFirst
    AspectJTest2-Before
    test aop
    AspectJTest2-AroundSecond
    AspectJTest2-After
    AspectJTest2-AfterReturning
    AspectJTest1-AroundSecond
    AspectJTest1-After
    AspectJTest1-AfterReturning

从源码开始了解

1. ReflectiveMethodInvocation类:

  1. 采用了装饰器模式(Decorator Pattern)和责任链模式(Chain of Responsibility Pattern)两种设计模式
  2. Spring 框架中实现了 AOP 的代理类,用于在目标对象的方法执行前后添加切面逻辑,使用currentInterceptorIndex来控制拦截器链的执行顺序
  3. 属性:interceptorsAndDynamicMethodMatchers:该对象中存储了需要拦截的方法 其中的顺序决定了增强方法执行的顺序!!
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {

	protected final Object proxy;

	protected final Object target;

	protected final Method method;

	protected Object[] arguments;

	private final Class<?> targetClass;

	/**
	 * Lazily initialized map of user-specific attributes for this invocation.
	 */
	private Map<String, Object> userAttributes;

	/**
	 * List of MethodInterceptor and InterceptorAndDynamicMethodMatcher
	 * that need dynamic checks.
	 */
	protected final List<?> interceptorsAndDynamicMethodMatchers; // 该对象中存储了需要拦截的方法 其中的顺序决定了增强方法执行的顺序!!

	/**
	 * Index from 0 of the current interceptor we're invoking.
	 * -1 until we invoke: then the current interceptor.
	 */
	private int currentInterceptorIndex = -1;


	/**
	 * Construct a new ReflectiveMethodInvocation with the given arguments.
	 * @param proxy the proxy object that the invocation was made on
	 * @param target the target object to invoke
	 * @param method the method to invoke
	 * @param arguments the arguments to invoke the method with
	 * @param targetClass the target class, for MethodMatcher invocations
	 * @param interceptorsAndDynamicMethodMatchers interceptors that should be applied,
	 * along with any InterceptorAndDynamicMethodMatchers that need evaluation at runtime.
	 * MethodMatchers included in this struct must already have been found to have matched
	 * as far as was possibly statically. Passing an array might be about 10% faster,
	 * but would complicate the code. And it would work only for static pointcuts.
	 */
	protected ReflectiveMethodInvocation(
			Object proxy, Object target, Method method, Object[] arguments,
			Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

		this.proxy = proxy;
		this.target = target;
		this.targetClass = targetClass;
		this.method = BridgeMethodResolver.findBridgedMethod(method);
		this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
		this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
	}


	@Override
	public final Object getProxy() {
		return this.proxy;
	}

	@Override
	public final Object getThis() {
		return this.target;
	}

	@Override
	public final AccessibleObject getStaticPart() {
		return this.method;
	}

	/**
	 * Return the method invoked on the proxied interface.
	 * May or may not correspond with a method invoked on an underlying
	 * implementation of that interface.
	 */
	@Override
	public final Method getMethod() {
		return this.method;
	}

	@Override
	public final Object[] getArguments() {
		return (this.arguments != null ? this.arguments : new Object[0]);
	}

	@Override
	public void setArguments(Object... arguments) {
		this.arguments = arguments;
	}


	@Override
	public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

	/**
	 * Invoke the joinpoint using reflection.
	 * Subclasses can override this to use custom invocation.
	 * @return the return value of the joinpoint
	 * @throws Throwable if invoking the joinpoint resulted in an exception
	 */
	protected Object invokeJoinpoint() throws Throwable {
		return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
	}
}

2. 探究属性:interceptorsAndDynamicMethodMatchers来源分析

  1. 通过CglibAopProxy的DynamicAdvisedInterceptor的intercept方法new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)CglibMethodInvocation继承自ReflectiveMethodInvocation,传入的chain作为连接器链
    spring_aop_第1张图片
    spring_aop_第2张图片

  2. 开始寻找chain的来源,通过下图,找到getInterceptorsAndDynamicInterceptionAdvice方法最终找到DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice方法

    spring_aop_第3张图片

  3. 发现config.getAdvisors()中的拦截器顺序和属性interceptorsAndDynamicMethodMatchers顺序一致
    spring_aop_第4张图片
    config.getAdvisors()
    spring_aop_第5张图片
    属性interceptorsAndDynamicMethodMatchers

  4. 开始寻找config.getAdvisors()顺序规则:最终发现config中的advisors是在Spring启动时AbstractAutoProxyCreator作为BeanPostProcessor(Bean后置处理器)在Bean初始化后进行创建代理时产生

    spring_aop_第6张图片

  5. 查看buildAdvisors(beanName, specificInterceptors)未进行排序,发现顺序取决于specificInterceptors,继续查找specificInterceptors的来源getAdvicesAndAdvisorsForBean

    spring_aop_第7张图片
    通过findCandidateAdvisors()获取Advisors,再通过sortAdvisors进行排序
    spring_aop_第8张图片

  6. 查看advisors是如何拿到的,其顺序又是什么? BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors->ReflectiveAspectJAdvisorFactory#getAdvisors->ReflectiveAspectJAdvisorFactory#getAdvisorMethods,通过Class反射获取类的所有方法并进行adviceMethodFilter和adviceMehtodComparator排序(排序规则为@Around, @Before, @After, @AfterReturning, @AfterThrowing)
    spring_aop_第9张图片

    spring_aop_第10张图片

  7. 点击里面发现由org.aspectj.util.PartialOrder + AspectJPrecedenceComparator类(通过实现Order接口or@Order注解+declarationOrder) 实现的排序
    spring_aop_第11张图片

    // AspectJPrecedenceComparator类 compare 分析
         @Override
       	public int compare(Advisor o1, Advisor o2) {
       		int advisorPrecedence = this.advisorComparator.compare(o1, o2); // 先用使用Order排序器进行排序,值越小,优先级越高
       		if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(o1, o2)) { // Order顺序值相同,且Advisor在同一个Aspect
       			advisorPrecedence = comparePrecedenceWithinAspect(o1, o2); // 使用declarationOrder的值进行排序(详细分析见下), 这里涉及到关于declarationOrder的来源见下分析
       		}
       		return advisorPrecedence;
       	}
    
         // spirng5.xdeclarationOrder的来源分析: 在步骤6中可以看到advisor的来源(ReflectiveAspectJAdvisorFactory#getAdvisors)
         @Override
     	public List getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
     		// // sprng  5.2.7之前
     		List advisors = new LinkedList();
     		for (Method method : getAdvisorMethods(aspectClass)) { // 重点1:获取所有的advisorMethods通过class 按照 @Around, @Before, @After, @AfterReturning, @AfterThrowing优先排序,注解相同则按照方法名按照自然排序
     			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); // 重点2: advisors.size()就是Advisor的declarationOrder值
     			if (advisor != null) {
     				advisors.add(advisor);
     			}
     		}
             // 3.分析同一个Aspect获取的Method按照 @Around, @Before, @After, @AfterReturning, @AfterThrowing 排序,它们的declarationOrder值依次递增分别是0,1,2,3,4
     		// ...
    
    
             // sprng  5.2.7
             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);
     			}
     	    }
     	}
    
         /**
            AspectJPrecedenceComparator类 comparePrecedenceWithinAspect 分析
            由上述declarationOrder的来源分析 @Around, @Before, @After, @AfterReturning, @AfterThrowing它们的declarationOrder值依次递增分别是0,1,2,3,4
            如果有一个是afterAdvice即 afte, afterreturn,afterthrowing 
            则排序时值越低,优先级越低, 说明排序时afterAdvice大于非afterAdvice(Around,Before) 即所有的 afterAdvice(afterthrowing > afterreturn > after) > 非afterAdvice(Around,Before)
            否则 值越低优先级越高,Around > Before  
            结合上述得出Afterthrowing > Afterreturn > After > Around > Before (afterAdvice优先级最高且afterAdvice是值越低优先级越高,反之非afterAdvice值越低优先级越高)
          */
       	private int comparePrecedenceWithinAspect(Advisor advisor1, Advisor advisor2) {
       		boolean oneOrOtherIsAfterAdvice =
       				(AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2));
       		int adviceDeclarationOrderDelta = getAspectDeclarationOrder(advisor1) - getAspectDeclarationOrder(advisor2);
    
       		if (oneOrOtherIsAfterAdvice) {
       			// the advice declared last has higher precedence
       			if (adviceDeclarationOrderDelta < 0) {
       				// advice1 was declared before advice2
       				// so advice1 has lower precedence
       				return LOWER_PRECEDENCE;
       			}
       			else if (adviceDeclarationOrderDelta == 0) {
       				return SAME_PRECEDENCE;
       			}
       			else {
       				return HIGHER_PRECEDENCE;
       			}
       		}
       		else {
       			// the advice declared first has higher precedence
       			if (adviceDeclarationOrderDelta < 0) {
       				// advice1 was declared before advice2
       				// so advice1 has higher precedence
       				return HIGHER_PRECEDENCE;
       			}
       			else if (adviceDeclarationOrderDelta == 0) {
       				return SAME_PRECEDENCE;
       			}
       			else {
       				return LOWER_PRECEDENCE;
       			}
       		}
       	}
    

    spring_aop_第12张图片

  8. 总结执行链顺序

    • spring 3.2 x前: 采用源码中方法书写的顺序+Advisor的Order
    • spring 5.2.7前:采用declarationOrder + Advisor的Order @AfterThrowing->@AfterReturn->@After->@Around->@before
    • spring 5.2.7后:采用d eclarationOrder=0 + Advisor的Order@Around->@Before->@After->@AfterReturning->@AfterThrowing

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-abvOMySj-1689236128862)(…/spring/assets/aop.drawio)]

你可能感兴趣的:(spring,java,后端)