网站开发语言php,网站制作多少钱?,html设计个人网页,asp网站怎么打开一、基本介绍
1#xff0c;什么是 AOP
#xff08;1#xff09;AOP 为 Aspect Oriented Programming 的缩写#xff0c;意为#xff1a;面向切面编程#xff0c;通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
#xff08;2#xff09;利用 AOP…一、基本介绍
1什么是 AOP
1AOP 为 Aspect Oriented Programming 的缩写意为面向切面编程通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
2利用 AOP 可以对业务逻辑的各个部分进行隔离从而使得业务逻辑各部分之间的耦合度降低提高程序的可重用性同时提高了开发的效率。
一个 AOP 的使用场景 假设一个已经上线的系统运行出现问题有时运行得很慢。为了检测出是哪个环节出现了问题就需要监控每一个方法的执行时间再根据执行时间进行分析判断。 由于整个系统里的方法数量十分庞大如果一个个方法去修改工作量将会十分巨大而且这些监控方法在分析完毕后还需要移除掉所以这种方式并不合适。 如果能够在系统运行过程中动态添加代码就能很好地解决这个需求。这种在系统运行时动态添加代码的方式称为面向切面编程AOP 2AOP 相关概念介绍
Joinpoint连接点类里面可以被增强的方法即为连接点。例如想要修改哪个方法的功能那么该方法就是一个链接点。Target目标对象要增强的类成为 Target。Pointcut切入点对 Jointpoint 进行拦截的定义即为切入点。例如拦截所有以 insert 开始的方法这个定义即为切入点。Advice通知拦截到 Jointpoint 之后要做的事情就是通知。通知分为前置通知、后置通知、异常通知、最终通知和环绕通知。例如前面说到的打印日志监控就是通知。Aspect切面即 Pointcut 和 Advice 的结合。 3安装配置 Spring Boot 在 Spring 的基础上对 AOP 的配置提供了自动化配置解决方案我们只需要修改 pom.xml 文件添加 spring-boot-starter-aop 依赖即可。
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId/dependency
二、使用样例
1创建 Service
首先创建一个 UserService假设在 com.hmblogs.backend.service内容如下
package com.hmblogs.backend.service;import org.springframework.stereotype.Service;Service
public class UserService {public String getUserById(Integer id) {System.out.println(getUserById( id )...);// 等待2秒try {Thread.sleep(2000);}catch(InterruptedException e) {e.printStackTrace();}return hangge;}
}2创建切面
接着定义一个切面类代码如下
注解说明 1Aspect 注解表明这是一个切面类。 2Pointcut 注解表明这是一个切入点。
execution 中的第一个 * 表示方法返回任意值第二个 * 表示 service 包下的任意类第三个 * 表示类中的任意方法括号中的两个点表示方法参数任意即这里描述的切入点为 service 包下所有类中的所有方法。
3Before 注解表示这是一个前置通知该方法在目标方法之前执行。
通过 JoinPoint 参数可以获取目标方法的方法名、修饰符等信息。
4After 注解表示这是一个后置通知该方法在目标执行之后执行。 5AfterReturning 注解表示这是一个返回通知在该方法中可以获取目标方法的返回值。
returning 参数是指返回值的变量名对应方法的参数。注意本样例在方法参数中定义 result 的类型为 Object表示目标方法的返回值可以是任意类型。若 result 参数的类型为 Long则该方法只能处理目标方法返回值为 Long 的情况。
6AfterThrowing 注解表示这是一个异常通知即当目标方法发生异常该方法会被调用。
样例中设置的异常类型为 Exception 表示所有的异常都会进入该方法中执行。若异常类型为 ArithmeticException 则表示只有目标方法抛出的 ArithmeticException 异常才会进入该方法的处理。
7 Around 注解表示这是一个环绕通知。环绕通知是所有通知里功能最为强大的通知可以实现前置通知、后置通知、异常通知以及返回通知的功能。
目标方法进入环绕通知后通过调用 ProceedingJointPoint 对象的 proceed 方法使目标方法继续执行开发者可以再次修改目标方法的执行参数、返回值并且可以在此目标方法的异常。
package com.hmblogs.backend.util;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;Aspect
Component
public class LogAspect {// 定义一个切入点Pointcut(execution(* com.hmblogs.backend.service.*.*(..)))public void pc1(){}// 前置通知Before(value pc1())public void before(JoinPoint jp) {String name jp.getSignature().getName();System.out.println(name 方法开始执行...);}// 后置通知After(value pc1())public void after(JoinPoint jp) {String name jp.getSignature().getName();System.out.println(name 方法执行结束...);}// 返回通知AfterReturning(value pc1(), returning result)public void afterReturning(JoinPoint jp, Object result) {String name jp.getSignature().getName();System.out.println(name 方法返回值为 result);}// 异常通知AfterThrowing(value pc1(), throwing e)public void afterThrowing(JoinPoint jp, Exception e) {String name jp.getSignature().getName();System.out.println(name 方法抛异常了异常是 e.getMessage());}// 环绕通知Around(pc1())public Object around(ProceedingJoinPoint pjp) throws Throwable {String name pjp.getSignature().getName();// 统计方法执行时间long start System.currentTimeMillis();Object result pjp.proceed();long end System.currentTimeMillis();System.out.println(name 方法执行时间为 (end - start) ms);return result;}
}
3创建 Controller
配置完成后接下来在 Controller 中创建接口调用 UserService 中的方法。
package com.hmblogs.backend.controller;import com.hmblogs.backend.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 HelloController {AutowiredUserService userService;GetMapping(/test)public String test(Integer id) {return userService.getUserById(id);}
}4运行样例
1使用浏览器访问如下地址
http://localhost:8081/test?id11
2查看控制台信息可以发现 LogAspect 中的代码动态地嵌入目标方法中执行了。