采用AOP的面向切面编程方式,对学生信息管理系统中的新增学生信息、更新学生信息和删除学生信息3个方法实现日志记录业务。
1. 创建项目
Idea创建Java项目,项目名称为:case08-spring-aop。
2. 导入spring相关jar包
case08-spring-aop项目下创建lib目录,在lib目录下导入Jar包:
-
核心包
spring-core-5.3.25.jar
spring-beans-5.3.25.jar
spring-context-5.3.25.jar
spring-expression-5.3.25.jar
-
AOP包
spring-aop-5.3.25.jar
aspectjweaver-1.9.7.jar
-
测试包
junit-4.6.jar
-
依赖包
commons-logging-1.2.jar
3. 创建Spring配置文件
src目录下创建applicationContext.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 https://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="com.wfit"/>
<!--开启aspectj-->
<aop:aspectj-autoproxy/>
</beans>
4. 创建StudentDao类
src目录下创建com.wfit.dao包,此包目录下创建StudentDao.java类。
@Repository
public class StudentDao {
public void addStudent(){
System.out.println("新增成功!");
}
public void delStudent(){
System.out.println("删除成功!");
}
public void getStudent(){
System.out.println("查询成功!");
}
}
5. 创建StudentService接口
src目录下创建com.wfit.service包,此包目录下创建StudentService.java接口。
public interface StudentService {
/**
* 新增
*/
public void addStudent();
/**
* 删除
*/
public void delStudent();
/**
* 查询
*/
public void getStudent();
}
6. 创建StudentServiceImpl类
src目录下创建com.wfit.service.impl包,此包目录下创建StudentServiceImpl.java类实现StudentService接口。
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
StudentDao studentDao;
@Override
public void addStudent() {
studentDao.addStudent();
}
@Override
public void delStudent() {
int i = 1/0;
studentDao.delStudent();
}
@Override
public void getStudent() {
studentDao.getStudent();
}
}
7. 创建MyAspect类
src目录下创建com.wfit.config包,此包目录下创建MyAspect.java类。
@Component //注解一个组件对象
@Aspect //声明一个切面
public class MyAspect {
/**
* 切入点
*/
@Pointcut("execution(* com.wfit.service.StudentService.*(..))")
private void myPointCut(){
}
/**
* 前置通知
*/
@Before("myPointCut()")
public void before(JoinPoint jp){
System.out.println("前置通知,日志:" + jp.getSignature().getName() + "开始执行!");
}
/**
* 后置返回通知
*/
@AfterReturning("myPointCut()")
public void afterReturning(JoinPoint jp){
System.out.println("后置返回通知,日志:" + jp.getSignature().getName() + "执行成功!");
}
/**
* 环绕通知
*/
@Around("myPointCut()")
public void around(ProceedingJoinPoint pjp) throws Throwable {
//环绕开始
System.out.println("around开始...");
//执行当前目标方法
pjp.proceed();
//环绕结束
System.out.println("around结束...");
}
/**
* 异常通知
*/
@AfterThrowing(value = "myPointCut()",throwing = "e")
public void afterThrowing(JoinPoint jp,Throwable e){
String msg = "异常通知,日志:" + jp.getSignature().getName() + "执行异常,原因是:" + e;
System.out.println(msg);
}
/**
* 后置(最终)通知
*/
@After("myPointCut()")
public void after(JoinPoint jp){
System.out.println("后置(最终)通知,日志:" + jp.getSignature().getName() + "执行结束!");
}
}
8. 编写测试类
src目录下创建com.wfit.test包,此包目录下创建TestStudent.java类。
public class TestStudent {
private StudentService studentService;
@Before
public void init(){
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
studentService = applicationContext.getBean("studentServiceImpl", StudentService.class);
}
@Test
public void testAdd(){
studentService.addStudent();
}
@Test
public void testDel(){
studentService.delStudent();
}
@Test
public void testGet(){
studentService.getStudent();
}
}
9. 执行结果
-
执行testAddStudent结果
-
执行testDelStudent结果