最近遇到的几个问题集合
最近在写项目的时候遇到了几个小问题,记录下来。希望对大家也有所帮助。
如何获取 T 的 class
在写BaseDao 之类的代码的时候,经常会遇到获取泛型T的class的情况?我们发现并没有T.class
这种写法,那怎么办呢?想起之前写的Hibernate 里面有相关的代码。通过反射获取T的class
1 | public class AbstractDao<T>{ |
Spring中的 @Value 加载时间
首先 @Value
注解可以方便的获取配置文件*.properties
的参数。
在写代码的时候遇到这样一个问题。为了减少重复代码,我们通常需要写一个抽象类把共有的方法抽象到Abstract 类中。AbstractDao<T>
如果遇到需要向这个class的构造方法注入参数。且这个参数是通过抽象方法获取的。且这个数据是使用 Spring的 @Value 注解获取的。这个描述比较绕,我们直接看代码:
1 | public class AbstractDao<T>{ |
1 | public class UserDao extends AbstractDao<User>{ |
代码运行起来以后,我们发现 userTableId,并不能取到相应的值,这个时候@Value
失效了。实际上这个问题的根源是因为@Value
的加载是发生在对象实例化之后。也就是首先调用对象的构造函数,然后再获取配置文件中的数据。
解决的方案是使用注解 @PostConstruct
,意思是构造函数执行完以后再执行注解标记的方法。我们可以吧抽象函数做如下修改:
1 | public class AbstractDao<T>{ |
使用 Java 8 的 lambda 和 stream 来 merge List
在使用微服务架构以后。我们经常会遇到 Merge两个List的场景。比如我们从索引里面获取了一个 List<Long>
包含的是对象的ID的 list。由于前端对象展示的元素需要。用这个ID 的list分别从两个服务批量的查询得到 List<A>
和 List<B>
,然后将两个List合二为一成为一个List<C>
,返回给前端作为列表页展示。
看代码:
首先我们有一个对象 A:
1 | public class A{ |
有另一个对象 B:
1 | public class B{ |
页面需要的对象C:
1 | public class C{ |
如何有效的把 List<A>
和 List<B>
merge 为一个 List
总体思路,因为两个list从不同服务里面获取。有可能两个服务出于健壮性的考虑会抛弃某些查询不到的对象,所以两个list的长度有可能不一致。所以使用一个Map<Long,B> 作为索引。
如果直接写代码会相当繁琐。如果使用 Java 8 的新特性Lamabda
和stream api
就能快速写出代码。
1 |
|
这样merge的代码简洁明了。
如果不明白的同学可以参考我之前的 Java 8 教程。