项目操作常见工具类(持续更新中)

Lou.Chen
大约 2 分钟

1、使用cglib高效拷贝对象属性

注意事项:

  • spring-core中已经将cglib集成在其中,不需要导入其他的包,直接使用即可。类路径:org.springframework.cglib.beans.BeanCopier
  • 两个对象中如果相同字段的类型不一致,则无法复制属性值,会导致目标对象的此字段值为null,请保证字段类型保持一致。
  • 针对第二点,实体对象中不要使用基础类型(int、long、boolean等),统一使用包装类型(Integer、Long、Boolean等)

对象间属性拷贝在DTO到VO或者PO到VO之间会经常使用,而这个对象属性拷贝不同的实现方案性能差异极大,为保证平台的稳定性,规范的一致性。我们建议各位采用CglibBeanCopier来实现对象属性拷贝,避免BeanUtils.copyproperties()这种性能差的方案,核心代码为

 // 动态生成用于复制的类
 BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
 // 执行source到target的属性复制
 copier.copy(source, target, null);
  • 具体示例
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AppleDTO {
    private String name;
    private Integer price;
    private String address;
    private String weight;
    private String createDate;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FoodDTO {
    private Integer price;
    private String code;
    private Integer weight;
    private String name;
    private Date createDate;
}
		AppleDTO source = new AppleDTO();
		source.setPrice(new Integer(43));
		FoodDTO target = new FoodDTO();
		// 动态生成用于复制的类
		BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
		// 执行source到target的属性复制
		copier.copy(source, target, null);
		if(target.getPrice()==43){
			System.out.println("cp success!");
		}

2、动态修改注解信息

  • BaseRemotePush
@TBASClient(addresses = "${thinkive.tbas.push.addresses}")
public interface BaseRemotePush extends AskSenderAware {

    /**
     * 同步调用
     * @param parameters 方法参数
     * @return
     */
    @Function(value = 2, timeout = 10000L, parameters = {
            @Parameter(name = "account_id", value = "123")
    })
    ResultAdapter methodSync(Map<String, Object> parameters);


    /**
     * 异步调用
     * @param parameters 方法参数
     * @return
     */
    @Function(value = 1, timeout = 10000L, parameters = {
            @Parameter(name = "account_id", value = "123")
    })
    CompletableFuture<ResultAdapter> methodAsync(Map<String, Object> parameters);

    /**
     * Reactive模式调用
     * @param parameters 方法参数
     * @return
     */
    @Function(value = 3, timeout = 10000L, parameters = {
            @Parameter(name = "account_id", value = "123")
    })
    Mono<ResultAdapter> methodReactive(Map<String, Object> parameters);
}
  • DynamicRemoteValue

public class DynamicRemoteValue {

public Class<? extends BaseRemotePush> dynamicValue(Class<? extends BaseRemotePush> baseRemotePushClass, int functionId) {
    Method[] declaredMethods = baseRemotePushClass.getDeclaredMethods();
    for (Method item : declaredMethods) {
        Function annotation = item.getAnnotation(Function.class);
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
        try {
            Field f1= invocationHandler.getClass().getDeclaredField("memberValues");
            f1.setAccessible(true);
            Map r = null;
            r = (Map) f1.get(invocationHandler);
            r.put("value", functionId);
            Annotation[] annotations = item.getAnnotations();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return baseRemotePushClass;
}

public static void printAnnotationInfo(Class<?> baseRemotePush) {
    Method[] declaredMethods = baseRemotePush.getDeclaredMethods();
    for (Method item : declaredMethods) {
            Annotation[] annotations = item.getAnnotations();
            for (Annotation annoitem : annotations) {
                System.out.println("注解打印:"+annoitem.toString());
            }
    }
}

}

待研究问题

1、Springsecurity中登录为什么默认只能为键值对即key-value形式?

2、fastdfs中对防盗链的处理?

3、多数据源处理?

4、rabbitmq消息丢失的处理?rabbitmq消息持久化 消息的幂等性

5、枚举的使用

6、spirng循环依赖

7、重复提交

8、导出表格(redis限流)

9、网站的访问量(redis 位图操作)