为了账号安全,请及时绑定邮箱和手机立即绑定

春季:以Map或Properties对象的形式访问所有Environment属性

春季:以Map或Properties对象的形式访问所有Environment属性

牧羊人nacy 2019-11-29 10:13:12
我正在使用注释来配置我的spring环境,如下所示:@Configuration...@PropertySource("classpath:/config/default.properties")...public class GeneralApplicationConfiguration implements WebApplicationInitializer {    @Autowired    Environment env;}这导致我的财产default.properties成为的一部分Environment。我想在@PropertySource这里使用该机制,因为它已经可以根据环境设置(例如config_dir位置)通过多个后备层和不同的动态位置来重载属性。我只是剥离了后备,以使示例更容易。但是,我现在的问题是我想在中配置例如我的数据源属性default.properties。您可以将设置传递给数据源,而无需详细了解数据源期望使用什么设置Properties p = ...datasource.setProperties(p);但是,问题是,Environment对象既不是Properties对象,也不是对象,也不是Map任何可比较的对象。从我的角度来看,这是根本不可能的访问环境的所有值,因为没有keySet或iterator方法或任何可比性。Properties p <=== Environment env?我想念什么吗?是否可以通过Environment某种方式访问对象的所有条目?如果是,我可以将条目映射到Map或Properties对象,甚至可以通过前缀过滤或映射它们-将子集创建为标准Java Map...这就是我想要做的。有什么建议么?
查看完整描述

3 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

这是一个老问题,但是公认的答案有一个严重的缺陷。如果Spring Environment对象包含任何替代值(如Externalized Configuration中所述),则不能保证它产生的属性值映射将与Environment对象返回的属性值匹配。我发现,简单地通过迭代PropertySource的S- Environment没有,其实给任何覆盖值。相反,它产生了原始值,该值应该被覆盖。


这是一个更好的解决方案。本品采用EnumerablePropertySource的S- Environment迭代通过已知的属性名称,但随后读取实际值了真正的春天的环境。这样可以保证该值是Spring实际解析的值,包括所有覆盖的值。


Properties props = new Properties();

MutablePropertySources propSrcs = ((AbstractEnvironment) springEnv).getPropertySources();

StreamSupport.stream(propSrcs.spliterator(), false)

        .filter(ps -> ps instanceof EnumerablePropertySource)

        .map(ps -> ((EnumerablePropertySource) ps).getPropertyNames())

        .flatMap(Arrays::<String>stream)

        .forEach(propName -> props.setProperty(propName, springEnv.getProperty(propName)));


查看完整回答
反对 回复 2019-11-29
  • 3 回答
  • 0 关注
  • 918 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信