Advanced auto wiring in Spring

Many times we face situation in which we want certain things configured as per the environment or on certain complex condition. Spring provides great features in easing the developer job for this use-case. We will look at such a scenario along with solution spring provides in this case.

Spring autowiring

Environments and Profiles:

One of the most challenging part of any application is to transitioning of the software into different environments (DEV, QA, STG, PROD). Certain choices that we make in DEV environments are not suitable when we run the same setup on PROD environment.
Consider basic use of using different database as per the deployment environment.

for DEV we might setup a datasource something like below:
@Bean(destroyMethod = "shutdown")
public DataSource dataSource() {
 return new EmbeddedDatabaseBuilder()
  .addScript("classpath:devCreate.sql")
  .addScript("classpath:devInsert.sql")
  .build();
}
but when we will go on PROD environment, this configuration of embedded database is not useful. In that case our database will be managed by highly secure environment deployed on separate sever and managed by database administrator.
So for your PROD environment your datasource configuration might look like below:
@Bean(destroyMethod = "shutdown")
public DataSource dataSource() {
 DriverManagerDataSource dataSource = new DriverManagerDataSource();
 dataSource.setDriverClassName("com.mysql.jdbc.Driver");
 dataSource.setUrl("jdbc:mysql://mydevdb.com:3306/mydb");
 dataSource.setUsername("dbUserName");
 dataSource.setPassword("dbPassword");
 return dataSource;
}
It is clear that both of above environment produce the bean of type javax.sql.DataSource, but the way it does that, is different. When we want to move our application to higher deployment environment, then we will have to build a new WAR/JAR and then deploy it. The process is cumbersome. To fix that we can use profiles feature provided by spring.

Using Profiles:

You can have both above beans defined in same java configuration file as below:
@Profile("dev")
@Bean(destroyMethod = "shutdown")
public DataSource dataSource() {
 return new EmbeddedDatabaseBuilder()
  .addScript("classpath:devCreate.sql")
  .addScript("classpath:devInsert.sql")
  .build();
}

@Profile("prod")
@Bean
public DataSource dataSource() {
 DriverManagerDataSource dataSource = new DriverManagerDataSource();
 dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
 dataSource.setUrl("jdbc:mysql://mydevdb.com:3306/mydb");
 dataSource.setUsername("dbUserName");
 dataSource.setPassword("dbPassword");
 return dataSource;
}

You can define the annotation on class-level as well if you have different java configuration class for different environment.

Using Old xml based configuration:?😓 Dont worry !

You can activate profiles in xml configuration as below:
<beans profile="dev" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="
    http://www.springframework.org/schema/jdbc
    http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

  <jdbc:embedded-database id="dataSource">
    <jdbc:script location="classpath:devCreate.sql"/>
    <jdbc:script location="classpath:devInsert.sql"/>
  </jdbc:embedded-database>
</beans>
<beans profile="prod"> 
 <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="dbUserName"/>
        <property name="password" value="dbPassword"/>
        <property name="”url”" value="jdbc:mysql://mydevdb.com:3306/mydb"/>
</bean>
</beans>

Activate Profiles:

Once you have defined the beans using @Profile annotation you need to activate the profile to create and register those beans with ApplicationContext.
  1. spring.profiles.active: This property is used to set the active profiles on the current configuration. You can set the property by many ways:
    //setting parameter on context directly
    AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
            context.getEnvironment().setActiveProfiles("DEV" )
    
    // OR using java system properties
    java -jar jarName -Dspring.active.profiles=DEV
    
    // OR as servletContext parameter
    servletContext.setInitParameter("spring.profiles.active", "DEV");
  2. spring.profiles.default:
    Any bean that does not specify a profile belongs to "default" profile.
    Spring also provides a way to set the default profile when no other profile is active – by using the "spring.profiles.default" property.

Cookies Consent

This website uses cookies to offer you a better Browsing Experience. By using our website, You agree to the use of Cookies

Privacy Policy