0

I have a problem with Spring Boot Configurations and Injections. I had the following class:

@Configuration
@ConfigurationProperties("app")
public class AppConfig() {
    public void A() { ...};
}

And everything works fine with it. Now I have to split up this class in dependence of the OS and my idea was it, to do this like this:

public interface AppConfig() {

    void A();
}

public WindowsAppConfig implements AppConfig() {

    public void A()  { //Windows implementation};
}

public LinuxAppConfig implements AppConfig() {
    public void A() { //Linux implementation };
}

@Configuration
public class AppConfigFactory() {
    
    @Bean
    public AppConfig getAppConfig() {
    if(...) { 
        return new WindowsAppConfig;
    } else {
        return new LinuxAppConfig;
    }
}

public class AppStart() {

    @Autowired
    private AppConfig appConfig;
}

Now I get an IllegalStateException like this:

java.lang.IllegalStateException: No ConfigurationProperties annotation found on  'appconfig.AppConfig'.

How and where I can add the ConfigurationProperties correctly?

Roland Weisleder
  • 9,668
  • 7
  • 37
  • 59
elPaso
  • 25
  • 4

1 Answers1

0

I think it may better to use @Conditional to change implementation for OS like this post. Spring expression to evaluate OS

But I write example based on your initial post.

@Component
public class TestConfig {

    private final AppConfig appConfig;

    public TestConfig(AppConfig appConfig){
        this.appConfig = appConfig;
    }

    @PostConstruct
    public void init(){
        appConfig.A();
    }
}

interface AppConfig {

    void A();

    void setFoo(String foo);

    String getFoo();
}

class WindowsAppConfig implements AppConfig {

    private String foo;

    public void A() {
        System.out.println("Windows config");
    }

    @Override
    public void setFoo(String foo) {
        this.foo = foo;
    }

    @Override
    public String getFoo() {
        return foo;
    }
}

class LinuxAppConfig implements AppConfig {

    private String foo;

    public void A() {
        System.out.println("Linux config");
    }

    @Override
    public void setFoo(String foo) {
        this.foo = foo;
    }

    @Override
    public String getFoo() {
        return foo;
    }
}

@Configuration
@ConfigurationProperties("factory")
class AppConfigFactory {

    private boolean useWin ;

    @Bean
    @ConfigurationProperties("app")
    public AppConfig getAppConfig() {
        if (useWin) {
            return new WindowsAppConfig();
        } else {
            return new LinuxAppConfig();
        }
    }

    public boolean isUseWin() {
        return useWin;
    }

    public void setUseWin(boolean useWin) {
        this.useWin = useWin;
    }
}

Following is application.yml sample

app:
  foo: Foo

factory:
  use-win: true
Kaz
  • 358
  • 3
  • 11