AOP(术语)
-
连接点
类里面哪些方法可以增强,这些点被称为连接点 -
切入点
实际被真正增强的方法 -
通知(增强)
实际增强的逻辑部分称为通知(增强)
通知(增强)有多种类型
- 前置通知–@Before
- 后置通知–@After
- 环绕通知–@Around
- 异常通知–@AfterThrowing
- 最终通知–@AfterReturning
切面(是动作)–
把通知(增强)应用到切入点过程
引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
实现步骤
- 新建一个注解类,用于后面做切入点
java">@Retention(value = RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Authorization {
}
- 建一个切面类
@Aspect
@***ponent
public class AuthAspect {
/**
* 定义了一个切点
* 这里的路径填自定义注解的全路径
*/
@Pointcut("@annotation(***.zhuyh.studytest.spring5.aop.Authorization)")
public void authornizeCut() {
}
@Before("authornizeCut()")
public void cutProcess(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("AOP开始拦截, 当前拦截的方法名: " + method.getName());
}
@After("authornizeCut()")
public void after(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("AOP执行的方法 :" + method.getName() + " 执行完了");
}
@Around("authornizeCut()")
public Object testCutAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("AOP拦截开始进入环绕通知.......");
Object proceed = joinPoint.proceed();
System.out.println("准备退出环绕......");
return proceed;
}
/**
* returning属性指定连接点方法返回的结果放置在result变量中
*
* @param joinPoint 连接点
* @param result 返回结果
*/
@AfterReturning(value = "authornizeCut()", returning = "result")
public void afterReturn(JoinPoint joinPoint, Object result) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("AOP拦截的方法执行成功, 进入返回通知拦截, 方法名为: " + method.getName() + ", 返回结果为: " + result.toString());
}
@AfterThrowing(value = "authornizeCut()", throwing = "e")
public void afterThrow(JoinPoint joinPoint, Exception e) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("AOP进入方法异常拦截, 方法名为: " + method.getName() + ", 异常信息为: " + e.getMessage());
}
}
- 来一个Controller作为请求被代理的对象
@RestController
@RequestMapping("/***pany")
public class ***panyController {
@GetMapping("/aopTest")
@Authorization
public Object aopTest(@RequestParam String name){
//远程调用
System.out.println("执行接口name:" + name);
// int n = 1/0;
return "成功了-----" + name;
}
}
- 启动类启动项目
@SpringBootApplication
public class StudyTestApplication {
public static void main(String[] args) {
SpringApplication.run(StudyTestApplication.class, args);
}
}
测试验证
- 浏览器或者api调用工具调接口
- 控制台打印
AOP拦截开始进入环绕通知.......
AOP开始拦截, 当前拦截的方法名: aopTest
执行接口name:zhuyh
AOP拦截的方法执行成功, 进入返回通知拦截, 方法名为: aopTest, 返回结果为: 成功了-----zhuyh
AOP执行的方法 :aopTest 执行完了
准备退出环绕......
- Controller加入一个异常 int i=1/0; 重启项目再次调用
异常通知打印了 / by zero
AOP拦截开始进入环绕通知.......
AOP开始拦截, 当前拦截的方法名: aopTest
执行接口name:zhuyh
AOP进入方法异常拦截, 方法名为: aopTest, 异常信息为: / by zero
AOP执行的方法 :aopTest 执行完了
2024-01-24 16:50:10.477 ERROR 4888 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ArithmeticException: / by zero] with root cause
java.lang.ArithmeticException: / by zero
at ***.zhuyh.studytest.spring5.aop.***panyController.aopTest(***panyController.java:16) ~[classes/:na]
感谢阅读
谢谢您的陪伴! 如果您有任何问题、建议或想要了解的特定主题,请随时在评论中告诉我们。期待与您共同探索java,共同提升我们的Java开发技能!