21

How to create project architecture to support multiple envionment. Each environment will have different datasource from different property file like(dev-propertfile,test-propertyFil,Production-propertyfile) with help of spring's

org.springframework.core.env.Environment;
Santoshkumar Kalasa
  • 477
  • 1
  • 5
  • 15
  • just use @Profie("profileName") - look at javadocs. http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/boot-features-profiles.html – Balaji Krishnan Dec 21 '16 at 12:51

5 Answers5

18

I'll give step by step procedure for Spring boot applications.

  1. Inside /src/main/resources/application.properties mention spring.profiles.active=dev (or Prod)
  2. Create /src/main/resources/application-dev.properties and give your custom dev configurations here.
  3. Create /src/main/resources/application-prod.properties and give your custom prod configurations here.

Run.

USM
  • 580
  • 1
  • 10
  • 21
12

Put property file in same location as application.property and follow the naming convention application-{profile}.properties like application-dev.properties,application-test.properties, application-prod.properties

And in application.properties set spring.profiles.active=dev,test etc

CodeMatrix
  • 2,124
  • 1
  • 18
  • 30
Chandra
  • 1,722
  • 16
  • 19
4

For Spring Boot applications it will work easily even by using a YAML File

spring: 
  profiles: dev
  property: this is a dev env
---
spring: 
  profiles: prod
  property: this is a production env 
---

However, for a Spring MVC application, it needs more work. Have a look at this link

Basically, it involves 2 steps

  1. Get the Spring Profile within servlet context

If you have set the profile on the server and want it to retrieve it within your application you can use System.getProperty or System.getenv methods. Here is the code which fetches the profile and defaults it to a local profile, if no profile has been found.

private static final String SPRING_PROFILES_ACTIVE = "SPRING_PROFILES_ACTIVE";
String profile;

/**
 * In local system getProperty() returns the profile correctly, however in docker getenv() return profile correctly
 * */
protected void setSpringProfile(ServletContext servletContext) {
if(null!= System.getenv(SPRING_PROFILES_ACTIVE)){
    profile=System.getenv(SPRING_PROFILES_ACTIVE);
}else if(null!= System.getProperty(SPRING_PROFILES_ACTIVE)){
    profile=System.getProperty(SPRING_PROFILES_ACTIVE);
}else{
    profile="local";
}
log.info("***** Profile configured  is  ****** "+ profile);

servletContext.setInitParameter("spring.profiles.active", profile);
}
  1. To access the application-dev.properties, say now you will need to use @Profile("dev") at the class level

The following code will fetch the application-dev.properties and common.properties

@Configuration
@Profile("dev")
public class DevPropertyReader {


    @Bean
    public static PropertyPlaceholderConfigurer properties() {
    PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
    Resource[] resources = new ClassPathResource[] { new ClassPathResource("properties/common.properties"), new ClassPathResource("properties/application-dev.properties") };
    ppc.setLocations(resources);
    ppc.setIgnoreUnresolvablePlaceholders(true);
    return ppc;
    }
}

For accessing say application-prod.properties you have to use @Profile("prod") at the class level. More details can be found here

Abhishek Galoda
  • 2,753
  • 24
  • 38
2

Take a look at Spring Profile. You will define a set of profiles configurations, like Test, Dev, Production. And then, when you launch the application, you can define wich profile it should use.

Here are some tutorials of how to use.

And this guys had the same problem as yours: How to config @ComponentScan dynamic?

Community
  • 1
  • 1
Bruno
  • 2,889
  • 1
  • 18
  • 25
2

We wanted a way to load different properties from application-<your_env>.properties file depending on the environment (spring profile) in a Spring MVC project, so we implemented a configuration class something like this.

@Configuration
@PropertySource({ "classpath:application-${envTarget:dev}.properties" })
@Data
public class EnvironmentConfig {

    @Value("${files.s3.accessId:}")
    String s3AccessId;

    @Value("${files.s3.accessToken:}")
    String s3AccessToken;
    .
    .
    .
}

Then we loaded the EnvironmentConfig in the class where we needed to use it.

While running the application, you just need to pass the -DenvTarget=<your_env>, and it will pick up the application-<your_env>.properties file from src/resources folder of the project.

In the above code, it will load values from application-dev.properties files when no envTarget is specified.

Thanks to Karthikeyan Muthurangam for suggesting this clever solution.

sarthakgupta072
  • 451
  • 6
  • 13