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
@Component
public class LogAspect {
/**
* @auther: 何十一
* @date: 2021/3/3
* @Description:对com.he.controller下的所有类的所有方法执行Aop处理
*/
@Pointcut("execution(public * com.he.controller.*.*(..))")
public void LogAspect() {
}
/**
* @auther: 何十一
* @date: 2021/3/3
* @Description:执行方法前
*/
@Before("LogAspect()")
public void doBefore(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()")
public void doAfter(JoinPoint joinPoint) {
System.out.println("doAfter");
}
/**
* @auther: 何十一
* @date: 2021/3/3
* @Description:执行方法返回后
*/
@AfterReturning("LogAspect()")
public void doAfterReturning(JoinPoint joinPoint) {
System.out.println("doAfterReturning");
}
/**
* @auther: 何十一
* @date: 2021/3/3
* @Description:执行方法出错时
*/
@AfterThrowing("LogAspect()")
public void deAfterThrowing(JoinPoint joinPoint) {
System.out.println("deAfterThrowing");
}
@Around("LogAspect()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("doAround1");
Object proceed = joinPoint.proceed();//相当于执行了原来的被代理的方法
System.out.println("doAround2");
return proceed;
}
}
b.创建Controller测试
@RestController
public class IndexController {
@GetMapping("/index1")
public String index(String name, Integer age) {
System.out.println("方法执行1");
//int a=1/0;
return "hello,index1";
}
@GetMapping("/index2")
public String index2() {
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
通知的签名--->String com.he.controller.IndexController.index(String,Integer)
代理方法的名称--->index
doBefore
方法执行1
doAfterReturning
doAfter
doAround2
方式二.使用自定义注解实现
a.自定义注解MyAop
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAop {
String param() default "";
}
b.添加切面类
@Aspect
@Component
public class LogAspect2 {
@Around("@annotation(myAop)")
public Object around(ProceedingJoinPoint joinPoint, MyAop myAop) throws Throwable {
System.out.println("around-方法开始");
Object o = joinPoint.proceed();
System.out.println("around-方法结束");
return o;
}
@Before("@annotation(myAop)")
public void before(MyAop myAop) {
System.out.println("方法开始前");
}
@After("@annotation(myAop)")
public void after(MyAop myAop) {
System.out.println("方法开始后");
}
@AfterReturning("@annotation(myAop)")
public void afterReturning(MyAop myAop) {
System.out.println("afterReturning");
}
}
c.创建Controller2测试
咋需要使用aop切入的方法上面使用 @MyAop注解即可
@RestController
public class IndexController2 {
@GetMapping("/test1")
@MyAop
public String test1() {
System.out.println("方法执行1");
//int a=1/0;
return "hello,test1";
}
@GetMapping("/test2")
public String test2() {
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的三种实现方式你有了解过吗? |
八皇后问题详细另类图解-九张图带你了解什么是八皇后问题 |