복붙노트

[SPRING] Spring - bean 속성 값을 새로운 Property File 값으로 대체하기

SPRING

Spring - bean 속성 값을 새로운 Property File 값으로 대체하기

속성 파일이 있고 Spring 속성 자리 표시자를 사용하여 Spring bean에 값을 설정합니다. 이제,이 특성 파일은 런타임 중에 수정 될 수 있습니다. 이 새로 수정 된 속성 값으로 Spring 빈의 속성을 새로 고치는 방법이 있습니까? 특히 싱글 톤 콩이 많이 있습니까? 새 값으로 어떻게 새로 고칠 수 있습니까? 이미 이것에 대한 해결책이 있습니까? 아니면 맞춤 코딩을해야합니까? 아직 존재하지 않는다면 누군가가 이것을 달성하기위한 최선의 접근 방식을 제시 할 수 있습니까? 감사!

추신 : 내 응용 프로그램은 배치 응용 프로그램입니다. 저는 Spring 기반 Quartz 구성을 사용하여 배치를 예약합니다.

해결법

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

    1.나는 이것을 참고할 것이지만, 업데이트 된 대답은 분배 자 아래에있다.

    나는 이것을 참고할 것이지만, 업데이트 된 대답은 분배 자 아래에있다.

    잘 ConfigurableApplicationContext 인터페이스에는 원하는대로해야하는 refresh () 메소드가 포함되어 있지만 질문은 해당 메소드에 액세스하는 방법입니다. 어떤 방법 으로든, 당신은 ConfigurableApplicationContext 타입의 의존성을 가진 빈을 가지고 시작할 것입니다 :

    private ConfigurableApplicationContext context;
    @Autowired
    public void setContext(ConfigurableApplicationContext ctx){
        this.context = ctx;
    }
    

    이제 내가 제안 할 두 가지 기본 옵션은

    주석을 참조 : 전체 컨텍스트를 새로 고치는 것은 불가능하기 때문에 대체 전략은 속성 팩토리 빈을 만들어 다른 모든 빈에 삽입하는 것입니다.

    public class PropertiesFactoryBean implements FactoryBean<Properties>{
    
        public void setPropertiesResource(Resource propertiesResource){
            this.propertiesResource = propertiesResource;
        }
    
        private Properties value=null;
        long lastChange = -1L;
    
        private Resource propertiesResource;
    
        @Override
        public Properties getObject() throws Exception{
            synchronized(this){
                long resourceModification = propertiesResource.lastModified();
                if(resourceModification != lastChange){
                    Properties newProps = new Properties();
                    InputStream is = propertiesResource.getInputStream();
                    try{
                        newProps.load(is);
                    } catch(IOException e){
                        throw e;
                    } finally{
                        IOUtils.closeQuietly(is);
                    }
                    value=newProps;
                    lastChange= resourceModification;
                }
            }
            // you might want to return a defensive copy here
            return value;
        }
    
        @Override
        public Class<?> getObjectType(){
            return Properties.class;
        }
    
        @Override
        public boolean isSingleton(){
            return false;
        }
    
    }
    

    이 속성 빈을 다른 모든 빈에 삽입 할 수 있지만 항상 프로토 타입 범위를 사용하는 데주의해야합니다. 이것은 싱글 톤 빈 내부에서 특히 까다 롭습니다. 해결책은 여기에서 찾을 수 있습니다.

    룩업 메소드를 그 곳 곳곳에 삽입하고 싶지 않다면 PropertyProvider 빈을 다음과 같이 삽입 할 수 있습니다 :

    public class PropertiesProvider implements ApplicationContextAware{
    
        private String propertyBeanName;
        private ApplicationContext applicationContext;
    
        public void setPropertyBeanName(final String propertyBeanName){
            this.propertyBeanName = propertyBeanName;
        }
    
        @Override
        public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException{
            this.applicationContext = applicationContext;
        }
    
        public String getProperty(final String propertyName){
            return ((Properties) applicationContext.getBean(propertyBeanName)).getProperty(propertyName);
        }
    
    }
    
  2. from https://stackoverflow.com/questions/4084890/spring-replacing-the-bean-property-values-with-new-property-file-values by cc-by-sa and MIT license