1.注解配置bean.xml
除了添加context标签,还有aop:aspectj-autoproxy标签
<!-- 配置spring创建容器时要扫描的包-->
<context:component-scan base-package="com.jh"></context:component-scan>
<!-- 配置spring开启注解AOP的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2. 在各层添加注解
注解模式比较简单
service:实现类只添加了注解,其余与XML配置一样
/**
* 账户的业务层实现类
* */
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
@Override
public void saveAccount() {
System.out.println("执行了保存");
}
}
service:接口无变化
utils:Logger通知类添加了注解( 仿照xml配置步骤注解 )
- @Component(“logger”) bean对象的获取
- @Aspect 表示当前类是一个切面类
- @Pointcut(“execution(* com.jh.service.impl..(…))”) 在pt1()方法上面注解,之后的通知类型调用切入点
- @Before(“pt1()”) @AfterReturning等
package com.jh.utils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 用于记录日志的工具类,它里面提供了公共的代码
* */
@Component("logger")
@Aspect//表示当前类是一个切面类
public class Logger {
@Pointcut("execution(* com.jh.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 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) {//必须Throwable
System.out.println("Logger类中的aroundPrintLog方法开始记录日志了。。。异常");
throw new RuntimeException(t);
} finally {
System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。最终");
}
}
/**环绕通知结果:
* Logger类中的aroundPrintLog方法开始记录日志了。。。前置
* 执行了保存
* Logger类中的aroundPrintLog方法开始记录日志了。。。后置
* Logger类中的aroundPringLog方法开始记录日志了。。。最终
* */
}
测试类无变化
package com.jh.test;
import com.jh.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**测试AOP的配置*/
public class AOPTest {
public static void main(String[] args) {
//1.获取容器
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
//2.根据id获取service bean对象
IAccountService as=(IAccountService)ac.getBean("accountService");
//3.执行方法
as.saveAccount();
/**结果:(一般只执行3个,后置通知和异常通知不能同时存在)
前置通知Logger类中的beforePrintLog方法开始记录日志了。。。
执行了保存
最终通知Logger类中的afterPrintLog方法开始记录日志了。。。
后置通知Logger类中的afterReturningPrintLog方法开始记录日志了。。。
* */
}
}