@Bean和@PostConstruct能一起使用嘛?
答案是不能,具体是什么原因呢?
我们先来看下@Bean的定义
@Bean注解用于在配置类(标有@Configuration的类)中声明一个bean。当你使用@Bean注解时,你实际上是在告诉Spring:“这是一个方法,它的返回值应该被注册为Spring应用上下文中的一个bean”。Spring容器会在启动过程中调用这个方法,并管理返回的对象作为bean。
大多数人都知道@Bean是Spring的注解,这里也不过多解释,但是@PostConstruct呢?
@PostConstruct注解是Java EE 5引入的,用于标注在方法上,表明该方法是在依赖注入完成后被自动调用的初始化方法。它不需要任何参数,也不会返回任何值。Spring框架支持这个注解,并将其集成到Spring的bean生命周期中。因此,当Spring容器创建一个bean实例,并且所有必要的依赖注入完成后,它会检查bean类中是否有@PostConstruct注解的方法,并调用它。
很显然@PostConstruct不是Spring框架的中的注解,但是,他的码缘不错被Spring集成了。
到这里大家就会想,既然集成了就是自己家人,肯定能一起用啊,但是问题来了!
这个是作者在写代码的时候遇到的问题(一个大坑),先看代码
@Bean
public Map<String, Object> CacheHashMap() {
return new HashMap<>();
}
这里定义了个普通的不能在普通的缓存,看着没啥问题,只要是注入了这个Bean都会返回一个空的HashMap,接着往下看
@PostConstruct
public void setCacheUserMap() {
final List<Object> ObjectList = ObjectMapper.selectById(null);
if (!CollectionUtils.isEmpty(ObjectList)) {
CacheUserMap = ObjectList.stream().collect(Collectors.toMap(Object::getId,
Function.identity(), (k1, k2) -> k1));
}
}
这里本意是想通过Mapper去查找表中的数据,之后通过流的方式将查找List转为Map,作者原本也以为这样会将上边我们声明好的Bean,也就是我们想要缓存的HashMap初始化完成。当我去用这个Map查找数据的时候才发现,问题没有想象的那么简单!!!
Object object = ObjectMapper.get(“id”);
当想要将这个表中的数据构建到另一个实体类中并插入另一个表示,发现数据是null,原本以为是在查询数据做缓存的时候出错了,于是又仔细的看了下查询 ObjectMapper.selectById(null)的sql,没有发现问题,于是打了个log,查看Map里的数据,也没有发现问题!
正常的思路现在应该查这个缓存有没有被注入到所使用的类,但是在下纯纯的小白,宁愿以为是自己测试的时候用到的id没有被查到,也不愿相信是注入的Map居然是个null,在看自己库里id也没有问题后,才想起debug下发现注入的Map.size=0。(这个时候不死心的又打印了下缓存的Map,数据依旧完好无损)崩溃了!!!!家人们谁懂啊。。。。
千辛万苦终于把注意力放到缓存的初始化上了,因为之前没用过这种缓存方式,所以去求助了下无所不能的老师(GPT)发现了问题
你的@PostConstruct方法无法修改通过@Bean方法创建的bean,因为它们是两个完全独立的实例。@PostConstruct方法中的CacheUserMap 变量将是类的一个局部变量或成员变量,而不是Spring容器中的bean。
这是GPT给的答案,至此问题结束。
解决方案
将对缓存的初始化写到的定义Bean的方法里,这样在生成Bean的时候总得给我初始化了吧
@Bean
public Map<String, Object> CacheHashMap() {
final List<Object> ObjectList = ObjectMapper.selectById(null);
Map<String, Object> cacheHashMap= null;
if (!CollectionUtils.isEmpty(ObjectList)) {
cacheUserMap = ObjectList.stream().collect(Collectors.toMap(Object::getId,
Function.identity(), (k1, k2) -> k1));
}
return cacheUserMap;
}
终于舒服了
如有问题欢迎指正!