【错题集1】@Bean和@PostConstruct能一起组合嘛?

@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;
    }

终于舒服了
如有问题欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值