美文网首页
SpringBoot bean的自动注入问题

SpringBoot bean的自动注入问题

作者: 多关心老人 | 来源:发表于2020-07-15 20:16 被阅读0次

自定义了一个注解 @EnableRedis, 用户在yml中配置了redis地址,再加上这个注解就自动生成redisService,
如果用@EnableRedis(import=RedisConfiguration.class), 在RedisConfiguration里定义@Bean方法只对一个redisService有效,而我们需要多个redisService实例,不能在RedisConfiguration的afterProperties()里取applicationContext,因为这个时候RedisConfiguration还没实例化,由此可知:@Bean是先取方法生成BeanDefinition,在具体需要注入bean的时候才会调用@Bean方法,这个时候RedisConfiguration才实例化,@Bean方法才被调用。

有没有可能用ImportBeanDefinitionRegistrar来实现呢? ImportBeanDefinitionRegistrar是BeanDefinition的注册类,这个时候没有什么被实例化了,但有一个特殊:那就是Environment对象,通过Environment对象获取yml文件,然后再注册到RedisService的BeanDefinition到Registry即可。
网上搜了一圈,发现结果很少,也说明没人这么用,不过这个时候可以投机取巧一波。
代码如下:

@Import({RedisProperties.class, RedisRegistrar.class})
public @interface EnableRedis {

}
public class RedisRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {

    private static final Logger logger = LoggerFactory.getLogger(RedisRegistrar.class);

    private Environment environment;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //ImportBeanDefinition比实例化bean要早,这里不能注入
        final RedisProperties redisProperties = Binder.get(environment).bind("xxx.redis", RedisProperties.class).orElse(null);
        if (redisProperties == null) {
            return;
        }
        for (Map.Entry<String, RedisPoolConfig> entry : redisProperties.getInstances().entrySet()) {
            final GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
            genericBeanDefinition.setBeanClass(RedisServiceImpl.class);
            genericBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(entry.getValue());
            registry.registerBeanDefinition(entry.getKey(), genericBeanDefinition);
            logger.info("注册redis service成功: {}, host={}", entry.getKey(), entry.getValue().getHost());
        }
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}

相关文章

网友评论

      本文标题:SpringBoot bean的自动注入问题

      本文链接:https://www.haomeiwen.com/subject/bsgjhktx.html