Spring注解驱动开发(三)--AOP使用
一、前言
本篇主要讲解Spring AOP的使用。如需查看实现原理,移步《Spring源码解析(三)--AOP实现原理》。
二、maven包引用
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.16.RELEASE</version> </dependency>
三、开启AOP
Spring默认是不开启AOP功能,需要通过注解@EnableAspectJAutoProxy。
/** * 开启Spring AOP */ @EnableAspectJAutoProxy public class AopConfig { @Bean public Calculator calculator() { return new Calculator(); } @Bean public LogAop logAop() { return new LogAop(); } }
四、定义目标对象
目标对象的定义和其它对象没有任何区别,所以Spring AOP对业务代码是无任何侵入性
public class Calculator { public int div(int num1, int num2) { return num1 / num2; } }
五、定义切面
- @Aspect 告诉Spring容器这是一个切面
- @Pointcut 定义需要拦截的目标方法
- @Before 目标方法执行前调用
- @After 目标方法执行后调用
- @AfterReturning 目标方法执行返回后调用
- @AfterThrowing 目标方法抛出异常后调用
- @Around 用于@Before和@After,可以手动控制方法调用
@Aspect public class LogAop { /** * 第一个*代表任意返回类型 * 第二个*代表任意方法 * ..代表任意参数 * 所以整个表达式代表拦截indi.zqc.spring.bean.Calculator类的所有方法 */ @Pointcut("execution(* indi.zqc.spring.bean.Calculator.*(..))") public void pointcut() { } @Before(value = "pointcut()") public void before(JoinPoint joinPoint) { System.out.println("LogAop --- before --- " + joinPoint.getSignature().getDeclaringTypeName()); } @After(value = "pointcut()") public void after(JoinPoint joinPoint) { System.out.println("LogAop --- after --- " + joinPoint.getSignature().getDeclaringTypeName()); } @AfterReturning(value = "pointcut()", returning = "result") public void afterReturning(JoinPoint joinPoint, Object result) { System.out.println("LogAop --- afterReturning --- " + result); } @AfterThrowing(value = "pointcut()", throwing = "exception") public void afterThrowing(JoinPoint joinPoint, Exception exception) { System.out.println("LogAop --- afterThrowing --- " + exception); } @Around(value = "pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("LogAop --- around --- before"); // 调用目标方法 Object proceed = joinPoint.proceed(); System.out.println("LogAop --- around --- after"); return proceed; } }
六、将目标对象和切面注入到Spring容器中
必须把切面和目标对象都注入到Spring容器中,才能生效
七、调用
public class AopConfigTest { @Test public void test() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class); Calculator calculator = applicationContext.getBean(Calculator.class); calculator.div(1, 1); } }