복붙노트

[SPRING] 어노테이션을 사용하여 스프링 4의 특성 파일을 다시로드하는 방법은 무엇입니까?

SPRING

어노테이션을 사용하여 스프링 4의 특성 파일을 다시로드하는 방법은 무엇입니까?

나는 여러 가지 속성 파일을 사용하여 다른 사용자가 편집 한 내용을 가져 오는 간단한 응용 프로그램을 가지고 있습니다 (사이트에 대한 링크 등).

속성을로드하는 클래스는 다음과 같습니다.

@Configuration
@PropertySource("classpath:salestipsWhitelist.properties")
public class SalestipsWhitelist {

@Autowired
Environment env;

public Environment getEnv() {
    return env;
}

public void setEnv(Environment env) {
    this.env = env;
}

@Bean
   public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
      return new PropertySourcesPlaceholderConfigurer();
   }
}

속성 파일 중 일부 :

UPS_MPP_M_L=True
UPS_MPP_M_M=True
UPS_MPP_M_MP=True
UPS_MPP_M_S=True

이 잘 작동하지만 속성 파일을 변경하면 모든 변경 내용을 시각화하기 위해 응용 프로그램을 다시로드해야합니다.

가능한 경우, 클래스 경로 대신 디스크로 위치를 이동하여 주기적으로 또는 수동으로 다시로드 할 수 있습니까? 이 작업이 완료 / 업데이트되는 시점을 제어하고 싶기 때문에 변경시이 작업이 자동으로 수행되기를 원하지 않습니다.

해결법

  1. ==============================

    1.이것은 대우를 작동합니다. Java 7, Apache commons logging, Apache commons lang (v2.6) 및 Apache commons가 필요합니다. 구성 :

    이것은 대우를 작동합니다. Java 7, Apache commons logging, Apache commons lang (v2.6) 및 Apache commons가 필요합니다. 구성 :

    package corejava.reloadTest;
    
    import org.apache.commons.configuration.ConfigurationException;
    import org.apache.commons.configuration.PropertiesConfiguration;
    import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
    
    public class MyApplicationProperties {
        private static PropertiesConfiguration configuration = null;
    
        static {
            try {
                configuration = new PropertiesConfiguration("test.properties");
            } catch (ConfigurationException e) {
                e.printStackTrace();
            }
            configuration.setReloadingStrategy(new FileChangedReloadingStrategy());
        }
    
        public static synchronized String getProperty(final String key) {
            return (String) configuration.getProperty(key);
        }
    }
    

    다음을 사용하여 테스트하십시오.

    package corejava.reloadTest;
    
    public class TestReloading {
        public static void main(String[] args) {
            while (true) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(MyApplicationProperties.getProperty("key"));
            }
        }
    }
    

    test.properties를 변경할 때 출력은 다음과 같습니다 (test.props의 원래 내용은 key = value이었고 나중에 key = value1 중간 프로그램 실행으로 변경되었습니다).

    value
    value
    value
    value
    value
    Jan 17, 2015 2:05:26 PM org.apache.commons.configuration.PropertiesConfiguration reload
    INFO: Reloading configuration. URL is file:/D:/tools/workspace   /AutoReloadConfigUsingApacheCommons/resources/test.properties
    value1
    value1
    value1
    

    Groovy와 같은 DSL을 사용하여 공식 Spring Framework 참조 문서 Refreshable Bean을 고려할 수도 있습니다.

  2. ==============================

    2.새 속성을 다시로드하려면 PropertyPlaceholderConfigurer를 재정의해야합니다.

    새 속성을 다시로드하려면 PropertyPlaceholderConfigurer를 재정의해야합니다.

    프로퍼티를 포함하는 StringValueResolver를로드 가능하게 만들려면 processProperties 메소드를 다시 작성해야합니다. 이것은 내 코드이다.

    import java.io.IOException;
    import java.util.Properties;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
    import org.springframework.util.PropertyPlaceholderHelper;
    import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
    import org.springframework.util.StringValueResolver;
    
    
    public class ReloadablePropertyPlaceholderConfigurer 
                                        extends PropertyPlaceholderConfigurer {
    
        private ReloadablePlaceholderResolvingStringValueResolver reloadableValueResolver;
    
    
        public void reloadProperties() throws IOException {
            Properties props = mergeProperties();
            this.reloadableValueResolver.refreshProperties(props);
        }
    
    
        @Override
        protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
                throws BeansException {
            this.reloadableValueResolver = new ReloadablePlaceholderResolvingStringValueResolver(props);
            StringValueResolver valueResolver = this.reloadableValueResolver;
            this.doProcessProperties(beanFactoryToProcess, valueResolver);
        }
    
    
        private class ReloadablePlaceholderResolvingStringValueResolver 
                implements StringValueResolver {
    
            private final PropertyPlaceholderHelper helper;
            private final ReloadablePropertyPlaceholderConfigurerResolver resolver;
    
            public ReloadablePlaceholderResolvingStringValueResolver(Properties props) {
                this.helper = new PropertyPlaceholderHelper(placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders);
                this.resolver = new ReloadablePropertyPlaceholderConfigurerResolver(props);
            }
    
            @Override
            public String resolveStringValue(String strVal) throws BeansException {
                String value = this.helper.replacePlaceholders(strVal, this.resolver);
                return (value.equals(nullValue) ? null : value);
            }
    
            private void refreshProperties(Properties props){
                this.resolver.setProps(props);
            }
        }
    
        private class ReloadablePropertyPlaceholderConfigurerResolver 
                implements PlaceholderResolver {
    
            private Properties props;
            private ReloadablePropertyPlaceholderConfigurerResolver(Properties props) {
                this.props = props;
            }
    
            @Override
            public String resolvePlaceholder(String placeholderName) {
                return ReloadablePropertyPlaceholderConfigurer.this.resolvePlaceholder(placeholderName, props, SYSTEM_PROPERTIES_MODE_FALLBACK);
            }
    
            public void setProps(Properties props) {
                this.props = props;
            }
       }
    }
    

    다음은 해당 속성의 properties-config.xml .all을 런타임시 프로토 타입 bean으로 다시로드 할 수있는 구성입니다.

    <bean id="propertyConfigurer" class="com.cn21.mail189.analysis.commons.expand.ReloadablePropertyPlaceholderConfigurer">
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="locations">
            <list>
                <!-- database config -->
                <value>classpath:spring/dbconfig.properties</value>
                <!-- app config -->
                <value>classpath:spring/app.properties</value>
                <!-- some other config -->
                <value>classpath:xxxx.properties</value>
            </list>
        </property>
    </bean>`
    
  3. ==============================

    3.내부 applicationContext.xml

    내부 applicationContext.xml

    <bean id="beanId" class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy">
        <property name="refreshDelay" value="30000" /> <!-- 30 seconds -->
    </bean>
    <bean id="reloadableProperties" class="org.apache.commons.configuration.PropertiesConfiguration">
        <constructor-arg value="file:/web/${weblogic.Domain}/${weblogic.Name}/${app.Name}/reloadable_cfg/Reloadable.properties"/>
        <property name="reloadingStrategy" ref="propertiesReloadingStrategy"/>
    </bean>
    
  4. from https://stackoverflow.com/questions/26150527/how-can-i-reload-properties-file-in-spring-4-using-annotations by cc-by-sa and MIT license