使用Spring(Boot,AOP处理方法的入参和返回值)

这篇文章主要介绍了使用Spring Boot AOP处理方法的入参和返回值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

使用Spring,Boot,AOP处理方法的入参和返回值,久久派带你了解更多相关信息。

前言

IOC和AOP是Spring 中最重要的两个模块。这里练习一下如何使用Spring Boot AOP处理方法的入参和返回值。

Spring AOP的简单介绍:

AOP(Aspect-Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP能够将那些与业务⽆关,却为业务模块所共同调⽤的逻辑或责任(例如事务处理、⽇志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于提高系统的可拓展性和可维护性。

Spring AOP就是基于动态代理的,如果要代理的对象,实现了某个接⼝,那么Spring AOP会使⽤JDK代理,去创建代理对象,⽽对于没有实现接⼝的对象,就⽆法使⽤ JDK代理去进⾏代理了,这时候Spring AOP会使⽤Cglib ,这时候Spring AOP会使⽤ Cglib代理 ⽣成⼀个被代理对象的⼦类来作为代理,如下图所示:

使用Spring(Boot,AOP处理方法的入参和返回值)

一篇详细介绍AOP的文章:细说Spring——AOP详解(AOP概览)

1. 需求场景

前段时间实习,遇到了一个需求是这样的:项目上线前,项目经理要求有一个用户私密信息的字段需要在数据库中加密存储,从数据库读取出来后需要解密,正常显示到用户界面中。

下面的DEMO中,模拟场景项目经理突然觉得这个用户的身份证号是用户隐私需要进行加密保存,保护用户的隐私,User类定义如下:

public class User {    private Integer id;    private String username;    private String password;    private String identityNum;    //省略getter、setter、toString方法}

2. 解决方案

因为是临时加的需求,考虑到多个实体类中都会有identityNum属性,为了不侵入原本的业务代码和数据处理代码和业务代码的解耦,一个比较好的方案是使用Spring AOP处理,以DAO层方法做切点,处理字段的加密解密。

3. 代码实现

下面使用Spring Boot+MyBatis实现DEMO,模拟上述场景和解决方案实现。

Controller层UserController类的代码:

@RestController@RequestMapping(\"/users\")public class UserController {    @Autowired    UserService userService;    @GetMapping    public List<User> getAllUsers(){        return userService.getAllUsers();    }    @PostMapping    public void save(@RequestBody User user){        userService.save(user);    }}

Service层UserService类代码:

@Servicepublic class UserService {    @Autowired    UserDao userDao;    public List<User> getAllUsers() {        return userDao.getAllUsers();    }    public void save(User user) {        userDao.save(user);    }}

Dao层UserDao接口实现:

@Mapperpublic interface UserDao {    List<User> getAllUsers();    void save(@Param(\"user\") User user);}

UserMapper.xml文件实现:

<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\"><mapper namespace=\"top.javahai.springbootdemo.dao.UserDao\">    <insert id=\"save\">        insert into user values (#{user.id},#{user.username},#{user.password},#{user.identityNum})    </insert>    <select id=\"getAllUsers\" resultType=\"top.javahai.springbootdemo.entity.User\">        select id,username,password,identity_num as identityNum  from user    </select></mapper>

切面类UserInfoHandler实现如下,这里只是使用字符串截取的方法模拟加密代码,使用环绕通知@Around注解实现。

@Aspect@Componentpublic class UserInfoHandler {    @Pointcut(\"execution(* top.javahai.springbootdemo.dao.UserDao.*(..))\")    public void pointcut(){    }    @Around(\"pointcut()\")    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {        //处理方法参数,如果是User就进行加密处理        Object[] args = joinPoint.getArgs();        for (Object arg : args) {            if (arg instanceof List){                if (((List) arg).get(0) instanceof User){                    ((List<User>) arg).forEach(user->{                        user.setIdentityNum(\"encode\"+user.getIdentityNum());                    });                }            }            if (arg instanceof User){                String identityNum = ((User) arg).getIdentityNum();                ((User) arg).setIdentityNum(\"encode\"+identityNum);            }        }        //执行方法,获取返回值        Object obj = joinPoint.proceed();        //处理方法返回值        if (obj instanceof List){            if (!((List) obj).isEmpty()){                if (((List) obj).get(0) instanceof User){                    ((List<User>) obj).forEach(data->{                        data.setIdentityNum(data.getIdentityNum().substring(6));                    });                }            }        }        return obj;    }}

如果是在其他实体类中也存在identityNum身份证字段,则需要在@PointCut中定义多个切点,另外处理的地方需要添加多个判断。定义多个切点:

    @Pointcut(\"execution(* top.javahai.springbootdemo.dao.UserDao.*(..)) ||\" +            \"execution(* top.javahai.springbootdemo.dao.ResumeDao.*(..))\")    public void pointcut(){}

4. 测试

通过http://localhost:8080/users接口,将保存一个新的用户数据到数据库中

使用Spring(Boot,AOP处理方法的入参和返回值)

查看数据库的存储:

使用Spring(Boot,AOP处理方法的入参和返回值)

取出所有的用户数据:

使用Spring(Boot,AOP处理方法的入参和返回值)

从测试结果可以看到代码可以正确的处理方法的入参和返回值。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持趣讯吧。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/13268.html

(0)
nan
上一篇 2021-08-16
下一篇 2021-08-16

相关推荐

  • 习近平同日本首相岸田文雄通电话

    国家主席习近平10月8日同日本首相岸田文雄通电话。习近平强调,中日是近邻,亲仁善邻,国之宝也。维护和发展中日友好合作关系,符合两国和两国人民根本利益,也有利于亚洲乃至世界和平、稳定、繁荣。

    2021-10-08
    0
  • 欠多少钱被起诉会坐牢(千万别触碰红线)

    不管是欠银行的钱,还是欠网贷机构的钱,如果借款人迟迟不还钱,对方很有可能通过法律渠道催收,到时候这件事情就会上升到一个比较严重的层面

    2021-08-28
    0
  • 老夫子出装(老夫子爆炸高伤害出装)

    “老夫子”这个英雄在路人局是一个相对小众的战士英雄,但因为其单挑出众以及后期单带能力出众,所以在职业赛场往往有很好的发挥。路人局老夫子公认的“天花板”是主播赖神,他对这个英雄的理解十分到位,细节把握无人能比,当之无愧的国服最强老夫子;而在职业赛场,不

    2021-12-27
    0
  • opporeno3pro有红外功能吗(Reno3 Pro性能测评)

    摘要:OPPOReno3Pro采用了6.5英寸,分辨率为2400×1080像素,材质为AMOLED的打孔屏,屏幕技术为康宁五代大猩猩玻璃,屏幕占比为92.1%,支持HDR10+,90Hz刷新率,180HZ最高采样率。

    2023-05-12
    0
  • 上海邮政男员工殴打女员工 已被行拘 !打人者也已被停职 !

    4月21日,“上海邮政职工在岗打人”一事又有新进展。4月21日,记者从上海静安警方获悉,涉事男子杨某因殴打他人被警方依法处以行政拘留处罚。4月20日,中国邮政集团有限公司上海市分公司表示,对“上海邮政静安区分公司闸北邮政支局员工打人视频”相关网络舆情高度重视,第一时间进行了核查。对打人者的行为深表震

    热点头条 2023-04-21
    0
  • 陈亚男离婚了吗(陈亚男的个人资料简介)

    朱之文最近遇到了一件头疼事儿,那就是儿子被儿媳妇撵回了家。在陈亚男和朱之文儿子结婚一周年的时候,陈亚男在直播间说出了很多内心想说的…

    2021-10-07
    0

发表回复

登录后才能评论