Spring Framework Tutorial

Software Setup and Configuration (STS/Eclipse/IntelliJ)

Core Spring

Spring Annotations

Spring Data

Spring JDBC

Spring Security

Spring - Dependency Injection by Setter Method

Dependency Injection (DI) is a core concept in the Spring framework. It is the mechanism by which Spring provides the dependencies of a bean. There are several ways to achieve DI in Spring: via constructor injection, setter method injection, and field injection.

Here, we'll focus on Setter Method Injection.

How Setter Method Injection Works

In setter method injection, the container will inject the dependencies through the bean's setter methods. For the setter method injection to work, you'll:

  1. Define the bean and its dependencies in the Spring configuration (either via XML or Java config or annotations).
  2. Provide setter methods in the bean class for injecting the dependencies.

Example

Consider we have a MessageService and a MessagePrinter class:

public class MessageService {
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

public class MessagePrinter {
    private MessageService messageService;

    // Setter method for DI
    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }

    public void printMessage() {
        System.out.println("Message: " + messageService.getMessage());
    }
}

XML Configuration:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="messageService" class="com.example.MessageService">
        <property name="message" value="Hello, Spring!"/>
    </bean>

    <bean id="messagePrinter" class="com.example.MessagePrinter">
        <property name="messageService" ref="messageService"/>
    </bean>

</beans>

In the above configuration:

  • The <property> tag corresponds to the setter methods of the bean class.
  • The name attribute of <property> should match the name of the property (field) in the bean.
  • The ref attribute refers to another bean definition (in this case, messageService).

Using in a Java Application:

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        MessagePrinter printer = context.getBean("messagePrinter", MessagePrinter.class);
        printer.printMessage();
    }
}

When you run the application, Spring initializes the beans, and the dependencies are injected using the setter methods. The output will be:

Message: Hello, Spring!

Setter injection is especially useful when:

  1. There are optional dependencies for a bean.
  2. When you prefer XML configurations (though it works with Java Config and annotations too).

However, note that in modern Spring applications, constructor injection is often favored over setter injection as it ensures the immutability of the bean's dependencies once they're set and promotes cleaner and more concise code.

  1. Setter-based Dependency Injection in Spring:

    • Setter-based DI involves injecting dependencies into a class using setter methods.
    // UserService.java
    public class UserService {
    
        private UserRepository userRepository;
    
        // Setter method for userRepository
        public void setUserRepository(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        // Other methods...
    }
    
  2. How to use setter injection in Spring framework:

    • Define setter methods for each dependency in your class and let Spring inject them.
    // OrderService.java
    public class OrderService {
    
        private OrderRepository orderRepository;
    
        // Setter method for orderRepository
        public void setOrderRepository(OrderRepository orderRepository) {
            this.orderRepository = orderRepository;
        }
    
        // Other methods...
    }
    
  3. Injecting dependencies using setter methods in Spring:

    • Declare setter methods for each dependency and annotate them with @Autowired to enable Spring to inject the dependencies.
    // ProductService.java
    public class ProductService {
    
        private ProductRepository productRepository;
    
        @Autowired
        public void setProductRepository(ProductRepository productRepository) {
            this.productRepository = productRepository;
        }
    
        // Other methods...
    }
    
  4. Configuring dependencies with setter methods in Spring:

    • Configure dependencies in the Spring configuration file or through annotations.
    <!-- applicationContext.xml -->
    <bean id="userService" class="com.example.UserService">
        <property name="userRepository" ref="userRepository" />
    </bean>
    
  5. Using @Autowired with setter methods in Spring:

    • Annotate setter methods with @Autowired for automatic dependency injection.
    // UserService.java
    public class UserService {
    
        private UserRepository userRepository;
    
        @Autowired
        public void setUserRepository(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        // Other methods...
    }