2014-11-14 2 views
5

스프링 컨텍스트를 직접 사용하지 않고 @ConfigurationProperties으로 표시된 클래스를로드하는 방법이 있습니까? 기본적으로 스프링이하는 똑똑한 로직을 모두 재사용하고 싶지만 빈의 경우 스프링 라이프 사이클 외부에서 수동으로 인스턴스를 생성한다.스프링 AppContext없이 @ConfigurationProperties를 수동으로로드 할 수 있습니까?

나는 봄 (부팅)에서 즐겁게로드 빈을하고 난 내 다른 서비스 콩에이를 주입 할 수 있습니다

@ConfigurationProperties(prefix="my") 
public class MySettings { 
    String property1; 
    File property2; 
} 

더 많은 정보를 원하시면 http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-external-config-command-line-args

의 스프링 docco를 참조하지만 지금은 필요 (Hibernate에 의해) Spring 외부에서 생성 된 클래스로부터이 빈에 접근한다. 이 클래스는 앱 시작 프로세스의 초기에 만들어 지므로 Spring Boot는 고전적인 룩업 도우미 메서드 나 롤 - 내 자신의 정적 참조를 통해 응용 프로그램 컨텍스트를 사용할 수 없게 만든다. 일부 클래스에 있는가

MySettings mySettings = new MySettings(); 
SpringPropertyLoadingMagicClass loader = new SpringPropertyLoadingMagicClass(); 
loader.populatePropertyValues(mySettings); 

그리고 MySettings 등 명령 줄, 시스템 특성, app.properties에서로드 된 모든 값과 끝이 있습니다

그래서 내가 대신 뭔가를하고 싶어 이런 식으로하거나 응용 컨텍스트와 너무 얽혀있는 봄?

분명히 Properties 파일을 직접로드 할 수는 있지만 커맨드 라인 변수 (예 : --my.property1 = xxx) 또는 시스템 변수 또는 application.properties를 사용하여 Spring Boot 논리를 유지하려고합니다. yaml 파일뿐만 아니라 편안한 바인딩과 타입 변환 (예 : property2는 File)에 대한 로직을 포함하고 있기 때문에 Spring 컨텍스트에서 사용되는 것과 완전히 똑같이 작동한다.

꿈이 있습니까?

도움 주셔서 감사합니다.

답변

4

찾고있는 "마법"수업은 PropertiesConfigurationFactory입니다. 하지만 당신의 필요성에 의문을 제기 할 것입니다. 한 번 묶는 것만으로 스프링이 당신을 대신해 줄 수 있어야합니다. 라이프 사이클 문제가 있다면, 다른 것들을 무너 뜨릴 수 있기 때문에 그것을 해결하는 것이 더 낫습니다.

6

나는 "문제"가 동일했다. 다음은 SpringBoot 버전 1.3.xxx 및 1.4.1에서의 해결 방법입니다.

의 우리는 다음과 같은 YAML 설정 파일이 있다고 가정 해 봅시다 :

foo: 
    apis: 
     - 
     name: Happy Api 
     path: /happyApi.json?v=bar 
     - 
     name: Grumpy Api 
     path: /grumpyApi.json?v=grrr 

을 우리가 ConfigurationProperties을 다음 있습니다 :

@ConfigurationProperties(prefix = "foo") 
public class ApisProperties { 
    private List<ApiPath> apis = Lists.newArrayList(); 

    public ApisProperties() { 
    } 

    public List<ApiPath> getApis() { 
     return apis; 
    } 

    public static class ApiPath { 
     private String name; 
     private String path; 

     public String getName() { 
      return name; 
     } 

     public void setName(final String aName) { 
      name = aName; 
     } 

     public String getPath() { 
      return path; 
     } 

     public void setPath(final String aPath) { 
      path = aPath; 
     } 
    } 
} 

을 그리고, 봄 부팅 의 "마법"일을 프로그래밍 방식으로 (정적 메서드에서 일부 속성로드 등)을 수행 할 수 있습니다.

private static ApisProperties apiProperties() { 
    try { 
     ClassPathResource resource; 
     resource = new ClassPathResource("/config/application.yml"); 

     YamlPropertiesFactoryBean factoryBean; 
     factoryBean = new YamlPropertiesFactoryBean(); 
     factoryBean.setSingleton(true); // optional depends on your use-case 
     factoryBean.setResources(resource); 

     Properties properties; 
     properties = factoryBean.getObject(); 

     MutablePropertySources propertySources; 
     propertySources = new MutablePropertySources(); 
     propertySources.addLast(new PropertiesPropertySource("apis", properties)); 

     ApisProperties apisProperties; 
     apisProperties = new ApisProperties(); 

     PropertiesConfigurationFactory<ApisProperties> configurationFactory; 
     configurationFactory = new PropertiesConfigurationFactory<>(apisProperties); 
     configurationFactory.setPropertySources(propertySources); 
     configurationFactory.setTargetName("foo"); // it's the same prefix as the one defined in the @ConfigurationProperties 

     configurationFactory.bindPropertiesToTarget(); 
     return apisProperties; // apiProperties are fed with the values defined in the application.yaml 

    } catch (BindException e) { 
     throw new IllegalArgumentException(e); 

    } 
} 
+0

자세한 답변을 보내 주셔서 감사합니다. 그것은 나를 많이 도와줍니다. – Rib47

관련 문제