AOP在SpringBoot中的实际运用


前言

AOP是面向切面编程,是OOP(面向对象编程)的延续。面向对象编程大家都使用过,万物皆对象嘛。而面向切面编程则是针对业务处理过程中的某一面进行提取,而不是面向整个对象来编程。

面向切面编程最大的特点就是,能够做到在不改变源码的前提下,实现对原有功能的升级与扩展,降低模块之间的耦合性,他的底层是动态代理。
在这里插入图片描述


一、浅提一嘴IOC

IOC、AOP是spring框架的两大核心技术,IOC是控制反转,也就是将创建对象的过程交给spring来管理。IOC创建的对象都放在spring容器中,想要使用对象就使用DI,也就是直接用依赖注入就可以使用啦~

二、AOP的核心概念

AOP总共有五大核心概念,分别是:

1、连接点(joinPoint):连接点是指程序执行过程中的一些点,比如方法调用,异常处理等。在 Spring AOP 中,仅支持方法级别的连接点。说直接一点就是,类中的所有方法,只要符合切入点条件的,能被增强的,都是连接点

2、通知(Advice):指拦截到连接点之后要执行的代码

3、切入点(PointCut):是对连接点进行拦截的条件定义

4、切面(Aspect):通知+切入点,将通知中的代码,通过切入点,动态加载到方法里面

5、目标对象(Target):真正被扩展的类的对象

可能不太好理解,我们画个图就好办了

在这里插入图片描述

三、使用步骤

1.导入依赖

代码如下(示例):

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

2.构建连接点

其实就是写一点类和方法
在这里插入图片描述

这是一个非常简单的SpringBoot项目,简单实现了部门管理和员工管理两个功能
页面效果如下:
在这里插入图片描述

连接点我们一般选在service或者dao层,因为这两层是对业务、数据进行处理的层,而controller层主要是为了和前端进行交互,一般不用做增强。

连接点有几个重要的方法:

1、获取目标类名:joinPoint.getTarget().getClass().getName();

2、获取目标方法签名:joinPoint.getSignature();

3、获取目标方法名:joinPoint.getSignature().getName();

4、获取目标参数:joinPoint.getArgs();

仅在环绕通知里面还有一个特殊的:
5、执行原始方法:joinPoint.proceed();

3.编写通知

编写通知其实就是编写切面类的方法,也就是你想要增强的方法内容。这里我想将操作信息纪录下来,并在数据库中记录。因此我的切面方法就是要给数据库的字段赋值~

注意 :切面类需要打两个注解:分别是@Component、@Aspect

代码如下(仅适用于小编自己的项目,这些代码具体情况具体设计):

@Component
@Aspect
public class LogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Around("@annotation(com.study1.util.Log)")
    public Object addToMsg(ProceedingJoinPoint pjp) throws Throwable {

        OperateLog operateLog = new OperateLog();
        operateLog.setId(null);

        //1、判断是谁在操作
        //1.1、获取token
        String token = request.getHeader("token");
        //1.2、解析token
        Claims claims = JwtUtils.jwtBack(token);
        //获取操作人id
        Integer id = (Integer) claims.get("id");
        operateLog.setOperateUser(id);
        //获取操作时间
        operateLog.setOperateTime(LocalDateTime.now());

        //获取操作的类名
        String name = pjp.getTarget().getClass().getName();
        operateLog.setClassName(name);

        //获取操作的方法名
        String name1 = pjp.getSignature().getName();
        operateLog.setMethodName(name1);

        //获取方法参数
        Object[] args = pjp.getArgs();
        operateLog.setMethodParams(Arrays.toString(args));

        //方法耗时,开始时间
        long start = System.currentTimeMillis();
        //执行原方法获取返回值
        Object proceed = pjp.proceed();

        String retuenValue = JSON.toJSONString(proceed);
        operateLog.setReturnValue(retuenValue);

        //结束时间
        long end = System.currentTimeMillis();

        operateLog.setCostTime(start-end);

        operateLogMapper.insert(operateLog);

        return proceed;
    }
}


4.编写切入点

1、切入点其实就是看你如何去定义和筛选要增强的方法,切入点表达式一共有两个:

(1)execution(“url…”):指定路径增强,url是指要增强的类的路径,当前路径下的所有方法都会被AOP拦截,进行一波加强后再还给service层。

(2)@annotation(“url…”):指定自定义注解增强,url是自定义注解的全路径,当前项目中,只要打了此自定义注解额度,都会被AOP拦截,进行一波加强后再还给service层。

我这个示例项目中,只需要将修改、删除的操作记录下来,而查询本身不需要对数据库进行修改因此就不需要增强,所以不适合用路径增强。(具体情况具体分析哈~)

2、使用自定义注解增强,就要先自定义一个注解:
代码如下(示例):

@Target({ElementType.METHOD})  //指定这个注解打在什么地方上 类/方法/接口 等等。。。
@Retention(RetentionPolicy.RUNTIME)  //指定这个注解的生命周期
public @interface Log {
    
}

3、写好自定义注解之后,就可以引入到切面类里面了。细心的小伙伴已经发现了,在上述代码的方法上,有一个@Around注解,在里面已经写好切入点表达式了。

5.定义切面

切面类里面有一个很重要的知识点,叫通知类型。常见的通知类型一共有五种:

1、Around(环绕通知):顾名思义就是既可以在目标方法前增强,也可以在目标方法后增强的通知类型。这是功能最强大、可以调用目标方法、设置参数、获取返回值的通知种类等。

2、Before(前置通知):顾名思义就是只能在目标方法执行前增强

3、After(后置通知):顾名思义就是只能在目标方法执行后增强

4、AfterReturning(返回后通知):这个也是在目标方法执行后增强。但是与后置通知不一样的是,这个方法在遇到异常后不执行

5、AfterThrowing(异常后通知):顾名思义,只有发生异常了,才做增强

这有什么作用呢?其实它的作用就相当于你自行选择,你要增强或添加的方法,应该在目标方法执行之前执行,还是目标方法执行之后执行。增强完的方法要符合逻辑,因此才有五种分类。

在这个示例项目中,我想要增强的功能是,记录操作的人,以及操作了什么事,因为涉及到操作时间,因此要用到环绕通知。在上述代码的方法上方定义了环绕通知的注解。

测试一下:

删除五一加班部
在这里插入图片描述
查看五一加班部的部门id:
在这里插入图片描述
操作前查看部门操作表里面的记录

在这里插入图片描述

在前端执行删除操作:

在这里插入图片描述

删除完成查看部门表,加班部不存在了

在这里插入图片描述

在看部门操作表,14号部门已经解散了

在这里插入图片描述

最后根据操作时间就可以确定是谁操作了删除功能

在这里插入图片描述


总结

充电时刻
AOP在SpringBoot中的实际运用就是充当一个动态代理的作用,在不改变源码的前提下,动态的给它增加功能。亦或者大量的方法里面都有相同的方法,就可以用AOP进行代码提取。极大加快了我们的开发速率~

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值