Spring基于注解AOP配置
一、Spring基于注解AOP配置
1. 假设创建一个AccountService需要增强(执行其中每一个方法都会加一个记录日志的方法),则再创建一个日志类实现记录日志方法;
//将该类注入spring容器 @Component("logger") @Aspect//表示当前类是一个切面类 public class Logger { @Pointcut("execution(* com.li.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方法开始记录日志。。。"); } /** * 环绕通知 *问题: * 当我们配置环绕通知之后,切入点方法没有执行,而是通知方法执行 *分析: * 动态代理中的环绕通知 有明确的切入点方法的调用,而我们的没有 *解决: * spring提供一个接口:ProceedingJoinPoint,该接口的proceed()方法相当于明确调用切入点方法 * 该接口可以作为环绕通知的方法参数,在程序执行时,spring框架中为我们提供接口的实现类供我们使用 * sprig的环绕通知 * 可以在代码中手动控制增强方法何时执行的方式 */ //@Around("pt1()") public Object aroundPrintLog(ProceedingJoinPoint pjp){ Object rtValue=null; try { Object[] args=pjp.getArgs(); System.out.println("Logger类中的aroundPrintLog方法开始记录日志。。。前置"); rtValue=pjp.proceed(args);//明确调用有业务层方法(切入点方法) System.out.println("Logger类中的aroundPrintLog方法开始记录日志。。。后置"); return rtValue; } catch (Throwable t) { System.out.println("Logger类中的aroundPrintLog方法开始记录日志。。。异常"); throw new RuntimeException(t); }finally { System.out.println("Logger类中的aroundPrintLog方法开始记录日志。。。最终"); } } }
@Service("accountService") public class AccountServiceImpl implements IAccountService { public void saveAccount() { System.out.println("执行了保存"); } public void updateAccount(int i) { System.out.println("执行了更新"+i); } public int deleteAccount() { System.out.println("执行删除"); return 0; } }
2.配置开启注解
<!--配置spring创建容器时要扫描的包--> <context:component-scan base-package="com.li"></context:component-scan> <!--配置spring开启注解AOP支持--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>