在使用XML配置过后,修改一下配置,将大部分配置都转换为相关注解即可。
基于XML的配置
1、将bean.xml文件部分配置转换为注解
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置要管理的包 -->
<context:component-scan base-package="org.example"></context:component-scan>
<!-- 配置spring开启注解AOP支持 ,同时也可以使用@EnableAspectJAutoProxy注解-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
2、一些相关注解
@Aspect //声明当前类是一个切面类
// 指定切入点表达式
@Pointcut(“execution(* org.example.service.impl..(…))”)
private void pt1() {}
各种通知注解见如下使用方法
logger.java
@Component("logger")
@Aspect //声明当前类是一个切面类
public class Logger {
// 指定切入点表达式
@Pointcut("execution(* org.example.service.impl.*.*(..))")
private void pt1() {
}
// @Before("pt1()")
private void BeforePrintLogger() {
System.out.println("执行了前置通知方法");
}
// @AfterReturning("pt1()")
private void AfterReturningPrintLogger() {
System.out.println("执行了后置通知方法");
}
// @AfterThrowing("pt1()")
private void ExThrowPrintLogger() {
System.out.println("执行了异常通知方法");
}
// @After("pt1()")
private void AfterPrintLogger() {
System.out.println("执行了最终通知方法");
}
/**
* 环绕通知
* 问题:
* 当我们配置了环绕通知之后,切入点方法没有执行,而通知方法执行了。
* 分析:
* 通过对比动态代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法调用,而我们的代码中没有。
* 解决:
* Spring框架为我们提供了一个接口:ProceedingJoinPoint。该接口有一个方法proceed(),此方法就相当于明确调用切入点方法。
* 该接口可以作为环绕通知的方法参数,在程序执行时,spring框架会为我们提供该接口的实现类供我们使用。
*
* spring中的环绕通知:
* 它是spring框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式。
*/
@Around("pt1()")
private Object AroundPrintLogger(ProceedingJoinPoint prj) {
Object rtValue = null;
try {
Object[] args = prj.getArgs(); // 得到方法执行所需的参数
System.out.println("前置通知");
rtValue = prj.proceed(args); // 明确使用业务层方法(切入点方法)
System.out.println("后置通知");
return rtValue;
} catch (Throwable t) {
System.out.println("异常通知");
throw new RuntimeException(t);
} finally {
System.out.println("最终通知");
}
}
}
别忘了同时注入accountService文件即可
最后直接在测试文件测试运行即可