Springboot-Aop基于正则表达式和注解实现

2022-07-02 08:49:24

Springboot-Aop基于正则表达式和注解实现

一.Aop的基本概念

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

我的理解总的一句话就是:没有侵入性的为原先的应用提供方法增强或者是补充。

AOP的几个关键词

1.Aspect(切面):通常是一个类,里面可以定义切入点(LogAspect)和通知(doBefore())

2.JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用如index(),addUser();

3.Advice(通知):AOP在特定的切入点上执行的增强处理,就是你使用Aop的目的,如记录日志等,有before,after,afterReturning,afterThrowing,around

4.Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式如@Pointcut(“execution(public * com.he.controller..(…))”)

5.AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类

二.Pom文件导入依赖

导入Aop的依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

项目结构

三.具体实现

方式一.使用正则表达式配置切入点

a.添加切面

@Aspect@ComponentpublicclassLogAspect{/**
     * @auther: 何十一
     * @date: 2021/3/3
     * @Description:对com.he.controller下的所有类的所有方法执行Aop处理
     */@Pointcut("execution(public * com.he.controller.*.*(..))")publicvoidLogAspect(){}/**
     * @auther: 何十一
     * @date: 2021/3/3
     * @Description:执行方法前
     */@Before("LogAspect()")publicvoiddoBefore(JoinPoint joinPoint){//得到请求参数的值Object[] args= joinPoint.getArgs();for(int i=0; i< args.length; i++){System.out.println("参数"+ i+"--->"+ args[i]);}//获得代理对象System.out.println("代理对象"+ joinPoint.getTarget());//通知的签名,被代理的方法Signature signature= joinPoint.getSignature();System.out.println("通知的签名--->"+ signature);System.out.println("代理方法的名称--->"+ signature.getName());System.out.println("doBefore");}/**
     * @auther: 何十一
     * @date: 2021/3/3
     * @Description:执行方法后
     */@After("LogAspect()")publicvoiddoAfter(JoinPoint joinPoint){System.out.println("doAfter");}/**
     * @auther: 何十一
     * @date: 2021/3/3
     * @Description:执行方法返回后
     */@AfterReturning("LogAspect()")publicvoiddoAfterReturning(JoinPoint joinPoint){System.out.println("doAfterReturning");}/**
     * @auther: 何十一
     * @date: 2021/3/3
     * @Description:执行方法出错时
     */@AfterThrowing("LogAspect()")publicvoiddeAfterThrowing(JoinPoint joinPoint){System.out.println("deAfterThrowing");}@Around("LogAspect()")publicObjectdoAround(ProceedingJoinPoint joinPoint)throwsThrowable{System.out.println("doAround1");Object proceed= joinPoint.proceed();//相当于执行了原来的被代理的方法System.out.println("doAround2");return proceed;}}

b.创建Controller测试

@RestControllerpublicclassIndexController{@GetMapping("/index1")publicStringindex(String name,Integer age){System.out.println("方法执行1");//int a=1/0;return"hello,index1";}@GetMapping("/index2")publicStringindex2(){System.out.println("方法执行2");return"hello,index2";}}

c.测试

向url中输入

http://localhost:8080/index1?name=he&age=1

d.结论

doAround1
参数0--->he
参数1--->1
代理对象com.he.controller.IndexController@1c94b9c6
通知的签名--->Stringcom.he.controller.IndexController.index(String,Integer)
代理方法的名称--->index
doBefore
方法执行1
doAfterReturning
doAfter
doAround2

方式二.使用自定义注解实现

a.自定义注解MyAop

@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public@interfaceMyAop{Stringparam()default"";}

b.添加切面类

@Aspect@ComponentpublicclassLogAspect2{@Around("@annotation(myAop)")publicObjectaround(ProceedingJoinPoint joinPoint,MyAop myAop)throwsThrowable{System.out.println("around-方法开始");Object o= joinPoint.proceed();System.out.println("around-方法结束");return o;}@Before("@annotation(myAop)")publicvoidbefore(MyAop myAop){System.out.println("方法开始前");}@After("@annotation(myAop)")publicvoidafter(MyAop myAop){System.out.println("方法开始后");}@AfterReturning("@annotation(myAop)")publicvoidafterReturning(MyAop myAop){System.out.println("afterReturning");}}

c.创建Controller2测试

咋需要使用aop切入的方法上面使用@MyAop注解即可

@RestControllerpublicclassIndexController2{@GetMapping("/test1")@MyAoppublicStringtest1(){System.out.println("方法执行1");//int a=1/0;return"hello,test1";}@GetMapping("/test2")publicStringtest2(){System.out.println("方法执行2");return"hello,test2";}}

d.测试

http://localhost:8080/test1
around-方法开始
方法开始前
方法执行1
afterReturning
方法开始后
around-方法结束

五.总结

Springboot整合Aop还是比较简单,两种方式中推荐使用第一种方式,因为第一种完全没有侵入原来的代码。

希望对大家有帮助。

近期文章
SpringBoot整合Redis及简单使用
Docker安装Mysql以及Mysql的基本操作——入门必看
vue-cli十分钟学习入门笔记――开袋即食
如何判断2的n次方?用四种方式来扒一扒。
关于SpringAOP的三种实现方式你有了解过吗?
八皇后问题详细另类图解-九张图带你了解什么是八皇后问题
  • 作者:何 十 一
  • 原文链接:https://blog.csdn.net/qq_43392759/article/details/114376516
    更新时间:2022-07-02 08:49:24