Close

Spring - Different ways of injecting dependencies

[Last Updated: Dec 6, 2020]

There are three possible ways of DI in Spring

  1. Constructor-based: should be used for mandatory dependencies. In constructor, we should assign constructor args to final member fields.

  2. Setter-based: Should be used for optional dependencies.

  3. Field-based: Spring discourages the use of this because it would possibly hide mandatory fields from outside which would otherwise be assigned in the constructor. This would take away the advantage of properly initialized POJO, specially if intended to use outside of Spring container. Even though, we are mostly using field based injection in this series of tutorials to simplify the concept we want to deliver, we suggest the developers to always avoid using field-based DI in real project scenarios.





Examples

package com.logicbig.example.service;

public class OrderService {
  public String getOrderDetails(String orderId) {
      return "Order details for order id=" + orderId;
  }
}

Constructor Based DI

package com.logicbig.example;

import com.logicbig.example.service.OrderService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ConstBasedDI {

    @Bean
    public OrderService orderService() {
        return new OrderService();
    }

    @Bean
    public OrderServiceClient orderServiceClient() {
        return new OrderServiceClient(orderService());
    }

    public static void main(String... strings) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
                ConstBasedDI.class);
        OrderServiceClient bean = context.getBean(OrderServiceClient.class);
        bean.showPendingOrderDetails();
    }

    private static class OrderServiceClient {

        private OrderService orderService;

        // @Autowired is not needed
        OrderServiceClient(OrderService orderService) {
            this.orderService = orderService;
        }

        public void showPendingOrderDetails() {
            System.out.println(orderService.getOrderDetails("100"));
        }
    }
}

Output

Order details for order id=100

Constructor Based DI with Component Scan

Following example shows Constructor Based DI with @ComponentScan:

package com.logicbig.example.scan;

import com.logicbig.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
@ComponentScan({"com.logicbig.example.scan"})
public class ConstBasedDIWithScan {

    @Bean
    public OrderService orderService() {
        return new OrderService();
    }

    public static void main(String... strings) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
                ConstBasedDIWithScan.class);
        OrderServiceClient bean = context.getBean(OrderServiceClient.class);
        bean.showPendingOrderDetails();
    }

    @Component
    public static class OrderServiceClient {

        private OrderService orderService;

        @Autowired
        OrderServiceClient(OrderService orderService) {
            this.orderService = orderService;
        }

        public void showPendingOrderDetails() {
            System.out.println(orderService.getOrderDetails("500"));
        }
    }
}

Output

Order details for order id=500

Setter Based DI

package com.logicbig.example;

import com.logicbig.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SetterBasedDI {

    @Bean
    public OrderService orderService() {
        return new OrderService();
    }

    @Bean
    public OrderServiceClient orderServiceClient() {
        return new OrderServiceClient();
    }

    public static void main(String... strings) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
                SetterBasedDI.class);
        OrderServiceClient bean = context.getBean(OrderServiceClient.class);
        bean.showPendingOrderDetails();
    }

    private static class OrderServiceClient {

        private OrderService orderService;

        @Autowired
        public void setOrderService(OrderService orderService) {
            this.orderService = orderService;
        }

        public void showPendingOrderDetails() {
            System.out.println(orderService.getOrderDetails("200"));
        }
    }
}

Output

Order details for order id=200
package com.logicbig.example;

import com.logicbig.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FieldBasedDI {

    @Bean
    public OrderService orderService() {
        return new OrderService();
    }

    @Bean
    public OrderServiceClient orderServiceClient() {
        return new OrderServiceClient();
    }

    public static void main(String... strings) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
                FieldBasedDI.class);
        OrderServiceClient bean = context.getBean(OrderServiceClient.class);
        bean.showPendingOrderDetails();
    }

    private static class OrderServiceClient {

        @Autowired
        private OrderService orderService;

        public void showPendingOrderDetails() {
            System.out.println(orderService.getOrderDetails("300"));
        }
    }
}

Output

Order details for order id=300

Dependencies and Technologies Used:

  • Spring Context 4.2.3.RELEASE: Spring Context.
  • JDK 1.8
  • Maven 3.6.3

Spring - Types of dependency injection Select All Download
  • spring-types-of-di
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • scan
                • service
                • ConstBasedDI.java

    See Also