手机报价网,哈尔滨seo优化代理,鞍山网站建设找金航,app拉新推广代理一、为什么需要面向切面编程#xff1f;
面向对象编程#xff08;OOP#xff09;的好处是显而易见的#xff0c;缺点也同样明显。当需要为多个不具有继承关系的对象添加一个公共的方法的时候#xff0c;例如日志记录、性能监控等#xff0c;如果采用面向对象编程的方法
面向对象编程OOP的好处是显而易见的缺点也同样明显。当需要为多个不具有继承关系的对象添加一个公共的方法的时候例如日志记录、性能监控等如果采用面向对象编程的方法需要在每个对象里面都添加相同的方法这样就产生了较大的重复工作量和大量的重复代码不利于维护。面向切面编程AOP是面向对象编程的补充简单来说就是统一处理某一“切面”的问题的编程思想。如果使用AOP的方式进行日志的记录和处理所有的日志代码都集中于一处不需要再每个方法里面都去添加极大减少了重复代码。
二、Spring AOP术语 通知Advice包含了需要用于多个应用对象的横切行为就是定义了“什么时候”和“做什么”。
连接点Join Point是程序执行过程中能够应用通知的所有点。
切点Poincut是定义了在“什么地方”进行切入哪些连接点会得到通知。显然切点一定是连接点。
切面Aspect是通知和切点的结合。通知和切点共同定义了切面的全部内容——是什么何时何地完成功能。
引入Introduction允许我们向现有的类中添加新方法或者属性。
织入Weaving是把切面应用到目标对象并创建新的代理对象的过程分为编译期织入、类加载期织入和运行期织入。
三、Spring Boot AOP实战
1、引入依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactIdversion2.7.2/version
/dependency
不需要再添加aspectjweaver的依赖了因为spring-boot-starter-aop包含了aspectjweaver
2、 编写用于拦截的bean
直接定义一个controller
RestController
public class AopController {GetMapping(/hello)public ResultMap sayHello(){ResultMap resultMap new ResultMap();resultMap.setCode(1);resultMap.setMessage(响应成功);resultMap.setData(Hello World!);return resultMap;}
}
3、 定义切面
Spring采用Aspect注解对POJO进行标注该注解表明该类不仅仅是一个POJO还是一个切面。切面是切点和通知的结合那么定义一个切面就需要编写切点和通知。在代码中只需要添加Aspect注解即可。
1定义切点
切点是通过Pointcut注解和切点表达式定义的。由于Spring切面粒度最小是达到方法级别而execution表达式可以用于明确指定方法返回类型类名方法名和参数名等与方法相关的部件并且实际中大部分需要使用AOP的业务场景也只需要达到方法级别即可因而execution表达式的使用是最为广泛的。如图是execution表达式的语法 execution表示在方法执行的时候触发。以“*”开头表明方法返回值类型为任意类型。然后是全限定的类名和方法名“*”可以表示任意类和任意方法。对于方法参数列表可以使用“..”表示参数为任意类型。如果需要多个表达式可以使用“”、“||”和“!”完成与、或、非的操作。
2定义通知
通知有五种类型分别是
前置通知Before在目标方法调用之前调用通知
后置通知After在目标方法完成之后调用通知
环绕通知Around在被通知的方法调用之前和调用之后执行自定义的方法
返回通知AfterReturning在目标方法成功执行之后调用通知
异常通知AfterThrowing在目标方法抛出异常之后调用通知
Aspect
Component
public class AopAdvice {Pointcut(execution(* com.mq.rabbit.controller.*.*(..)))public void pointCut(){}Before(pointCut())public void beforeAdvice(){System.out.println(\t------前置通知------);}After(pointCut())public void afterAdvice(){System.out.println(\t------后置通知------);}Around(pointCut())public Object aroundAdvice(ProceedingJoinPoint joinPoint) {System.out.println(------环绕通知开始------);Object result null;try {result joinPoint.proceed(); //接收Controller的返回值}catch (Throwable t){t.printStackTrace();}System.out.println(------环绕通知结束------);return result; //将Controller方法的返回值返回}
}
4、启动测试
运行项目在浏览器访问http://localhost:端口号/项目名/hello控制台输出如图所示