2014-10-01 6 views
26

스프링 부트의 @ConfigurationProperties 주석으로 불변 (최종) 필드를 가질 수 있습니까? 예변경 불가능한 @ConfigurationProperties

@ConfigurationProperties(prefix = "example") 
public final class MyProps { 

    private final String neededProperty; 

    public MyProps(String neededProperty) { 
    this.neededProperty = neededProperty; 
    } 

    public String getNeededProperty() { .. } 
} 

접근 아래 지금까지 시도했다 : 빈과 neededProperty 인수

  • 로 :

      • 두 개의 생성자를 제공하는 두 개의 생성자 으로 MyProps 클래스의 @Bean 만들기 콩이 만들어집니다 new MyProps()
      • 필드에있는 결과 MyProps 빈을 제공하기 위해 @ComponentScan@Component를 사용 null
    1. . 각 final이 아닌 필드 게터/세터를 제공함으로써>NoSuchMethodException: MyProps.<init>()

    만 나는 그것을 작업 가지고 방법입니다 - BeanInstantiationException에서

    • 결과.

  • +1

    을 도움이되기를 바랍니다

    을 줄일 수 하려고하면 상자 밖으로 작동하지 않습니다. – geoand

    +0

    슬픈 일입니다.물론, 나는 @Value 주석으로 생성자 매개 변수를 사용하여 평범한 Spring으로 언제나 그것을 할 수있다. 그러나 스프링 부트가 이것을 지원한다면 좋을 것입니다. – RJo

    +0

    나는 소스 코드에서 작은 부분을 차지했지만, 당신이 묻고있는 것과 같은 것을 지원하는 것은 쉽지 않다. 당연히 나는 스프링 내부에 대한 전문가가 아니기 때문에 무언가를 놓치고있는 것일 수도 있습니다. – geoand

    답변

    10

    나는이 문제를 매우 자주 해결해야하고 나는 조금 다른 접근법을 사용하여 어떤 클래스에서 final 변수를 사용할 수 있습니다.

    먼저 모든 구성을 한 곳 (클래스)에 유지합니다 (예 : ApplicationProperties). 이 클래스에는 특정 접두사가있는 @ConfigurationProperties 주석이 있습니다. 또한 구성 클래스 (또는 기본 클래스)에 대한 @EnableConfigurationProperties 주석에 나열되어 있습니다.

    그런 다음 생성자 인수로 ApplicationProperties을 제공하고 생성자 내의 final 필드에 할당을 수행합니다.

    예 :

    홈페이지 클래스 :

    @SpringBootApplication 
    @EnableConfigurationProperties(ApplicationProperties.class) 
    public class Application { 
        public static void main(String... args) throws Exception { 
         SpringApplication.run(Application.class, args); 
        } 
    } 
    

    ApplicationProperties 클래스

    @ConfigurationProperties(prefix = "myapp") 
    public class ApplicationProperties { 
    
        private String someProperty; 
    
        // ... other properties and getters 
    
        public String getSomeProperty() { 
         return someProperty; 
        } 
    } 
    

    그리고있는 클래스 최종 속성

    @Service 
    public class SomeImplementation implements SomeInterface { 
        private final String someProperty; 
    
        @Autowired 
        public SomeImplementation(ApplicationProperties properties) { 
         this.someProperty = properties.getSomeProperty(); 
        } 
    
        // ... other methods/properties 
    } 
    

    이 접근 방식은 여러 가지 이유로 선호됩니다. 생성자에서 더 많은 속성을 설정해야하는 경우, 항상 하나의 인수 (내 경우에는 ApplicationProperties)가 있으므로 생성자 인수 목록은 "거대한"것이 아닙니다. 더 final 속성을 추가 할 필요가있는 경우, 내 생성자는 동일 (단 하나 개의 인수를) 유지 - 당신이 무엇인지 등 다른 변화의 수 나는 그것이 제가 알기로

    +1

    대용량의 보일러 플레이트 대 @Value 사용 –

    +0

    이것은 [tag : Java]입니다. 더 많은 상용구는 더 나은 코드를 의미합니다. – Clijsters

    +0

    @Clijsters 당신이 우스꽝 스러울지라도 솔직하게 말할 수는 없지만 그 말이 맞지는 않습니다. –

    관련 문제