11.2-动态代理基于注解配置aop-spring008

mac2026-08-08  4

1.环境搭建

2.导入配置文件context的名称空间

<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置spring创建容器时要扫描的包--> <context:component-scan base-package="com"></context:component-scan> <!-- 配置spring开启注解AOP的支持 没有此句,不能注解aop--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>

3.账户功能实现

** * 账户的业务层实现类 */ @Service("accountService") //交给spring public class AccountServiceImpl implements IAccountService{ @Override public void saveAccount() { System.out.println("执行了保存"); } @Override public void updateAccount(int i) { System.out.println("执行了更新"+i); } @Override public int deleteAccount() { System.out.println("执行了删除"); return 0; } }

4.通知类 中介类

/** * 用于记录日志的工具类,它里面提供了公共的代码 */ @Component("logger") @Aspect//表示当前类是一个切面类 public class Logger { //切入点表达式 @Pointcut("execution(* com.itheima.service.impl.*.*(..))") private void pt1(){} /** * 前置通知 */ // @Before("pt1()") //前置通知 public void beforePrintLog(){ System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志了。。。"); } /** * 后置通知 */ // @AfterReturning("pt1()") //后置通知 public void afterReturningPrintLog(){ System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志了。。。"); } /** * 异常通知 */ // @AfterThrowing("pt1()") //异常通知 public void afterThrowingPrintLog(){ System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志了。。。"); } /** * 最终通知 */ // @After("pt1()") //最终通知 public void afterPrintLog(){ System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志了。。。"); } @Around("pt1()") public Object aroundPringLog(ProceedingJoinPoint pjp){ Object rtValue = null; try{ Object[] args = pjp.getArgs();//得到方法执行所需的参数 System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。前置"); rtValue = pjp.proceed(args);//明确调用业务层方法(切入点方法) System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。后置"); return rtValue; }catch (Throwable t){ System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。异常"); throw new RuntimeException(t); }finally { System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。最终"); } } }

当使用 @After(“pt1()”)@AfterThrowing(“pt1()”)@Before(“pt1()”)@AfterReturning(“pt1()”) 4个时,执行结果为

前置通知Logger类中的beforePrintLog方法开始记录日志了。。。 执行了保存 最终通知Logger类中的afterPrintLog方法开始记录日志了。。。 后置通知Logger类中的afterReturningPrintLog方法开始记录日志了。。。

显然有顺序调用的问题

当使用环绕通知 @Around(“pt1()”) public Object aroundPringLog(ProceedingJoinPoint pjp){ 时,是没有顺序调用的问题的,环绕通知的调用顺序依靠为方法内顺序执行 只要方法不写反,不会有调用顺序的问题

5.不使用XML @EnableAspectJAutoProxy

使用配置类

@Configuration @ComponentScan(basePackages="com.itheima") @EnableAspectJAutoProxy public class SpringConfiguration { }
最新回复(0)