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

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

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()

  }

}

项目开发中经常需要加载外部资源文件谨备, @PropertySource 给我们提码返供了极大的便利。但是 @PropertySource 目前不支持 yml 文件的解析,由于 yml 结构清晰等优点,使用频率也会越来越高。

注意 factory 这个属性,作为解析资源文件的工厂类,默认实现是 DefaultPropertySourceFactory :

我们只需要自定义一个工厂类 ResourceFactory ,继承这个 default 工厂,重写 createPropertySource 即可:

新建测试文迟晌饥件 sso.yml:

结合 @ConfigurationProperties 实现 sso 配置类注入:

test 方法作为测试输出当前信息:

我们在做微服务项目时候会引入spring cloud框架,对于配置文件我们就会通过spring cloud config来配置,实现线上环境动态修改配置文件属性而不需要重新打jar 包。 但行猛如是对于单体的spring boot工程,我们又希望可以在生产环境中方案修改配置文件属性。

通过引入外部配置文件,应用启动时候设置配置文件的自动加载

1: 在单体工程的root目录下添加一个config目录,然后新建我们的properties, 如:jdbc-db.properties, redis.properties

2: 然后在我们的application启动类上添加@propertySources注解引入我们的外部文件

注意:因为PropertySources 默认只解析.properties文件档启,如果要解析yml文件,需要指定factory只需要实现org.springframework.core下的 PropertySourceFactory 接口就OK了。

简单的properties配置文件知笑只需要按如下方式配置即可

只需要1,2步骤就可以完成外部文件的加载,如果涉及到线上修改配置就只需要手动修改配置文件,重新启动应用即可生效。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/8217784.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存