Spring注解使用yml注入属性出现的问题整理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring注解使用yml注入属性出现的问题整理相关的知识,希望对你有一定的参考价值。

参考技术A 1:在某个标注@Configuration的bean中使用@Value("$task.runServer.enable:false")试图注入属性,发现没有效果,但是切换成@Value("#taskRunServerConfig.enable")之后,发现是好用的;

分析原因:原因1@Configuration默认使用application.yml中读配置属性,而本项目的属性是来自于taskconfig.yml自定义文件,所以注入失败。原因2就是使用的这个类是一个Component,但是加载顺醋可能晚于InitConfig这个bean(而initconfig加载以后才能设置从taskconfig.yml加载属性配置,可使用@DependsOn("propertySourcesPlaceholderConfigurer")设置在其之后加载。)

解决方案是:一个是在@Configuration的这配置中加入注解,切换属性加载位置,@PropertySource(value = "classpath:taskconfig.yml", ignoreResourceNotFound = true , factory = MixPropertySourceFactory.class),因为PropertySource注解默认不支持yml,因此使用了自定义的MixPropertySourceFactory。或者使用@DependsOn("propertySourcesPlaceholderConfigurer")设置在其之后加载。再就是推荐使用 @Value("#taskRunServerConfig.enable")这种方式,通过bean统一来注入。

2:在标注@Configuration的主配置类中,使用@Value("$task.runServer.enable:false")这种方式是好用的,而使用@Value("#taskRunServerConfig.enable")则是不好用的。分析原因,发现。这个类中taskRunServerConfig依赖于此Configuration配置的一个bean,因此taskRunServerConfig这个bean晚于本配置类创建,因此taskRunServerConfig的bean属性注入失败(值不是yml中的)。而为啥@Value("$task.runServer.enable:false")这种方式好用呢?因为之前写了个InitConfig,其中使用YamlPropertiesFactoryBean的方式加载了taskconfig.yml配置文件,并且有@Import(InitConfig.class, TaskCommonRedisConfig.class)引入了这个配置,因此是好用的。为了统一使用bean方式引入配置,作出了如下修改:

2.1TaskRunServerConfig配置类使用@Bean的方式在主配置类中配置

@Bean

@ConfigurationProperties(prefix="task.runServer")

TaskRunServerConfig taskRunServerConfig()



TaskRunServerConfig config = new TaskRunServerConfig();

return config;



2.2

主配置类中引入@PropertySource(value = "classpath:taskconfig.yml", ignoreResourceNotFound = true , factory = MixPropertySourceFactory.class),那么配置会从自定义的taskconfig.yml文件中加载配置属性。

2.3

TaskRunServerConfig 中原来Autowried了一个主配置类中创建的bean,此时不采用绑定方式,而是在创建另一个bean的时候,调用TaskRunServerConfig的set方法去设置自己进去。不然会出现循环依赖。

2.4

主配置类型使用@Bean创建bean的时候,使用参数绑定的方式传入TaskRunServerConfig ,例如@Bean(name="taskInstanceRunManager", initMethod="start", destroyMethod="stop")

public TaskInstanceRunManager taskInstanceRunManager( TaskRunServerConfig taskRunServerConfig )

#

@Configuration

public class InitConfig



// @Bean

// public static PropertySourcesPlaceholderConfigurer properties()

//

//       PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();

//       YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();

//       yaml.setResources(new ClassPathResource("taskconfig.yml"));

//       propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());

//       return propertySourcesPlaceholderConfigurer;

//



#

public class MixPropertySourceFactory extends DefaultPropertySourceFactory

  @Override

  public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException

    String sourceName = name != null ? name : resource.getResource().getFilename();

    if (!resource.getResource().exists())

      return new PropertiesPropertySource(sourceName, new Properties());

    else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml"))

      Properties propertiesFromYaml = loadYml(resource);

      return new PropertiesPropertySource(sourceName, propertiesFromYaml);

    else

      return super.createPropertySource(name, resource);

   

 

  private Properties loadYml(EncodedResource resource) throws IOException

    YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();

    factory.setResources(resource.getResource());

    factory.afterPropertiesSet();

    return factory.getObject();

 

以上是关于Spring注解使用yml注入属性出现的问题整理的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 项目属性配置

springboot 配置的参数注入

Spring之IOC-注解方式

Spring学习一(依赖注入/Bean/注解等)

spring使用注解,自动扫描类的时候怎么注入

Spring小指南(Spring笔记整理-上)