The main purpose of the Java Based Configurations is to avoid XML configurations in the Spring applications, that is to remove Spring Configuration files in the Spring applications.
As per the above, we can prepare a Spring application without providing a Spring Configuration file but we must use the Java based configurations.
In the Spring applications, if we want to provide Java based configurations then we have to use the following steps.
- Prepare Configuration Class.
- Prepare Bean Methods in the configuration class.
- Create a Test Application to test the Java based configurations.
Prepare Configuration Class
The main purpose of the Configuration class is to provide all the beans configuration details to the IOC Container.
@Configuration annotation
To prepare a configuration class , we have to declare a normal Java class with @Configuration annotation.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
// Other bean definitions and configuration methods can go here
}
The @Configuration annotation is used in the Spring Framework to indicate that a class is a source of bean definitions. In other words, classes annotated with @Configuration are used to define Spring beans and their configuration in a Java-based configuration rather than relying solely on XML configuration.
In this example:
- The @Configuration annotation is applied to the class AppConfig, indicating that this class contains configuration information for the Spring container.
- The @Bean annotation is used on a method (myBean() in this case) to declare a bean definition. The method’s return value represents the bean instance that will be managed by the Spring container.
Classes annotated with @Configuration are often used in conjunction with the @Bean annotation to define beans and their dependencies in a programmatic and type-safe manner. This is an alternative to XML configuration.
Prepare Bean Methods in the configuration class
@Bean annotation
The @Bean annotation in the Spring Framework is used to declare a method as a producer of a bean managed by the Spring IoC (Inversion of Control) container. The main purpose of the Bean methods is to create bean objects and supply Bean objects to the IOC Container
When a method is annotated with @Bean, it serves as a factory for creating and configuring a bean instance. This is particularly useful in Java-based configuration, where you define your beans and their relationships in code rather than using XML.
If a bean has complex initialization logic or dependencies, @Bean allows you to express that complexity in a method, encapsulating the bean creation process.
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
@Bean
public AnotherBean anotherBean() {
return new AnotherBean(myBean());
}
}
In this extended example, the anotherBean() method is annotated with @Bean and demonstrates how you can manage dependencies between beans. Here, anotherBean() depends on the myBean() method, and Spring will automatically inject the result of myBean() when creating anotherBean().
In summary, the @Bean annotation is used when you want fine-grained control over the instantiation and configuration of beans in your Spring application, especially in scenarios where the standard stereotype annotations (@Component, @Service, etc.) are not sufficient.
@Bean
public Hello hello(){
Hello hello = new Hello();
return hello;
}
By Default, ApplicationContext will store the generated bean object along with the “methodName” as logical name , here we are able to get the Bean object by using the same method name.
Hello hello = applContext.getBean(“hello”);
If we want to store the generated Bean object with a particular logical name then we have to provide the logical name to the @Bean annotation.
@Bean(“helloBean”)
public Hello hello(){
Hello hello = new Hello();
return hello;
}
To get the Bean object as per the above configuration we have to use the following method.
Hello hello = applContext.getBean(“helloBean”);
Test Application to test the Java based configuration
The main purpose of the Test application is to create the ApplicationContext container and to get Bean objects and access the business methods that we declared in the bean classes.
Note: For the Java based configurations we have an AnnotationConfigApplicationContext container , it is an implementation class to the ApplicationContext interface.
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
Hello hello = (Hello)applicationContext.getBean(“hello”);
In the Java based configurations, when we create ApplicationContext container , the ApplicationContext container will take the provided Configuration class .class file name , it will perform loading and instantiation , it will recognize all the bean methods with the @Bean annotation , it will execute all the bean methods , it will create bean objects and stores all the bean objects along with the logical Name , here the logical name may be respective bean method name or may be an explicit name.
Note: If we want to use Java based configurations in the Spring applications then we have to provide spring-aop-version.jar file in the project library.
Example
Hello.java - POJO class
package com.durgasoft.beans;
public class Hello {
public String sayHello(){
return "Hello User!";
}
}
Welcome.java
package com.durgasoft.beans;
public class Welcome {
public String sayWelcome(){
return "Wecome To Durga Software Solutions";
}
}
AppConfig.java
package com.durgasoft.config;
import com.durgasoft.beans.Hello;
import com.durgasoft.beans.Welcome;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public Hello hello(){
return new Hello();
}
@Bean("welcomeBean")
public Welcome welcome(){
return new Welcome();
}
}
Main.java
import com.durgasoft.beans.Hello;
import com.durgasoft.beans.Welcome;
import com.durgasoft.config.AppConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
Hello hello = (Hello) applicationContext.getBean("hello");
System.out.println(hello.sayHello());
Welcome welcome = (Welcome) applicationContext.getBean("welcomeBean");
System.out.println(welcome.sayWelcome());
}
}
In Java based configuration , we are able to define scope to the bean components by using @Scope annotation.
@Bean
@Scope(“singleton”)
public Hello hello(){
—---
}
When to use Java based configuration ?
Using @Configuration and @Bean annotations
I have a class, and its object needs to be created with some data that is given at runtime.
package com.rndayala.util;
public class Password
{
public Password(String algo) {
System.out.println("Algo used : " + algo);
}
}
I would want the object to be created by myself, but then I want that object to be managed by Spring IoC, then I need to use @Bean annotation.
package com.rndayala.util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Configure {
public Configure() {
System.out.println("Instantiating Configure object..");
}
@Bean
public Password generateAlgo() {
Password p = new Password("SHA1");
return p;
}
}
Accessing the bean :
// getting bean from Spring framework
Password p = context.getBean(Password.class);
Output :
Instantiating DataModel object using default constructor.
Instantiating Service object using default constructor.
Instantiating Configure object..
Instantiating Util object using default constructor.
Algo used : SHA1