3

I have Spring Boot Application and i have 3 property files: applications.properties, applications-dev.properties, applicaton-prod.properties. In applications.properties i specify that spring.profiles.active=prod. But I want to allow startup of application without prod profile(applicaton-prod.properties). It means that spring must startup application in dev profile(applications-dev.properties) automatically. How can i implement this? May be some MissingOnProfile annotation exist?) My task is to create different application behaviour based on application.properties files. Also i use @Profile annotation in each bean that depends on particular profile. All task is to create WebInstaller, and in finish step i will create application-prod.properties and by using RestartEndpoint i will restart application context and required beans from application-prod.properties will injected. But i need to make startup withoud application-prod.properties, but if this file exist i will startup in prod profile.

Abzelhan
  • 510
  • 1
  • 7
  • 26
  • “If prod profile is not exist”?? The point of spring profiles is you have one artifact you can promote from one env to the next, with all the profile configs present, using system properties or whatever to decide what profile is active in each env. There should not be a case where the prod profile properties file does not exist. – Nathan Hughes Aug 01 '18 at 02:31

4 Answers4

1

You are setting the profile information in the wrong place. The file application.properties contains properties that are common to all profiles (dev, stage, prod etc). For profiles you should, as you suggested, create a file of the name application-{profile}.properties which will override certain properties according to the environemnt defined by variable profile.

The usual approach is to pass this variables as parameters to the JVM (e.g:-Dprofile=dev), which you can set by modifying the run configuration of the servlet container if you are launching from an IDE. In case of a stand-alone tomcat you can pass this information through JAVA_OPTIONS variable found in the file setenv.sh.

NiVeR
  • 9,644
  • 4
  • 30
  • 35
  • 1
    i mean that i want to start my application in dev profile(using application-dev.properties) if application-prod.properties was not found. But by default my profile is prod(application-prod.properties). If i specify in application.properties that active profile is prod, and if application-prod.properties was not found in resources package my application failed to start. But i want to automaticaly switch to dev profile (application-dev.properties) if prod profile was not found. Because i want to dynamicaly add this file and restart all application in runtime. – Abzelhan Jul 30 '18 at 11:16
1

If you need to manually implement some kind of business logic with profiles, for example, specify that the active profile by default prod

  1. In application.properties define spring.profiles.active=prod

and for example if the application-prod.properties is missing, then the active profile should be the dev, you can implement this with EnvironmentPostProcessor:

Allows for customization of the application's Environment prior to the application context being refreshed

  1. Implement EnvironmentPostProcessor with your business logic

    public class ProfileResolverEnvironmentPostProcessor implements EnvironmentPostProcessor {
    
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        ClassPathResource prodPropertiesResource = new ClassPathResource("application-prod.properties");
        // if "application-prod.properties" missing and "prod" profile active
        if (!prodPropertiesResource.exists() && environment.acceptsProfiles("prod")) {
            environment.setActiveProfiles("dev");
            //environment.addActiveProfile("dev");
        }
    }
    
    }
    
  2. Register your EnvironmentPostProcessor implementation class in META-INF/spring.factories

org.springframework.boot.env.EnvironmentPostProcessor=\ com.example.ProfileResolverEnvironmentPostProcessor

Also, take look at Spring Boot documentation Customize the Environment

Additional:

Of course, you can specify beans that will be active if the profile is missing @Profile("!prod") But this does not work in your case if you define spring.profiles.active=prod, because the active profile prod will be in the Environment but it has nothing to do with the fact that the application-prod.properties is missing

tsarenkotxt
  • 3,231
  • 4
  • 22
  • 38
1

You can do this:

SpringApplication application = new SpringApplication(IdMatrixApplication.class);
File file = new File("src/main/resources/dev/application-prod.properties");
if (file.exists()) {
    application.setAdditionalProfiles("prod","dev");
}
application.run(args);
Pang
  • 9,564
  • 146
  • 81
  • 122
Alien Ware
  • 34
  • 3
0

If you want this then why you need application-dev.properties. Keep Your dev properties in application.properties. If profile set then applicatoin.properties value will be overwrite. Spring boot read both application.properties && application.yml and replace value if profile active

GolamMazid Sajib
  • 8,698
  • 6
  • 21
  • 39