Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @运行时的值_Java_Spring - Fatal编程技术网

Java @运行时的值

Java @运行时的值,java,spring,Java,Spring,如何在运行时动态访问@Value机器 我原以为那个环境可能就是我要找的,但事实并非如此 @Component public class SpringConfiguration implements ConfigurationI { @Autowired private Provider<Environment> env; @Override public String get(String key) { try {

如何在运行时动态访问@Value机器

我原以为那个环境可能就是我要找的,但事实并非如此

@Component
public class SpringConfiguration implements ConfigurationI {
    @Autowired
    private Provider<Environment> env;

    @Override
    public String get(String key) {
        try {
            return env.get().getRequiredProperty(key);
        } catch (IllegalStateException e) {
            return null;
        }
    }
}

PropertyPlaceholder
和朋友不会将属性放入您的
环境中
(主要是因为向后兼容的原因)。相反,它们使用环境及其自身的内部
属性
对象来解析
@Value
属性,这些对象通常从类路径的属性文件中收集。因此,无法动态获取从PropertyPlaceholder加载的属性(即no
getProperty(String..)
)。 有些人创建自定义
PropertyPlaceholder
,公开存储属性(通过getter或其他方式),但我认为这完全破坏了Spring新的统一环境配置处理

您真正想要的可能是
@PropertySource
,它仍然非常糟糕,因为它不是动态的(因为它是一个注释,您无法更改文件从何处加载),但它会将属性加载到
环境中。我一直想向Spring Source提交关于这一混乱的问题

无论如何,您可以在此处查看我的解决方案:

基本上,您需要掌握
ConfigurableEnvironment
,并通过创建
PropertySources
将您的属性加载到其中。这方面的API非常强大,但不是很直观。您可以使用
ApplicationContextInitializers
获取有其自身恼人问题的
环境
(请参见链接),也可以执行我下面所做的操作

public class ConfigResourcesEnvironment implements 
    ResourceLoaderAware, EnvironmentAware, BeanDefinitionRegistryPostProcessor, EnvironmentPropertiesMapSupplier {

    private Environment environment;
    private Map<String, String> environmentPropertiesMap;

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        if (environment instanceof ConfigurableEnvironment) {
            ConfigurableEnvironment env = ((ConfigurableEnvironment) this.environment);
            List<PropertySource> propertySources;
            try {
                propertySources = loadPropertySources(); //Your custom method for propertysources
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            //Spring prefers primacy ordering so we reverse the order of the sources... You may not need to do this.
            reverse(propertySources);
            for (PropertySource rp : propertySources) {
                env.getPropertySources().addLast(rp);
            }
            environmentPropertiesMap = ImmutableMap.copyOf(environmentPropertiesToMap(env));
        }
        else {
            environmentPropertiesMap = ImmutableMap.of();
        }
    }


    public static Map<String,String> environmentPropertiesToMap(ConfigurableEnvironment e) {
        Map<String, String> properties = newLinkedHashMap();
        for (String n : propertyNames(e.getPropertySources())) {
            String v = e.getProperty(n);
            if (v != null)
                properties.put(n, v);
        }
        return properties;
    }

    public static Iterable<String> propertyNames(PropertySources propertySources) {
        LinkedHashSet<String> propertyNames = new LinkedHashSet<String>();
        for (PropertySource<?> p : propertySources) {
            if (p instanceof EnumerablePropertySource) {
                EnumerablePropertySource<?> e = (EnumerablePropertySource<?>) p;
                propertyNames.addAll(asList(e.getPropertyNames()));
            }
        }
        return propertyNames;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //NOOP
    }

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


    public Map<String, String> getEnvironmentPropertiesMap() {
        return environmentPropertiesMap;
    }

}

您的
属性PlaceHolderConfigure
是如何配置的?我在问题中添加了一个示例。不幸的是,我们的配置设置没有存储在属性文件中。如果我们把它们储存在别的东西里,这对我有帮助吗?我是否必须尝试将所有配置文件塞入属性中,以便spring能够提供它们?因此,您不应该使用
@PropertySource
,这正是我所抱怨的。看看我的另一个问题(链接)。您需要制作一个
BeanDefinitionRegistryPostProcessor
,并配置
环境
,您将在该环境中加载属性。我们有一个
ApplicationContextInitializer
,它从多个位置(文件、数据库等)检索属性每个寄存器都有一个
PropertySource
。工作非常好,因为它与Spring
环境
很好地集成,因此
@Value
之类的东西也能很好地集成。我在链接的问题中引用了我的问题与
ApplicationContextInitializer
。使用
ApplicationContextInitializer
时,您确实需要小心加载(包括日志记录)的内容,并且在没有意外预加载的情况下,无法使用许多spring内容。这是首选的规范方法(尽管Spring甚至没有将其用于@PropertySource..so…。@M.Deinum,只是为了与初始值设定项迭代更多的问题(慢慢记住)。您甚至不能使用SpringCore的大部分来设置
ApplicationContextInitializer
,因为您将启动Commons日志记录。这包括整个
资源
加载框架,请参阅。所以我可以想象,在db配置加载中,您一定使用了原始JDBC?
public class ConfigResourcesEnvironment implements 
    ResourceLoaderAware, EnvironmentAware, BeanDefinitionRegistryPostProcessor, EnvironmentPropertiesMapSupplier {

    private Environment environment;
    private Map<String, String> environmentPropertiesMap;

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        if (environment instanceof ConfigurableEnvironment) {
            ConfigurableEnvironment env = ((ConfigurableEnvironment) this.environment);
            List<PropertySource> propertySources;
            try {
                propertySources = loadPropertySources(); //Your custom method for propertysources
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            //Spring prefers primacy ordering so we reverse the order of the sources... You may not need to do this.
            reverse(propertySources);
            for (PropertySource rp : propertySources) {
                env.getPropertySources().addLast(rp);
            }
            environmentPropertiesMap = ImmutableMap.copyOf(environmentPropertiesToMap(env));
        }
        else {
            environmentPropertiesMap = ImmutableMap.of();
        }
    }


    public static Map<String,String> environmentPropertiesToMap(ConfigurableEnvironment e) {
        Map<String, String> properties = newLinkedHashMap();
        for (String n : propertyNames(e.getPropertySources())) {
            String v = e.getProperty(n);
            if (v != null)
                properties.put(n, v);
        }
        return properties;
    }

    public static Iterable<String> propertyNames(PropertySources propertySources) {
        LinkedHashSet<String> propertyNames = new LinkedHashSet<String>();
        for (PropertySource<?> p : propertySources) {
            if (p instanceof EnumerablePropertySource) {
                EnumerablePropertySource<?> e = (EnumerablePropertySource<?>) p;
                propertyNames.addAll(asList(e.getPropertyNames()));
            }
        }
        return propertyNames;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //NOOP
    }

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


    public Map<String, String> getEnvironmentPropertiesMap() {
        return environmentPropertiesMap;
    }

}
public interface EnvironmentPropertiesMapSupplier {
    public Map<String, String> getEnvironmentPropertiesMap();

}