我的杂记两篇

辅助创建对象工具

我们编写代码时有些时候需要编写组装比较复杂的参数,写起来,非常麻烦,我以前使用的一次mapstruct,想按照它的思路写一个编译时组件处理器,但是对于级联属性的赋值,在编译时无法获取详细信息,最终只能求助于运行时注解
实际也非常简单,就是使用反射创建对象,并对对象的级联属性赋值,若对象没有创建自动创建,我在此基础上又使用责任链与代理模式,把对象的创建逻辑,类型转换逻辑给抽取出来了
效果:
在这里插入图片描述
在这里插入图片描述

隔空传参

你是否遇到这样的问题,A创建B,B创建C,但是C需要A的参数,B虽然不需要但是还是要使用构造器或set传递这些参数,使用构造器传参会使对象创建代码非常不美观,set又容易忘记调用,并且最重要的是B不需要这个参数,这个参数对B是冗余的,这时可能有些人会想着IOC容器,但是容器中的对象并没有对象生命周期的范围,A被创建多次,C中所需的参数可能是专属自己A中的参数。于是我便想,使用发布参数的形式,父对象(例如A)发布参数,子对象(例如C)接受参数。
我使用ThreadLocal做了简单的实现
效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样的实现明显是有问题的,但是我暂时也没有什么好方法,但是我认为若它能被好好的实现,一定能对编程带来巨大的便利
补充
后来我发现通过Reflection.getCallerClass获取调用该方法的类信息(类似获取方法调用堆栈)可以解决一些问题

private static void setValue(Object obj, Field field, String name) {
        int deep=3;//从非框架代码开始
        Class<?> clazz=Reflection.getCallerClass(deep);//获取调用它的类
        while (clazz!=null){
            Map<String, Object> map = MAP_MAP.get(clazz);
            if(map!=null&&map.containsKey(name)){
                field.setAccessible(true);
                field.set(obj,map.get(name));
                return;
            }else {
                deep++;
                clazz=Reflection.getCallerClass(deep);
            }
        }
        throw new RuntimeException("对象"+obj+"没有找到");
    }

2021-12-24
我突然想到隔空传参可以使用发布订阅递归的方式,于是又写了两版

方案1,使用属性共享接受参数

在这里插入图片描述
在这里插入图片描述

方案2,通过发布接受传递数据

在这里插入图片描述
在这里插入图片描述
这样一来实际跟安卓的EventBus或Spring消息机制类似了

最后还是直接使用反射简单省事

public class Reflect {
    public static <T> T getValue(Object target, String exp){
        String[] exps = exp.split("\\.");
        for (int i = 0; i < exps.length; i++) {
            if(target==null){
                return null;
            }
            target=move(target,exps[i],false);
        }
        return (T) target;
    }
    /**
     * @param target  目标对象
     * @param exp     表达式
     * @param value   设置的值
     * @param create  是否在对象不存在时自动创建
     */
    @SneakyThrows
    public static void setValue(Object target, String exp, Object value, boolean create){
        String[] fields = exp.split("\\.");
        int last=fields.length-1;
        for (int i = 0; i < last; i++) {
            if(target==null){
                return;
            }
            target=move(target,fields[i],create);
        }
        if(target!=null){
            Field field = target.getClass().getDeclaredField(fields[last]);
            field.setAccessible(true);
            field.set(target,value);
        }
    }
    @SneakyThrows
    private static Object move(Object target, String fieldName, boolean create) {
        Field field = target.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        Object res = field.get(target);
        if(create&&res==null){
            res=field.getType().newInstance();
            field.set(target,res);
        }
        return res;
    }
    public static void setValue(Object target,String exp,Object value){
        setValue(target, exp, value,false);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值