Spring Framework Tutorial

Software Setup and Configuration (STS/Eclipse/IntelliJ)

Core Spring

Spring Annotations

Spring Data

Spring JDBC

Spring Security

Spring Dependency Injection with Example

In the Spring framework, Dependency Injection (DI) is a technique wherein an object receives its dependencies from outside rather than creating them itself. This promotes the principle of inversion of control where the control of creating objects is transferred from the application code to the framework.

There are primarily three types of DI in Spring:

  1. Constructor Injection
  2. Setter Injection
  3. Field Injection

I'll provide a simple example for each type of DI.

1. Constructor Injection:

Bean classes:

public class Engine {
    public String type() {
        return "V8 Engine";
    }
}

public class Car {
    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public void displayEngineType() {
        System.out.println(engine.type());
    }
}

XML Configuration:

<bean id="engine" class="com.example.Engine"/>

<bean id="car" class="com.example.Car">
    <constructor-arg ref="engine"/>
</bean>

2. Setter Injection:

Bean classes:

public class Wheel {
    public String type() {
        return "Alloy Wheel";
    }
}

public class Bike {
    private Wheel wheel;

    public void setWheel(Wheel wheel) {
        this.wheel = wheel;
    }

    public void displayWheelType() {
        System.out.println(wheel.type());
    }
}

XML Configuration:

<bean id="wheel" class="com.example.Wheel"/>

<bean id="bike" class="com.example.Bike">
    <property name="wheel" ref="wheel"/>
</bean>

3. Field Injection (using annotations):

Field injection uses @Autowired annotation directly on the field.

Configuration:

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {}

Bean classes:

@Component
public class Battery {
    public String type() {
        return "Lithium-ion Battery";
    }
}

@Component
public class Mobile {
    @Autowired
    private Battery battery;

    public void displayBatteryType() {
        System.out.println(battery.type());
    }
}

Running the Application:

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        // For Constructor Injection
        Car car = context.getBean(Car.class);
        car.displayEngineType();

        // For Setter Injection
        Bike bike = context.getBean(Bike.class);
        bike.displayWheelType();

        // For Field Injection
        Mobile mobile = context.getBean(Mobile.class);
        mobile.displayBatteryType();
    }
}

The output will be:

V8 Engine
Alloy Wheel
Lithium-ion Battery

Remember:

  • Constructor Injection is preferable when the dependency is mandatory.
  • Setter Injection is preferable when the dependency is optional.
  • Field Injection is less favored due to various reasons (like testability issues), but it provides a concise way to inject dependencies.

Regardless of the injection type, the primary goal is to decouple components and make them more modular and testable.

  1. How to implement Dependency Injection in Spring framework:

    • Dependency Injection in Spring involves providing the dependent objects (dependencies) to a class rather than the class creating them.
    // UserService.java
    public class UserService {
    
        private UserRepository userRepository;
    
        // Constructor-based Dependency Injection
        public UserService(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        // Other methods...
    }
    
  2. Dependency Injection types in Spring with examples:

    • Spring supports various DI types, including constructor injection, setter injection, and method injection.
    // OrderService.java
    public class OrderService {
    
        private OrderRepository orderRepository;
    
        // Constructor-based DI
        public OrderService(OrderRepository orderRepository) {
            this.orderRepository = orderRepository;
        }
    
        // Setter-based DI
        public void setOrderRepository(OrderRepository orderRepository) {
            this.orderRepository = orderRepository;
        }
    
        // Other methods...
    }
    
  3. Constructor-based Dependency Injection in Spring example:

    • In constructor-based DI, dependencies are injected through the constructor.
    // ProductService.java
    public class ProductService {
    
        private ProductRepository productRepository;
    
        // Constructor-based DI
        public ProductService(ProductRepository productRepository) {
            this.productRepository = productRepository;
        }
    
        // Other methods...
    }
    
  4. Setter-based Dependency Injection in Spring example:

    • In setter-based DI, dependencies are injected using setter methods.
    // ShoppingCartService.java
    public class ShoppingCartService {
    
        private CartRepository cartRepository;
    
        // Setter-based DI
        public void setCartRepository(CartRepository cartRepository) {
            this.cartRepository = cartRepository;
        }
    
        // Other methods...
    }
    
  5. Using @Autowired for Dependency Injection in Spring:

    • Annotate fields, constructors, or setter methods with @Autowired for automatic DI.
    // UserService.java
    public class UserService {
    
        @Autowired
        private UserRepository userRepository;
    
        // Other methods...
    }
    
  6. Injecting dependencies with XML configuration in Spring:

    • Configure dependencies in an XML file, specifying beans and their relationships.
    <!-- applicationContext.xml -->
    <bean id="userService" class="com.example.UserService">
        <property name="userRepository" ref="userRepository" />
    </bean>