不被spring管理的类依赖于spring管理的bean,如何让spring管理的bean及早初始化?

我要配置mybatis二级缓存为redis
因为需要注入redis的ip port username等等
我需要构建JedisPoolConfig的bean,然后得到JedisConnectionFactory的bean
而我定义的redis缓存如下

final class MybatisCache implements Cache {
private String id
private final ReadWriteLock readWriteLock = new DummyReadWriteLock()
private RedisTemplate<String, Object> redisTemplate
private HashOperations<String, Object, Object> hashOperations
private static JedisConnectionFactory jedisConnectionFactory

static setJedisConnectionFactory(JedisConnectionFactory factory){
    jedisConnectionFactory = factory
}

MybatisCache(String id) {
    if (id == null) {
        throw new IllegalArgumentException("Cache instances require an ID")
    } else {
        this.id = id
        redisTemplate = new RedisTemplate()
        redisTemplate.setConnectionFactory(jedisConnectionFactory)
        redisTemplate.setKeySerializer(new StringRedisSerializer())
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer())
        redisTemplate.setHashKeySerializer(new GenericJackson2JsonRedisSerializer())
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer())
        redisTemplate.afterPropertiesSet()
        hashOperations = redisTemplate.opsForHash()
    }
        。。。
}

但是MybatisCache不是spring的bean,所以如果这个类被加载时JedisPoolConfig,JedisConnectionFactory等bean还没有初始化的话,就得到null,有没有什么办法让JedisPoolConfig,JedisConnectionFactory等bean能保证在MybatisCache被使用期前初始化?

阅读 3.1k
4 个回答

1、要么把你所谓的那些不被spring管理的类依赖于spring管理的bean,配置为Spring管理的Bean,这样你就可以用Spring的IOC注入了,这种方式更简单,理论上任何Bean,都可以被Spring管理。
2、如果你不想让Spring管理,那你在你代码里面,先把Spring初始化,这个应该好办的,初始化完成后,代码里可以监听Spring初始化完成的事件的,得到以后,你拿到Spring工厂,自己做IOC,做自己的类的初始化。

你可以注解MybatisCache成为spring的bean,如果你有其他理由不这样做的话,也可以在MybatisCache的构造方法中调用spring创建JedisPoolConfig,JedisConnectionFactory的实例。

  1. 把这个东西做成spring的bean
  2. 在依赖的bean里初始化这个bean

确实有一些场景,例如引用第三方包的时候,存在提主说的这种第三方包中的对象无法通过Spring去注入的情况,可以在spring boot的启动main方法中这样做:

ConfigurableApplicationContext context = SpringApplication.run(YourApp.class, args);
ObjectThatCannotBeManagedBySpring.setObjectA(context.getBean(ClassA.class)); 

其中ObjectThatCannotBeManagedBySpring代表没有办法被Spring实例化的对象(在题主的问题中就是Mybatiscache对象),ClassA代表是被依赖的可以被Spring实例化的类(在问题中对应JedisConnectionFactory对象,set方法对应setJedisConnectionFactory)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题