Spring @Configuration Annotation

By Arvind Rai, June 05, 2019
Spring @Configuration is annotated at class level to indicate that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime. @Configuration can be used with other Spring annotations. Find some of the annotations that are used in conjunction with @Configuration.
@PropertySource: Provides a convenient and declarative mechanism for adding a property source to Spring's Environment.
@Profile: Enables the configuration classes to be registered when specified profiles are active.
@EnableScheduling: Enables Spring's scheduled task execution capability.
@ImportResource: Indicates one or more resources containing bean definitions to import.
@Import: Indicates one or more @Configuration classes to import.
@ComponentScan: Configures component scanning directives for use with @Configuration classes.
@EnableWebMvc: Provides Spring MVC configuration.
@EnableWebSecurity: Provides Spring Security configuration.

Here on this page we will provide some examples to create and use @Configuration classes.

Technologies Used

Find the technologies being used in our example.
1. Java 11
2. Spring 5.1.6.RELEASE
3. Spring Boot 2.1.4.RELEASE
4. Maven 3.5.2
5. Eclipse 2018-09

Using @Configuration

We will create a class annotated with @Configuration and we will create a bean inside this class using @Bean annotation.
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
	 @Bean
	 public User getUser() {
		 return new User("Mahesh");
	 }
} 
In the above JavaConfig, we have created a User class bean. Find this class.
User.java
package com.concretepage;
public class User {
	private String userName;
	public User(String userName) {
		this.userName = userName;
		System.out.println("--- Initializing User ---");
	}
	public String getUserName() {
		return userName;
	}
} 
We can access @Configuration classes using AnnotationConfigApplicationContext or via Spring <beans> XML.

1. Access @Configuration classes using AnnotationConfigApplicationContext:
To register our configuration classes annotated with @Configuration, we can use AnnotationConfigApplicationContext that registers classes using constructor, register() or scan() method. In constructor and register(), we specify configuration classes, and in scan() we specify package name. scan() will scan specified package and its sub-packages.
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
		User user = ctx.getBean(User.class);
		System.out.println("User name: " + user.getUserName());
		ctx.registerShutdownHook();
		ctx.close();		
	}
} 
Output
--- Initializing User ---
User name: Mahesh 

2. Access @Configuration classes via Spring <beans> XML:
@Configuration classes can be registered via Spring <beans> XML as following.
app-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">

	<context:annotation-config/>
        <bean class="com.concretepage.AppConfig"/>
</beans> 
MySpringAppWithXML.java
package com.concretepage;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MySpringAppWithXML {
	public static void main(String[] args) {
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("app-config.xml");
		User user = ctx.getBean(User.class);
		System.out.println("User name: " + user.getUserName());
		ctx.registerShutdownHook();
		ctx.close();		
	}
} 

@Configuration + @Autowired

We can inject externalized values and other beans using @Autowired inside @Configuration classes. Here in our example we will inject Spring Environment.
AppConfig.java
package com.concretepage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
public class AppConfig {
	 @Autowired Environment env;	
	 
	 @Bean
	 public User getUser() {
		 System.out.println(env.getProperty("java.home"));
		 return new User("Mahesh");
	 }
} 

@Configuration + @PropertySource

@PropertySource provides a convenient and declarative mechanism for adding a property source to Spring's Environment. To read properties from property file inside @Configuration classes, we use @PropertySource annotation. Here in our example we will read a property file using @PropertySource and read values using @Value annotation.
Find the property file of our example.
myproject.properties
cp.user.country= USA
cp.user.role= ADMIN 
Find the configuration class.
AppConfig.java
package com.concretepage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:myproject.properties")
public class AppConfig {
	 @Value("${cp.user.country}")
	 private String country;

	 @Value("${cp.user.role}")
	 private String role;
	 
	 @Bean
	 public User getUser() {
		 System.out.println("Country: "+ country);
		 System.out.println("Role: "+ role);		 
		 return new User("Mahesh");
	 }
} 
Output
Country: USA
Role: ADMIN
--- Initializing User ---
User name: Mahesh 

@Configuration + @Profile

We can use Spring @Profile with @Configuration. The @Profile enables the configuration classes to be registered when specified profiles are active.
In our example we have two configuration classes, one with prod profile and another with dev profile.
ProdEnvConfig.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import com.concretepage.User;

@Configuration
@Profile("prod")
public class ProdEnvConfig {
  @Bean
  public User getUser(){
	return new User("Prod User");
  }
} 
DevEnvConfig.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import com.concretepage.User;

@Configuration
@Profile("dev")
public class DevEnvConfig {
   @Bean
   public User getUser(){
      return new User("Dev User");
   }
} 
We can activate the profile using setActiveProfiles() method of ConfigurableEnvironment.
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.getEnvironment().setActiveProfiles("dev");
		ctx.scan("com.concretepage");
		ctx.refresh();
		User user = ctx.getBean(User.class);
		System.out.println("User name: " + user.getUserName());
		ctx.registerShutdownHook();
		ctx.close();
	}
} 
In the above code we have activated dev profile, so DevEnvConfig configuration class will be used by application.
Output
--- Initializing User ---
User name: Dev User
 

@Configuration + @EnableScheduling

We can use Spring @EnableScheduling with @Configuration. The @EnableScheduling enables Spring's scheduled task execution capability.
Find the class with a scheduled task using @Scheduled annotation.
Task.java
package com.concretepage;
import org.springframework.scheduling.annotation.Scheduled;
public class Task {
	@Scheduled(fixedRate = 2000)
	public void doTask() {
		System.out.println("Work in progress...");
	}
} 
Find the configuration class annotated with @EnableScheduling.
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

@Configuration
@EnableScheduling
public class AppConfig {
	@Bean
	public Task task() {
		return new Task();
	}
} 
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
	}
} 
Output
Work in progress...
Work in progress...
Work in progress... 

@Configuration + @ImportResource

We can use Spring @ImportResource with @Configuration. The @ImportResource annotation indicates one or more resources containing bean definitions to import.
In our example we will create a XML configuration and then we will import it into @Configuration class using @ImportResource.
app-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="com.concretepage.User">
        <constructor-arg name="userName" value="Mahesh"/>
    </bean>
</beans> 
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ImportResource("app-config.xml")
public class AppConfig {
} 
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
		User user = ctx.getBean(User.class);
		System.out.println("User name: " + user.getUserName());
		ctx.registerShutdownHook();
		ctx.close();
	}
} 
Output
--- Initializing User ---
User name: Mahesh 

@Configuration + @Import

We can use Spring @Import with @Configuration. The @Import indicates one or more @Configuration classes to import.
In our example we have two @Configuration classes and one configuration class is importing another configuration class using @Import annotation.
OtherAppConfig.java
package com.concretepage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OtherAppConfig {
	@Bean
	public User getUser() {
		return new User("Mahesh");
	}
}
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(OtherAppConfig.class)
public class AppConfig {
} 
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
		User user = ctx.getBean(User.class);
		System.out.println("User name: " + user.getUserName());
		ctx.registerShutdownHook();
		ctx.close();
	}
} 
Output
--- Initializing User ---
User name: Mahesh 

@Configuration + @ComponentScan

We can use Spring @ComponentScan with @Configuration. The @ComponentScan annotation configures component scanning directives for use with @Configuration classes.
In our example we have a component annotated with @Component class that will be scanned by @ComponentScan annotated at configuration class.
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.concretepage")
public class AppConfig {
} 
User.java
package com.concretepage;
import org.springframework.stereotype.Component;

@Component
public class User {
	private String userName = "Mahesh";
	public String getUserName() {
		return userName;
	}
} 
MySpringApp.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
		User user = ctx.getBean(User.class);
		System.out.println("User name: " + user.getUserName());
		ctx.registerShutdownHook();
		ctx.close();
	}
}
Output
User name: Mahesh 

Reference

Spring Doc: @Configuration
POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us