1.AOP(Aspect Oriented Programming)相关术语
①增强处理(Advice)
- 前置增强
- 后置增强
- 环绕增强
- 异常抛出增强
- 最终增强等类型
②切入点(Pointcut)
- 何时执行切面类代码
③连接点(Joint Point)
④切面(Aspect)
- 非核心代码,如日志,异常等,单独取出作为切面类
⑤目标对象(Target Object)
- Service服务层
⑥AOP代理(AOP Proxy)
⑦织入(Weaving)
- 即往目标对象中注入切面类的说法
2.关于execution表达式的规定,来源于Spring官网
The following examples show some common pointcut expressions:
下面的示例显示了一些常见的切入点表达式:
The execution of any public method:
执行任何公共方法:
execution(public * *(..))
The execution of any method with a name that begins with set:
执行名称以set开头的任何方法:
execution(* set*(..))
The execution of any method defined by the AccountService interface:
AccountService接口定义的任何方法的执行:
execution(* com.xyz.service.AccountService.*(..))
The execution of any method defined in the service package:
执行服务包中定义的任何方法:
execution(* com.xyz.service.*.*(..))
The execution of any method defined in the service package or one of its sub-packages:
执行服务包或其子包之一中定义的任何方法:
execution(* com.xyz.service..*.*(..))
3.SpringBoot实现AOP
①在SpringBoot工程基础上添加Aop依赖
<!--AOP面向切面编程-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
②创建Service类,即目标对象
IUserService接口类
public interface IUserService {
/**
* 用于测试前置通知,后置通知及环绕通知
*/
void aopTest();
/**
* 用户测试后置通知返回值
* @return
*/
String aopReturning();
/**
* 用于测试后置通知异常返回
* @throws Exception
*/
void aopExceptionTest() throws Exception;
}
UserServiceImpl实现类
@Override
public void aopTest(){
System.out.println("用来测试AOP功能");
}
@Override
public String aopReturning() {
return "返回值";
}
@Override
public void aopExceptionTest() throws Exception {
throw new Exception("AOP后置异常测试");
}
③创建AOP类
@Component
@Aspect
public class MyAspect {
/**
* 切点前置通知
*/
@Before("execution(* com.cx.springboot.service..*.*(..))")
public void before() {
System.out.println("前置通知");
}
/**
* 切点后置通知
*/
@After("execution(* com.cx.springboot.service..*.*(..))")
public void after() {
System.out.println("后置通知");
}
/**
* 切点环绕通知
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("execution(* com.cx.springboot.service..*.*(..))")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("====环绕开始====");
// 切面中获取到调用方法名
String methodName = proceedingJoinPoint.getSignature().getName();
// 切面中获取到调用方法的参数
Object[] args = proceedingJoinPoint.getArgs();
// 执行调用方法
Object result = proceedingJoinPoint.proceed();
System.out.println("方法名:" + methodName);
System.out.println("方法参数:" + args.toString());
System.out.println("====环绕结束====");
return result;
}
/**
* 切点后置通知返回值
*
* @param joinPoint
* @param result
*/
@AfterReturning(pointcut = "execution(* com.cx.springboot.service..*.*(..))", returning = "result")
public void afterReturning(JoinPoint joinPoint, String result) {
System.out.println("后置通知返回值:" + result);
}
/**
* 切点后置通知异常返回
*
* @param joinPoint
* @param exception
*/
@AfterThrowing(pointcut = "execution(* com.cx.springboot.service..*.*(..))",throwing = "exception")
public void afterThrowing(JoinPoint joinPoint, Exception exception) {
System.out.println("后置异常返回:" + exception.getMessage());
}
}
④创建测试AOP类
@SpringBootTest
public class UserTest {
@Autowired
IUserService userService;
@Test
public void test01(){
userService.aopTest();
}
@Test
public void test02(){
userService.aopReturning();
}
@Test
public void test03(){
try {
userService.aopExceptionTest();
} catch (Exception e) {
System.out.println("异常结束");
}
}
⑤测试结果
- 前置通知
- 后置通知
- 环绕通知
- 后置通知返回值
- 后置通知异常返回