目录
一、什么是Spring AOP
在做后台系统的时候,除了登录和注册等几个功能不需要做用户登录验证以外,其他几乎所有的地方都需要对于用户的权限做一个验证。可是如果每一个地方都这样验证,肯定会消耗比较多的维护成本。
所以,对于这种统一的功能,并且使用的地方比较多,就可以考虑使用AOP来统一处理了。
二、AOP的相关概念
①切面(类)
某一方面的具体内容就是一个切面;例如判断用户是否登录就是一个“切面”。
对于日志的统一记录也是一个切面。
当定义一个类的时候,这个类的功能是什么,可以就理解为“切面”。
②切点(方法)
定义一个拦截的规则;类似于:定义一个具体的方法是什么
③通知(方法的具体实现)
执行AOP响应的逻辑业务;
3.1前置通知:在目标方法(实际要执行的方法)调用之前执行的通知;
3.2后置通知:在目标方法(实际要执行的方法)调用之后执行的通知;
3.3环绕通知:在目标方法调用前、后都执行的通知;
3.4异常通知:在目标方法抛出异常的时候执行的通知;
3.5返回通知:在目标方法返回的时候执行的通知。
④连接点(Join Point)
所有可能触发切点的点就叫做连接点。
三、实现SpringAOP
第一步:添加springBoot的依赖
此处采用的是SpringBoot的项目,所以导入SpringBoot的AOP依赖;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
第二步:新建统一功能处理的类
在启动类的同一级目录下面新建一个包,在这包当新建类
新建好之后,在这个类当中添加两个注解:
一个是@Aspect注解,另一个是@Component
@Aspect
@Component
public class UserAOP {
}
那么,这个时候,切面就已经定义好了。
第三步:创建切点
3.1找到需要拦截的对象
首先,需要定义到需要拦截的类的路径:
例如:此处需要拦截UserController,那么就需要找到这个类的全限定名;
此处我需要拦截UserController这个类,因此就在@Pointcut的参数当中传入字符串:
这个字符串的内容为:execution(* +需要拦截的对象);注意“*”之后会带有一个空格。
@Pointcut("execution(* com.example.demo.Controller.UserController)")
此处拦截的对象是UserController这个类。
拦截表达式
①拦截某个方法
@Pointcut("execution(* com.example.demo.Controller.UserController.*(..))")
类.*代表的是拦截所有方法;类.*()当中的内容为方法的传入参数;此处传入..代表的意思是所有类型的参数。
如果想要拦截int类型的参数,那么就把..替换为具体的参数类型:
/**
* 定义拦截规则
*/
@Pointcut("execution(* com.example.demo.Controller.UserController.*(int,String))")
如图,此时拦截的就是int类型和String类型的参数
3.2编写拦截的方法
@Pointcut注解是需要作用于某一个方法上面的;下面就来编写这个方法的实现:
/**
* 定义拦截规则
*/
@Pointcut("execution(* com.example.demo.Controller.UserController.*(int,String))")
public void pointcut(){
}
3.2.1各类通知
前置通知:@Before
@Before注解的参数为调用的方法,那么在doBefore方法内部就是需要编写的内容;
@Before("pointcut()")
public void doBefore(){
}
后置通知:@After
@After("pointcut()")
public void doAfter(){
System.out.println("执行了后置方法");
}
环绕通知:@Around
@Around("pointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("begin Around");
//执行切点方法
Object obj=joinPoint.proceed();
System.out.println("After Around");
return obj;
}
当执行jointPoint.proceed()方法的时候
3.3编写连接点
连接点在上面也提到过,就是触发切点的“点”。
例如在上面的代码当中,切面是UserController那么连接点就是请求UserController接口当中的方法