【Spring】Spring之AOP的执行顺序

切面中不同注解的切入点的执行顺序为:前置处理、后置处理、返回处理/异常处理,这个顺序是很好理解的。但是如果定义了多个切面类,并且里面有相同的处理环节时,如果不手动指定处理顺序,那么他们将按照字母顺序执行,如果指定了执行顺序,那么将按照指定的顺序执行。下面就来说明一下使用AOP的两种方式中是如何指定相同处理环节的执行顺序的。还是以处理下面的service层代码为例:

package cn.jingpengchong.calculator.service;

import org.springframework.stereotype.Service;

@Service
public class CalculatorService implements ICalculatorService {

	public int div(int a, int b) {
		return a/b;
	}
}

注解方式指定执行顺序

这种方式需要在切面类前面加上@Order()注解,括号里面的参数值越小,越先执行。

1、新建模块“cn.jingpengchong.aspect”,然后新建“ArgsAspect.java”和“MethodAspect.java”文件:
package cn.jingpengchong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

//指定第二个执行
@Order(2)
@Aspect
@Component
public class ArgsAspect {
	
	@Before("execution(public int cn.jingpengchong.calculator.service.CalculatorService.*(..))")
	public void before(JoinPoint jp) {
		Object[] args = jp.getArgs();
		Signature signature = jp.getSignature();
		String name = signature.getName();
		System.out.println("日志:The " + name + " method args:[" + args[0] + "," + args[1] + "]");
	}
}
package cn.jingpengchong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

//指定第一个执行
@Order(1)
@Aspect
@Component
public class MethodAspect {
	
	@Before("execution(public int cn.jingpengchong.calculator.service.CalculatorService.*(..))")
	public void before(JoinPoint jp) {
		Signature signature = jp.getSignature();
		String name = signature.getName();
		System.out.println("日志:The " + name + " method begins");
	}
}
2、spring的xml配置文件中指定自动代理:
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
3、编写测试类:
package cn.jingpengchong.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.jingpengchong.calculator.service.ICalculatorService;

public class Test {
	
	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
		System.out.println(calculatorService.div(6, 2));
		applicationContext.close();
	}
}

运行结果如下:
在这里插入图片描述

xml配置方式指定执行顺序

这种方式需要在<aop:aspect>标签加上order属性,order属性的属性值越小,越先执行。

1、新建模块“cn.jingpengchong.aspect”,然后新建“ArgsAspect.java”和“MethodAspect.java”文件:
package cn.jingpengchong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

public class ArgsAspect {
	public void before(JoinPoint jp) {
		Object[] args = jp.getArgs();
		Signature signature = jp.getSignature();
		String name = signature.getName();
		System.out.println("日志:The " + name + " method args:[" + args[0] + "," + args[1] + "]");
	}
}
package cn.jingpengchong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

public class MethodAspect {
	public void before(JoinPoint jp) {
		Signature signature = jp.getSignature();
		String name = signature.getName();
		System.out.println("日志:The " + name + " method begins");
	}
}
2、spring的xml配置文件中配置切面:
<bean id = "argsAspect" class = "cn.jingpengchong.aspect.ArgsAspect"/>
<bean id = "methodAspect" class = "cn.jingpengchong.aspect.MethodAspect"/>

<aop:config>
	<aop:pointcut expression="execution(public int cn.jingpengchong.calculator.service.CalculatorService.*(..))" id="pointCut"/>
	<aop:aspect ref="argsAspect" order="2">
		<aop:before method="before" pointcut-ref="pointCut"/>
	</aop:aspect>
	<aop:aspect ref="methodAspect" order="1">
		<aop:before method="before" pointcut-ref="pointCut"/>
	</aop:aspect>
</aop:config>
3、编写测试类:
package cn.jingpengchong.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.jingpengchong.calculator.service.ICalculatorService;

public class Test {
	
	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
		System.out.println(calculatorService.div(6, 2));
		applicationContext.close();
	}
}

运行结果如下:
在这里插入图片描述

发布了128 篇原创文章 · 获赞 17 · 访问量 2734

猜你喜欢

转载自blog.csdn.net/qq_43705275/article/details/104181197