springspring-boot

@ConfigurationProperties and duplicated prefix


Since @ConfigurationProperties does not allow duplicated prefix. How to make the follow case to work? The following code will throw error as duplicated prefix is not allowed

abstract class Base {
    var key: String

    abstract fun execute()
}



@ConfigurationProperties(prefix = "test")
fun getA() : Base {
    return object : Base {
        override fun execute() {
           // do something
        }
    }
}
 
@ConfigurationProperties(prefix = "test")
fun getB() : Base {
    return object : Base {
        override fun execute() {
           // do something else
        }
    }
}

properties.yml

test:
   key: value

Note the Base class is in a lib so not possible to change


Solution

  • First, you should create a @ConfigurationProperties class that defines all of the properties that you want to be able to configure on an instance of Base. Here's an example with properties one and two:

    package com.example;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties("test")
    public class TestProperties {
        
        private String one;
        
        private String two;
    
        public String getOne() {
            return one;
        }
    
        public void setOne(String one) {
            this.one = one;
        }
    
        public String getTwo() {
            return two;
        }
    
        public void setTwo(String two) {
            this.two = two;
        }
    
    }
    

    You then enable this properties class using @EnableConfigurationProperties and use the instance of it that Spring Boot creates to configure your sub-classes of Base:

    package com.example;
    
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration(proxyBeanMethods = false)
    @EnableConfigurationProperties(TestProperties.class)
    class ExampleConfiguration {
        
        @Bean
        Base getA(TestProperties properties) {
            Base a = new Base() {
                void execute() {
                    
                }
            };
            configure(a, properties);
            return a;
        }
        
        @Bean
        Base getB(TestProperties properties) {
            Base b = new Base() {
                void execute() {
                    
                }
            };
            configure(b, properties);
            return b;
        }
        
        private void configure(Base base, TestProperties properties) {
            base.setOne(properties.getOne());
            base.setTwo(properties.getTwo());
        }
    
    }