千家信息网

如何基于SpringBoot实现自动装配返回属性

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要介绍了如何基于SpringBoot实现自动装配返回属性,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一:需求背景在业务开发
千家信息网最后更新 2026年10月31日如何基于SpringBoot实现自动装配返回属性

这篇文章主要介绍了如何基于SpringBoot实现自动装配返回属性,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

一:需求背景

在业务开发中经常会有这个一个场景,A(业务表)表中会记录数据的创建人,通常我们会用userId字段记录该数据的创建者,但数据的使用方会要求展示该数据的创建者姓名,故我们会关联用户表拿该用户的姓名。还有一些枚举值的含义也要展示给前端。导致原本一个单表的sql就要写成多表的关联sql,以及枚举含义的转换很是恶心。

例如:业务对象BusinessEntity.java

public class BusinessEntity {    /**     * 创建者id     */    private Long createUserId;     * 创建者名称 (需要关联用户表)    private String userName;     * 数据状态(0:有效,1失效)    private String status;     * 数据状态含义(需要解析0或1的含义给前端)    private String statusName;     * 数据集合    private List list;}

二:设计思路

就像@JsonFormat注解,可以指定返回日期格式。我们是不是可以也自定义一个注解,通过这个注解,我们可以自动的把需要联表的数据userName自动填充,需要解析的数据数据statusName如何通过枚举解析。

故定义枚举@AutowiredAttribute如下

/** * 自动装配属性 */@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})@Retention(RUNTIME)@Documentedpublic @interface AutowiredAttribute {    /**     * 当为默认值时,表明该属性为javaBean,且该javaBean需要自动注入属性     * 否则为指向的某一个属性     *     * @return     */    String param() default "";     * 默认为BaseEnum.class,     * 当为默认时注入数据的来源时redis缓存,     * 否则为枚举类型    Class enumClass() default BaseEnum.class;     * 数据源    DataSourceEnum dataSource() default DataSourceEnum.EMPTY;}

定义公共枚举继承继承接口BaseEnum

public interface BaseEnum {    String getCode();    String getMsg();}

定义数据源枚举如下dataSource

public enum DataSourceEnum implements BaseEnum {    SYSTEM_DICT("sys:dict:", "系统字典值", "sys_dict_value", "name"),    USER_NAME("user:name:", "用户的id与姓名的映射", "sys_user", "user_name"),    USER_ROLE("user:role:", "角色id于角色名称映射", "sys_role", "name"),    DEPT_NAME("dept:name:", "部门的id与部门名称的映射", "sys_dept", "name"),    EMPTY("00", "默认", "", "");    DataSourceEnum(String code, String msg, String tableName, String tableColumn) {        this.code = code;        this.msg = msg;        this.tableName = tableName;        this.tableColumn = tableColumn;    }    private String code;    private String msg;    /**     * 表明     */    private String tableName;     * 表的列    private String tableColumn;    @Override    public String getCode() {        return code;    public String getMsg() {        return msg;    public String getTableName() {        return tableName;    public String getTableColumn() {        return tableColumn;}

三:使用方法

对比原对象:通过新增注解,就避免的关联查询和数据解析

public class BusinessEntity {    /**     * 创建者id     */    private Long createUserId;     * 创建者名称 (需要关联用户表)    @AutowiredAttribute(param = "createUserId", dataSource = DataSourceEnum.USER_NAME)    private String userName;     * 数据状态(0:有效,1失效)    private String status;     * 数据状态含义(需要解析0或1的含义给前端)    @AutowiredAttribute(param = "status", enumClass = StatusEnum.class)    private String statusName;     * 数据集合    @AutowiredAttribute    private List list;}

四:注解解析器(核心代码)

/** * 填充相应体 */@Component@ControllerAdvice()public class FillResponseBodyAdvice implements ResponseBodyAdvice {    @Autowired    RedissonClient redissonClient;    JdbcTemplate jdbcTemplate;    private static String GET_CODE_METHOD_NAME = "getCode";    private static String GET_MSG_METHOD_NAME = "getMsg";    @Override    public boolean supports(MethodParameter returnType, Class converterType) {        if (ResponseResult.class.getName().equals(returnType.getMethod().getReturnType().getName())) {            return true;        }        return false;    }    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {        if (((ResponseResult) body).getCode() == 200) {//仅仅对相应为200结果处理            Object data = ((ResponseResult) body).getData();            Class aClass = data.getClass();            if (data instanceof List) {                //集合对象设置属性                setForListBeanArr((List) data);            } else {                //判断是否为自定义java对象                if (aClass.getSuperclass() instanceof Object) {                    setForJavaBeanArr(data, aClass);                }            }        return body;    /**     * 为集合对象设置属性     *     * @param list     */    void setForListBeanArr(List list) {        for (Object object : list) {            Class aClass = object.getClass();            setForJavaBeanArr(object, aClass);     * 为自定义javaBean对象设置值    private void setForJavaBeanArr(Object data, Class aClass) {        Field[] declaredFields = aClass.getDeclaredFields();        for (Field field : declaredFields) {            AutowiredAttribute annotation = field.getAnnotation(AutowiredAttribute.class);            if (annotation == null) {                continue;            //通过枚举注入            String param = annotation.param();            try {                field.setAccessible(true);                if (param.equals("")) {//注解表明该对象时javaBean对象                    //获取该javaBean对象                    Object data2 = field.get(data);                    if (data2 == null) {                        continue;                    }                    //属性是list对象                    if (data2 instanceof List) {                        setForListBeanArr((List) data2);                    } else if (data2.getClass().getSuperclass() instanceof Object) {                        setForJavaBeanArr(data2, data2.getClass());                } else {                    //反射获取值                    Field field1 = aClass.getDeclaredField(param);                    field1.setAccessible(true);                    Object o = field1.get(data);                    if (annotation.enumClass().getName().equals(BaseEnum.class.getName())) {                        //通过redis注入                        injectByEnum(o, field, data);                    } else {                        //通过枚举注入                        injectByRedis(o, field, data);            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (NoSuchFieldException e) {    private void injectByEnum(Object param, Field field, Object data) throws IllegalAccessException {        AutowiredAttribute annotationAutowiredAttribute = field.getAnnotation(AutowiredAttribute.class);        DataSourceEnum dataSourceEnum = annotationAutowiredAttribute.dataSource();        if (dataSourceEnum.equals(DataSourceEnum.EMPTY)) {            //不规范的        } else if (dataSourceEnum.equals(DataSourceEnum.SYSTEM_DICT)) {            Object o = redissonClient.getMap(DataSourceEnum.SYSTEM_DICT.getCode()).get(param);            if (o == null) {                o = getDictAndSetRedis(DataSourceEnum.SYSTEM_DICT, param);            field.set(data, o);    private void injectByRedis(Object param, Field field, Object data) throws IllegalAccessException {        AutowiredAttribute annotation = field.getAnnotation(AutowiredAttribute.class);        Class aClass = annotation.enumClass();        try {            // 获取所有常量            Object[] objects = aClass.getEnumConstants();            //获取指定方法            Method getMsg = aClass.getMethod(GET_MSG_METHOD_NAME);            Method getCode = aClass.getMethod(GET_CODE_METHOD_NAME);            for (Object obj : objects) {                if (getCode.invoke(obj).equals(param.toString())) {                    field.set(data, getMsg.invoke(obj));                    System.out.println(getMsg.invoke(obj));        } catch (Exception e) {            System.out.println(e.getMessage());    //    Object getDictAndSetRedis(DataSourceEnum dataSourceEnum, Object value) {        String sql = "select name from " + dataSourceEnum.getTableName() + " where id = " + value;        String s = jdbcTemplate.queryForObject(sql, String.class);        RMap map = redissonClient.getMap(dataSourceEnum.getCode());        map.put(value, s);        return s;}

实现了从数据库(mysql)自动查询,并把结果缓冲到数据库。

感谢你能够认真阅读完这篇文章,希望小编分享的"如何基于SpringBoot实现自动装配返回属性"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

数据 对象 属性 创建者 含义 注解 用户 关联 名称 状态 篇文章 装配 业务 前端 姓名 用户表 有效 数据库 数据源 方法 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州大一互联网络科技有限公司 互联网科技行业发展 金融科技还是互联网 科技类互联网 金融科技 互联网金融 上海致骋互联网科技 友谊互联网络科技 撒么互联网科技公司 中国互联网金融科技基金 互联网科技热点资讯 随着互联网科技发展 互联网和黑科技的看法 互联网还是高科技吗 移动互联网年度科技创新 开一家科技互联网公司需要多少钱 电子科技大学互联网创业大赛 互联网金融科技展 西安小鹰速贷互联网科技有限公司 广州智享互联网科技 互联网科技创业有什么好项目 互联网是不是新科技 善班互联网科技有限公司 掌上梦互联网科技 深圳前海聚择互联网科技有限公司 常德市电业局互联网科技部 开一家科技互联网公司需要多少钱 华夏恒生科技与互联网科技 高科技互联网发展前景如何 上海乐五互联网科技有限公司 互联网科技博主张洲
0