Spring @Configuration Annotation
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.
Contents
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"); } }
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; } }
@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(); } }
--- 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>
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
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"); } }
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"); } }
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"); } }
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(); } }
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..."); } }
@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(); } }
package com.concretepage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MySpringApp { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); } }
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>
package com.concretepage; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; @Configuration @ImportResource("app-config.xml") public class AppConfig { }
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(); } }
--- 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"); } }
package com.concretepage; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration @Import(OtherAppConfig.class) public class AppConfig { }
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(); } }
--- 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 { }
package com.concretepage; import org.springframework.stereotype.Component; @Component public class User { private String userName = "Mahesh"; public String getUserName() { return userName; } }
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(); } }
User name: Mahesh