在系统运行时动态添加代码的方式称为面向切面编程(AOP)
AOP(Aspect-Oriented Programming)能解决啥问题?
- 记录日志
- 监控方法运行时间 (监控性能)
- 权限控制
- 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
- 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务
下面是SpringBoot配置AOP的一个例子
引入spring-boot-starter-aop依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
|
在service包下创建UserService类
package com.biu.chapter04_aop.service;
import org.springframework.stereotype.Service;
@Service public class UserService { public String getUserById(Integer id) { System.out.println("get……"); return "user"; }
public void deleteUserById(Integer id) { System.out.println("delete……"); } }
|
创建切面
package com.biu.chapter04_aop;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component;
@Component
@Aspect public class LogAspect { @Pointcut("execution(* com.biu.chapter04_aop.service.*.*(..))") public void pc1() { }
@Before(value = "pc1()") public void before(JoinPoint joinPoint) { String name = joinPoint.getSignature().getName(); System.out.println("方法执行开始,name = " + name); }
@After(value = "pc1()") public void after(JoinPoint joinPoint) { String name = joinPoint.getSignature().getName(); System.out.println("方法执行结束,name = " + name); }
@AfterReturning(value = "pc1()", returning = "result") public void afterReturning(JoinPoint joinPoint, Object result) { String name = joinPoint.getSignature().getName(); System.out.println(name + "方法返回值为:" + result); }
@AfterThrowing(value = "pc1()", throwing = "e") public void afterThrowing(JoinPoint joinPoint, Exception e) { String name = joinPoint.getSignature().getName(); System.out.println(name + "方法抛异常了,异常是:" + e.getMessage()); }
@Around("pc1()") public Object around(ProceedingJoinPoint pjp) throws Throwable { return pjp.proceed(); } }
|
调用UserService中的两个方法
package com.biu.chapter04_aop;
import com.biu.chapter04_aop.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
@RestController public class UserController { @Autowired UserService userService;
@GetMapping("getUserById") public String getUserById(Integer id) { return userService.getUserById(id); }
@GetMapping("deleteUserById") public void deleteUserById(Integer id) { userService.deleteUserById(id); } }
|
output
方法执行开始,name = getUserById get…… getUserById方法返回值为:user 方法执行结束,name = getUserById 方法执行开始,name = deleteUserById delete…… deleteUserById方法返回值为:null 方法执行结束,name = deleteUserById
|