Spring 3.1 Окружающая среда не работает с файлами свойств пользователя - программирование
Подтвердить что ты не робот

Spring 3.1 Окружающая среда не работает с файлами свойств пользователя

Я делаю это.

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(context);
xmlReader
        .loadBeanDefinitions(new ClassPathResource("SpringConfig.xml"));
PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer();
propertyHolder.setLocation(new ClassPathResource(
        "SpringConfig.properties"));
context.addBeanFactoryPostProcessor(propertyHolder);

    ......

context.refresh();

Теперь в моих файлах @Configuration свойства, присутствующие в моем SpringConfig.properties, не получаются, если я это делаю...

@Autowired
private Environment env
.....
env.getProperty("my.property")

Но я получаю это свойство, если я использую

@Value("${my.property}")
private String myProperty;

Я даже попытался добавить пару таких строк, но это бесполезно.

ConfigurableEnvironment env = new StandardEnvironment();
propertyHolder.setEnvironment(env);

Кто-нибудь знает, почему мои свойства не загружаются в среду? Спасибо.

4b9b3361

Ответ 1

PropertySourcesPlaceholderConfigurer напрямую считывает файлы свойств (как это было сделано PropertyPlaceholderConfigurer в Spring 3,0 раза), это просто постпроцессор, который не меняет способ использования свойств в контексте Spring - в этом случае свойства доступны только как bean.

Это PropertySourcesPlaceholderConfigurer, который использует среду, а не наоборот.

Структура источников ресурсов работает на уровне контекста приложения, в то время как конфигураторы заполнителей свойств предоставляют функциональные возможности для обработки заполнителей в определениях bean. Чтобы использовать абстракцию источника собственности, вы должны использовать @PropertySource аннотация, то есть украсить свой класс конфигурации чем-то вроде @PropertySource("classpath:SpringConfig.properties")

Я считаю, что вы можете сделать то же самое программно, то есть вы можете получить контейнер ConfigurableEnvironment до обновления контекста, изменить его MutablePropertySources (вам нужно сначала получить свойство AbstractApplicationContext environment через context.getEnvironment()) через getPropertySources().addFirst(new ResourcePropertySource(new ClassPathResource( "SpringConfig.properties"))); но маловероятно, что вы хотите сделать - если у вас уже есть аннотированный класс @Configuration, его украшение с @PropertySource("classpath:SpringConfig.properties") намного проще.

Что касается экземпляра PropertySourcesPlaceholderConfigurer - он будет автоматически извлекать источники свойств (поскольку он реализует EnvironmentAware) из контекста приложения, поэтому вам нужно просто зарегистрировать его экземпляр по умолчанию.

Примеры реализации пользовательского свойства свойства см. http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/

Ответ 2

Добавление локальных свойств в PropertySourcesPlaceholderConfigurer (с помощью setProperties() или setLocation()) не делает их доступными в Environment.

Фактически это работает обратным образом - Environment действует как первичный источник свойств (см. ConfigurableEnvironment) и PropertySourcesPlaceholderConfigurer может создавать свойства из Environment, доступные с помощью синтаксиса ${...}.

Ответ 3

Я сделал это за предложение @Boris.

    PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer();
    ConfigurableEnvironment env = new StandardEnvironment();
    env.getPropertySources().addFirst(
            new ResourcePropertySource(new ClassPathResource(
                    "SpringConfig.properties")));
    propertyHolder.setEnvironment(env);
    context.addBeanFactoryPostProcessor(propertyHolder);
            context.register(SpringConfig.class);
            context.refresh();

Теперь в классах @Configuration все свойства (включая мои собственные и системные свойства) можно разрешить с помощью @Value.

Но среда, которая получает @Autowired в класс @Configuration, имеет в ней только системные свойства, а не SpringConfig.properties, которые я установил, как указано выше. Но ясно, что перед тем, как называть context.refresh() выше, ConfigurableEnvironment также имеет мои свойства. Но после вызова context.refresh() мои свойства удаляются из среды, которая автоматически добавляется в @Configuration.

Я хочу иметь возможность использовать лучший синтаксис, env.getProperty( "my.property" ). Кто-нибудь знает, почему это так?

Ответ 4

Я загружаю 2 типа свойств, один из которых является свойством Environment, а другой - это контекст, который вы обычно получаете от let say servletContext.getServletContext(). Свойство моей среды определяется как: MOD_CONFIG_ROOT, который устанавливается отдельно на среду, тем самым разделяя детали местоположения файла уха, который содержит код. Здесь конфигурация. [Примечание: перед загрузкой сервлетов мне пришлось загружать файлы свойств, чтобы использовать свойства, используя ${someProperty}]

<bean id="externalProperties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>file:#{ systemEnvironment['MOD_CONFIG_ROOT']
                }#{servletContext.contextPath}/users.properties</value>
        </list>
    </property>
    <property name="searchSystemEnvironment" value="true" />
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" />
</bean>