- 以下内容只提供 关于Aop 使用的业务场景的思考及 关于Spring aop Around 环绕增强的一部分简单使用介绍,如果想要看Spring aop 如何使用的请移步spring 官网 查看使用文档
我们时常会遇到这样的场景。
1.当业务逻辑模块已经写完,却又突发的想要在这个已经完成了一阶段的逻辑上,进一步处理。
2.当我们的项目数据库结构已经设计完成,并已投入使用一段时间。但这时,我们有需要让我们的项目去对接外部接口。这时就会出现,【语义】上的偏差。说白了,就是我们的A字段 和接口出来的 B字段 其实是同一个意义上的值,但却无法直接使用。(我叫身份证为a ,小明叫身份证为b,明明都是身份证,却有2种说法,b在某种意义上是不能被我直接当成身份证来用的,我们必须把b 转为 a 才能在我这里当成身份证)。这时候呢。要怎么处理。
我原先是想说写成一个适配器,就是做一下简单的转译处理。
写一个类,专门做这种特定的处理。在需要转译的地方,我们引入这个类,例如这样
List<String> a = ...... //a 是未处理过得知
List<String> b = change(a) //经过chane处理后 转为了 b
但后来一想,这样做,其实对原先的代码会存在类的侵入性。不是很友好且优雅。
这时候,我就发现了,其实所有做的这些事,无非就是在原先的基础上做 【拓展】,在衍生一下
其实就是面向切面所说的那样,【增强处理】。
那就优雅了!
使用Spring aop 对这块逻辑 进行【增强处理】!
这里有一点需要强调!!!!!
Aop 的 增强 其实很需要我们的代码质量高及业务逻辑分解度高。因为只有这样的代码块,才能对其增强。你不可能要求aop在每行代码上下进行逻辑【增强】的。
所以,小伙伴们,一定要对自己的代码质量及封装,抽象能力,业务模块划分能力提高要求。
关于Spring aop 具体的各类使用 我这里就不具体列举了。建议大家去看文档,网上的代码乱又杂,文档还是最清晰的。。
我这里就提一个 【环绕增强 @Around】的处理
我们使用Aop 除了 日常的权限控制,日志记录,等一些常规用法外。
还会经常碰到这样一个事情,例如我想 【转译】!
什么叫【转译】呢??
在列举一个常况。
我从外部接口获取到这样这个接口数据格式
[{ "uuid":"123","userName":"小明","sex":"男"}]
我们想要把这个数据插入我们的数据库,或是映射在我们的前端页面上。
但!我们的库表结构 是这样的 name 代表 username usersex 代表 sex
这时候怎么办???
很多小伙伴会说,直接改呗。是的。这也是行的。但是!如果我们很多页面上都使用了 name 去映射信息。而全局替换的方式风险又很大。这时候如何降低风险。没错,就是使用【转译】。
我们把我们的项目想象成一个容器!我们已经把容器的内容都做好了。但,就因为要对接外部参数,就该全部更新一遍我们的容器内部实现吗??肯定是不合理的。这样的工作是在浪费时间。
那我们就这样,在容器外面裹一层滤网,对所有想要进入我们项目的数据进行预处理 【转译】!!!
这样,我们就不需要改变内部实现,转成我们内部能解析的格式就行了。
而!Around 就很符合这个思想。
我们的容器肯定不是游离与体系之外的,肯定是与其它项目进行沟通的。那就肯定会出数据的双向流动。
需要对接口进行前后【转译增强】!!!,那就意味着我们会对入参和结果返回值进行更改,那就只能使用到Aop 的Around 环绕增强了。
后面就贴一部分代码实例吧。
//伪代码,根据自己的业务需求使用
@Around("execution(* 。。。。拦截的方法路径(..)) && args(。。。参数名1,参数名2)")
public Object outerCheckMetaDmodAdapter(ProceedingJoinPoint joinPoint,参数名1,参数名2) throws Throwable{
//进入方法前的增强处理,拦截方法的参数可以从joinPoint 内取出
Object result = joinPoint.proceed(new Object[] {(beforeHandler((Map<String,Object>)object)),pageNum,pageSize});
//result => 方法的返回结果
//方法返回结果后的增强处理
//方法返回结果后的增强处理
List<Map<String,Object>> params = (List<Map<String,Object>>)result;
return afterHandler(params);
}