Spring 项目利用自定义注解 + 反射机制,消除重复代码

>>号外:关注“Java精选”公众号,回复“面试资料”,免费领取资料!“Java精选面试题”小程序,3000+ 道面试题在线刷,最新、最全 Java 面试题!

1. 案例场景

假设银行提供了一些 API 接口,对参数的序列化有点特殊,不使用 JSON,而是需要我们把参数依次拼在一起构成一个大字符串。

按照银行提供的API文档顺序,将所有的参数构成定长的数据,并且拼接在一起作为一整个字符串。

因为每一种参数都有固定长度,未达到长度需要进行填充处理

  • 字符串类型参数不满长度部分要以下划线右填充,即字符串内容靠左

  • 数字类型的参数不满长度部分以0左填充,即实际数字靠右

  • 货币类型的表示需要把金额向下舍入2位到分,以分为单位,作为数字类型同样进行左填充

  • 参数做MD5 操作作为签名

2. 初步代码实现

public class BankService {

//创建用户方法

public static String createUser(String name, String identity, String mobile, int age) throws IOException {

StringBuilder stringBuilder = new StringBuilder();

//字符串靠左,多余的地方填充_

stringBuilder.append(String.format(“%-10s”, name).replace(’ ', ‘_’));

//字符串靠左,多余的地方填充_

stringBuilder.append(String.format(“%-18s”, identity).replace(’ ', ‘_’));

//数字靠右,多余的地方用0填充

stringBuilder.append(String.format(“%05d”, age));

//字符串靠左,多余的地方用_填充

stringBuilder.append(String.format(“%-11s”, mobile).replace(’ ', ‘_’));

//最后加上MD5作为签名

stringBuilder.append(DigestUtils.md2Hex(stringBuilder.toString()));

return Request.Post(“http://localhost:45678/reflection/bank/createUser”)

.bodyString(stringBuilder.toString(), ContentType.APPLICATION_JSON)

.execute().returnContent().asString();

}

//支付方法

public static String pay(long userId, BigDecimal amount) throws IOException {

StringBuilder stringBuilder = new StringBuilder();

//数字靠右,多余的地方用0填充

stringBuilder.append(String.format(“%020d”, userId));

//金额向下舍入2位到分,以分为单位,作为数字靠右,多余的地方用0填充

stringBuilder.append(String.format(“%010d”, amount.setScale(2, RoundingMode.DOWN).multiply(new BigDecimal(“100”)).longValue()));

//最后加上MD5作为签名

stringBuilder.append(DigestUtils.md2Hex(stringBuilder.toString()));

return Request.Post(“http://localhost:45678/reflection/bank/pay”)

.bodyString(stringBuilder.toString(), ContentType.APPLICATION_JSON)

.execute().returnContent().asString();

}

}

这样做能够基本满足需求,但是存在一些问题:

  • 处理逻辑互相之间有重复,稍有不慎就会出现Bug

  • 处理流程中字符串拼接、加签和发请求的逻辑,在所有方法重复

  • 实际方法的入参的参数类型和顺序,不一定和接口要求一致,容易出错

  • 代码层面参数硬编码,无法清晰进行核对

3. 使用接口和反射优化代码

3.1 实现定义了所有接口参数的POJO类

@Data

public class CreateUserAPI {

private String name;

private String identity;

private String mobile;

private int age;

}

3.2 定义注解本身

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

@Documented

@Inherited

public @interface BankAPI {

String desc() default “”;

String url() default “”;

}

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)

@Documented

@Inherited

public @interface BankAPIField {

int order() default -1;

int length() default -1;

String type() default “”;

}

3.3 反射配合注解实现动态的接口参数组装

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

Docker步步实践

目录文档:

①Docker简介

②基本概念

③安装Docker

④使用镜像:

⑤操作容器:

⑥访问仓库:

⑦数据管理:

⑧使用网络:

⑨高级网络配置:

⑩安全:

⑪底层实现:

⑫其他项目:

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

⑩安全:

[外链图片转存中…(img-qnKPWhsi-1712678804449)]

⑪底层实现:

[外链图片转存中…(img-2diNwrF2-1712678804449)]

⑫其他项目:

[外链图片转存中…(img-VXYCy1HG-1712678804449)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 22
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值