当前位置: 首页 > 后端技术 > Java

SpringAOP在项目中的典型应用场景

时间:2023-04-01 23:22:01 Java

学过Spring的相信都知道AOP,学好AOP的相信对AOP的概念很熟悉:面向切面编程,切点,aspect-cutting,notification,Aspect,Pointcut,Advice等等。AOP之所以如此重要,是因为它在项目中有着非常广泛的应用。在今天的文章中,宋哥就和大家总结一下我们在日常开发中需要用到AOP的典型场景有哪些。我先用一句话总结一下。AOP的使用基本上涉及自定义注解。一个非常常见的组合是自定义注释+AOP。在日常开发中,有很多重复的代码,我们总是希望能够简化它们。AOP是一种很常见的简化手段。简化的思路一般是这样的:首先,自定义一个注解。定义AOP切面。在切面中,定义切点和通知。截点就是方法的截取规则。我们可以根据注解来拦截,也就是有自定义注解的方法,我会拦截。拦截之后随便写什么,比如前置通知,后置通知,异常通知,返回通知或者环绕通知。所以这些涉及到自定义注解的地方基本上都可以看成是AOP的使用场景,因为自定义注解需要用AOP来解析。下面我们来看几个典型的例子。1.幂等性处理接口的幂等性处理其实有很多不同的方案,例如:Token机制去重表使用Redis的setnx设置status字段为lock无论采用哪种方案来处理幂等性,每种方法都是在里面写幂等处理显然是不现实的。所以幂等处理一般都是通过自定义注解+AOP来封装的。大致思路如下:首先,自定义一个注解。自定义切入点并使用自定义注释拦截所有方法。定义环绕通知。在环绕通知中,首先通过以上五种思路中的任意一种来判断方法执行的幂等性。如果判断通过,则执行目标方法。如果判断失败,则直接抛出异常。目标方法未执行。这是一个典型的自定义注解+AOP的应用场景。如果你对上面的说法感到困惑,不妨看看宋哥发的这个视频,里面有详细的一步一步的教程:处理接口幂等性的两种常用解决方案|一步步教你。2.接口限流对于接口限流,目前比较成熟的方案是使用阿里巴巴的Sentienl,通过简单的配置就可以实现接口限流。但是如果不使用这个工具呢?如果我们自己写呢?毫无疑问,还是自定义注解+AOP,思路大致如下:自定义注解。在需要限流的接口方法上添加自定义注解,同时设置一些限流参数,比如时间窗值,流量大小等。自定义切点,拦截规则都是添加了自定义注解的方法,方法被拦截后,在surroundnotification中,可以使用Redis插件redis-cell和漏斗算法来处理限流,这里就不多说了,在之前的文章中已经写过了。如果限流计算没有问题,就执行target方法,否则会被拦截。大体思路如上。说白了就是自定义注解+AOP。道理虽然简单,但是在实际实现中还是有很多细节问题。有兴趣的朋友可以参考松哥之前的这篇文章:Redis作为接口限流,一个注解的东西!.3、日志处理说到AOP,有几种使用场景大家都能想到。我不会重复这个。之前宋哥也专门介绍过一篇文章。没看过的可以点这里:记录项目日志,一个注解搞定。4.多数据源处理有时我们的项目中有多个不同的数据源,在实际使用中需要进行切换。网上也有一些开源的方案,不过这个东西其实也不难,我们自己写也可以。自定义多数据源处理的大致思路是:从Spring2.0.1开始引入AbstractRoutingDataSource类(注意Spring2.0.1不是SpringBoot2.0.1,所以这其实是Spring很老的一个特性),该类充当DataSource的路由中介,可以在运行时根据某个键值动态切换到真正的DataSource。一般的用法是,你提前准备好各种数据源,存储在一个Map中。Map的key是数据源的名称,Map的value是具体的数据源。然后将Map配置成AbstractRoutingDataSource。最后,每次执行一次数据库查询,取出一个key,AbstractRoutingDataSource会找到一个具体的数据源来执行这次数据库操作。基于以上知识,我们可以自定义一个注解,将这个注解添加到需要切换数据源的方法中,然后通过AOP解析自定义注解。当目标方法被拦截时,我们跟进注解中的配置,重新设置要执行的数据源,这样服务中的方法在以后的执行过程中就会使用切换后的数据源。这个想法并不难。宋大哥之前也写过详细的教程。小伙伴们可以参考这里:一步步教你玩多数据源动态切换!能否在网页上一键切换不同数据源?宋哥一步步教你!5.方法权限处理这个其实和上一个差不多。方法级别的权限处理一般是基于注解来完成的。如果使用SpringSecurity等权限框架,则不需要自己解析权限注解,直接根据框架的要求使用即可。有时候,我们可能没有使用SpringSecurity,想自己处理权限注解,这也是可以的。自定义权限注解,在注解中添加属性,然后在目标方法中添加注解,然后通过AOP解析注解,AOP拦截目标方法的执行,然后判断用户是否有需要的权限,如果是,则执行目标方法,否则不执行。松哥前两天刚刚分享的是在微服务里面,服务里面的权限校验就是自定义一个注解,拦截来自其他微服务的请求,然后判断请求的来源,如果是来自其他微服务的话就上来,执行目标方法。如果请求不是来自其他微服务,而是来自外部,那么会被拦截并抛出异常,目标方法不会执行。请参阅:如何在微服务中进行身份验证?.6.事务处理不需要自定义注解。对于声明式事务,可以直接使用现成的注解,但本质上也是AOP。如果有小伙伴在SpringXML中配置过事务,就会知道这个东西的底层也是AOP。好了,整理了几个简单的案例,希望小伙伴们明白AOP不是屠龙术,而是日常开发中广泛使用的技术。