Article Directory
1. Notes Configuration bean.xml
In addition to adding context tags, as well as aop: aspectj-autoproxy tag
<!-- 配置spring创建容器时要扫描的包-->
<context:component-scan base-package="com.jh"></context:component-scan>
<!-- 配置spring开启注解AOP的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2. Add annotations in layers
Annotation mode is relatively simple
service: implementation class only add annotations, XML configuration like the rest
/**
* 账户的业务层实现类
* */
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
@Override
public void saveAccount() {
System.out.println("执行了保存");
}
}
service: Interface No change
utils: Logger notification class adds annotations (notes modeled xml configuration step)
- @Component ( "logger") acquired bean object
- @Aspect represents the current class is a class section
- @Pointcut ( "Execution (* com.jh.service.impl. . (...))") in pt1 () method of the above comments, calling the entry point after the notification type
- @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方法开始记录日志了。。。最终
* */
}
No change test class
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方法开始记录日志了。。。
* */
}
}