Friday, March 27, 2020

Spring Java Configuration Example Using @Configuration

In this post we'll see Spring Java based configuration example using @Configuration annotation. For creating project structure Maven is used.

Technologies used

  • Spring 5.0.4
  • JDK 1.8
  • Apache Maven 3.3.3
  • Eclipse Luna 4.2.2

Spring Java Config example step by step

Let's go step by step to see how these classes are configured using Java configuration.

  1. Provide dependencies in pom.xml of Maven

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>org.netjs.exp</groupId>
      <artifactId>Spring-Example</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>
    
      <name>Spring-Example</name>
      <url>http://maven.apache.org</url>
      <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>5.0.4.RELEASE</spring.version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>         
      </dependencies>
    </project>
    

    Note that you'll already have most of the entries in pom.xml, you just need to add dependencies for spring-core and spring-context and an entry for spring.version in properties element. spring-context is needed for the annotations.

  2. Spring JavaConfig example - Bean classes

    We need 2 classes PaymentService and CashPayment. Since Spring promotes loose coupling so it is always recommended to code to interfaces. So we'll also create interfaces for the classes.

    Payment Service

    public interface IPayService {
        void performPayment();
    }
    
    public class PayServiceImpl implements IPayService {
     private IPayment payment;
     
     public void performPayment() {
      payment.executePayment();
     }
     
     public IPayment getPayment() {
      return payment;
     }
    
     public void setPayment(IPayment payment) {
      this.payment = payment;
     }
    }
    

    PayServiceImpl class has a dependency on instance of type IPayment, this dependency is defined in the Configuration class i.e. class that is annotated with @Configuration annotation.

    Cash Payment

    public interface IPayment {
     void executePayment();
    }
    
    public class CashPayment implements IPayment{
     public void executePayment() {
      System.out.println("Perform Cash Payment "); 
     }
    }
    
  3. Spring JavaConfig example - JavaConfig class

    For Java based configuration in Spring you need to annotate JavaConfig class with @Configuration annotation. When a class is annotated with @Configuration annotation the annotated class is identified as a configuration class. This configuration class will contain the @Bean annotated methods, these methods will provide details about the beans that are to be created and managed by the Spring application context.

    It's better to keep config classes in a separate package so create a new package and create the config class (I have named it AppConfig.java) there.

    package org.netjs.exp.config;
    
    import org.netjs.exp.Spring_Example.CashPayment;
    import org.netjs.exp.Spring_Example.IPayService;
    import org.netjs.exp.Spring_Example.IPayment;
    import org.netjs.exp.Spring_Example.PayServiceImpl;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AppConfig {
     @Bean
     public IPayService payService(){
      PayServiceImpl payServiceImpl = new PayServiceImpl();
      //setting bean dependency
      payServiceImpl.setPayment(cashPayment());
      return payServiceImpl;
     }
     
     @Bean
     public IPayment cashPayment(){
      return new CashPayment(); 
     }
    }
    

    Here it can be seen how the methods that create the beans are annotated with @Bean annotation. Also note that in this configuration class I have given example of setter based dependency injection.

  4. Java class to run the application

    package org.netjs.exp.Spring_Example;
    
    import org.netjs.exp.config.AppConfig;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.support.AbstractApplicationContext;
    
    public class App 
    {
        public static void main( String[] args ){
            AbstractApplicationContext context = new AnnotationConfigApplicationContext
             (AppConfig.class);
            IPayService bean = (IPayService) context.getBean("payService");
            bean.performPayment();
            context.close();
        }
    }
    

    Output

    May 20, 2018 11:24:27 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@46fbb2c1: startup date [Sun May 20 11:24:27 IST 2018]; root of context hierarchy
    Perform Cash Payment 
    May 20, 2018 11:24:29 AM org.springframework.context.support.AbstractApplicationContext doClose
    INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@46fbb2c1: startup date [Sun May 20 11:24:27 IST 2018]; root of context hierarchy
    

    Here note that AnnotationConfigApplicationContext is used to create the Spring application context. JavaConfig class is passed as parameter to the class constructor. While setting up application context it searches for all the beans in the configuration class by looking for the methods annotated with @Bean annotation.
    Another thing to note here is that by default the bean's id is the same as the name given to the method annotated with @Bean. That's why you can get the PayService bean using-

    context.getBean("payService");
    
    Because in the JavaConfig class method's name is payService. If you want to provide another name then you can use the name attribute. As example if you want to call the payService bean as myPayService then it can be done this way -
    @Bean(name="myPayService")
    public IPayService payService(){
     PayServiceImpl payServiceImpl = new PayServiceImpl();
     payServiceImpl.setPayment(cashPayment());
     return payServiceImpl;
    }
    
    And then it should be called as
     
    IPayService bean = (IPayService) context.getBean("myPayService");
    

Spring Java Configuration example with constructor dependency injection

As I mentioned above, the configuration done was for setter. If you want to use constructor dependency injection then you need to change it a little.

Suppose the PayService class is like this-
 
public class PayServiceImpl implements IPayService {
 
 private IPayment payment;
 public PayServiceImpl(IPayment payment){
  this.payment = payment;
 }
 
 public void performPayment() {
  payment.executePayment();
 }

}
Then in JavaConfig class we have to provide a constructor injection.
package org.netjs.exp.config;

import org.netjs.exp.Spring_Example.CashPayment;
import org.netjs.exp.Spring_Example.IPayService;
import org.netjs.exp.Spring_Example.IPayment;
import org.netjs.exp.Spring_Example.PayServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
 @Bean
 public IPayService payService(){
  return new PayServiceImpl(cashPayment());
 }
 
 @Bean
 public IPayment cashPayment(){
  return new CashPayment(); 
 }
}

That's all for this topic Spring Java Configuration Example Using @Configuration. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring XML Configuration Example Program
  2. Spring Example Program Using Automatic Configuration
  3. What is Dependency Injection in Spring
  4. Using Conditional Annotation in Spring Framework
  5. Insert\Update Using JDBCTemplate in Spring Framework

You may also like-

  1. Dependency Injection Using factory-method in Spring
  2. Bean Definition Inheritance in Spring
  3. Data access in Spring framework
  4. Creating a Maven project in Eclipse
  5. ReentrantReadWriteLock in Java
  6. ConcurrentHashMap in Java
  7. Deadlock in Java multi-threading
  8. Marker interface in Java