Home > database >  How to include multiple @SpringBootApplication by @Profile?
How to include multiple @SpringBootApplication by @Profile?

Time:07-21

I would like to define multiple @SpringBootApplication configurations that should load different packages. So that I can only load certain parts of the application, depending on the -Dspring.profiles.active= property.

Eg, the following MyApp1 startup class should only auto load classes under com.myapp.config1 subpackages:

package com.myapp.config1

@SpringBootApplication
@Profile("app1")
public class MyApp1 {
  public static void main(String[] args) {
    SpringApplication.run(MyApp1.class, args);
  }
}

And another package aside:

package com.myapp.config2

@SpringBootApplication
@Profile("app2")
public class MyApp2 {
  public static void main(String[] args) {
    SpringApplication.run(MyApp2.class, args);
  }
}

Problem: I cannot have multiple main() in multiple classes, as I lateron want to run my app with mvn spring-boot:run. How could this be solved?

CodePudding user response:

If you want to load different packages depending on a profile you should instead define different configuration classes that are annotated with different @ComponentScan annotations.

@Configuration
@ComponentScan("bar.foo")
@Profile("app1")
public class loadApp2 {

}

@Configuration
@ComponentScan("foo.bar")
@Profile("app2")
public class loadApp1 {

}

This is actually the recommended way of setting up configuration and is called "slicing" and is documented in the spring boot docs

CodePudding user response:

If I understand your question properly, then you want to run different class based on profiles, then you can have profile like below:

@Configuration
@ComponentScan("abc")
@Profile("app1")
public class MyApp1 {
  //
}

@Configuration
@ComponentScan("xyz")
@Profile("app2")
public class MyApp2 {
  //
}

Now in your SpringBootapplication:

@SpringBootApplication
  public class SpringApp {
    
    @Autowired
    Environment env;
    
      public static void main(String[] args) {
        if (Arrays.asList(env.getActiveProfiles()).contains("app1"))
          SpringApplication.run(MyApp1.class, args);
       else 
         SpringApplication.run(MyApp2.class, args);
      }
    }

CodePudding user response:

Could solve it as follows.

package com.myapp
@SpringBootApplication(scanBasePackages = "com.myapp.config")
public class MyApp {
  public static void main(String[] args) {
    SpringApplication.run(MyApp.class, args);
  }
}

Which loads config:

package com.myapp.config

@Configuration
@Profile("app1")
@ComponentScan(basePackages = "com.myapp.app1")
public class App1Config {
    //only load classes from app1 package
}

@Configuration
@Profile("app2")
@ComponentScan(basePackages = "com.myapp.app2")
public class App2Config {
    //only load classes from app2 package
}

CodePudding user response:

You could specify the main class in the spring boot plugin configuration. I am not sure if you are using gradle or maven... so cant tell you the exact config.

https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/#goals-repackage-parameters-details-mainClass

  • Related