Spring Framework Tutorial

Software Setup and Configuration (STS/Eclipse/IntelliJ)

Core Spring

Spring Annotations

Spring Data

Spring JDBC

Spring Security

Spring - Constructor Injection with Dependent Object

Constructor injection with a dependent object in Spring is a common scenario. When one bean has a dependency on another bean, you can inject the dependent bean using constructor injection.

Let's look at an example of how you can inject a dependent object through constructor injection.

Domain Objects:

Address.java:

public class Address {
    private String city;
    private String country;

    // Constructors, getters, setters...
    public Address(String city, String country) {
        this.city = city;
        this.country = country;
    }
}

Person.java:

public class Person {
    private String name;
    private Address address;

    // Constructors, getters, setters...
    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }
}

In this example, the Person class has a dependency on the Address class.

XML Configuration:

To set up constructor injection using XML, you'll use the <constructor-arg> element:

spring-config.xml:

<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="address" class="com.example.Address">
        <constructor-arg value="New York" />
        <constructor-arg value="USA" />
    </bean>

    <bean id="person" class="com.example.Person">
        <constructor-arg value="John" />
        <constructor-arg ref="address" />
    </bean>

</beans>

The address bean is injected into the person bean through the constructor.

Java-based Configuration:

Using Java configuration, you'd set it up like this:

package com.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public Address address() {
        return new Address("New York", "USA");
    }

    @Bean
    public Person person() {
        return new Person("John", address());
    }
}

Here, the address() method creates an Address bean, and it's passed as an argument to create the Person bean.

Annotations-based Autowiring:

If you're using component scanning and annotations:

Address.java (Updated):

import org.springframework.stereotype.Component;

@Component
public class Address {
    //...
}

Person.java (Updated):

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Person {
    
    @Autowired
    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    //...
}

In the annotated configuration, Spring automatically wires the Address bean into the Person bean using the @Autowired annotation on the constructor.

  1. Constructor injection with nested objects in Spring framework:

    • Use constructor injection with nested objects for creating hierarchical dependencies.
    // MyService.java
    public class MyService {
    
        private final MyDependency myDependency;
    
        public MyService(MyDependency myDependency) {
            this.myDependency = myDependency;
        }
    }
    
  2. Injecting dependent objects in Spring constructor using annotations:

    • Inject dependent objects in the constructor using annotations for cleaner configuration.
    // MyService.java
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class MyService {
    
        private final MyDependency myDependency;
    
        @Autowired
        public MyService(MyDependency myDependency) {
            this.myDependency = myDependency;
        }
    }
    
  3. Spring constructor injection with object dependencies example:

    • Demonstrate constructor injection with object dependencies in a Spring project.
    // AppConfig.java
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AppConfig {
    
        @Bean
        public MyService myService(MyDependency myDependency) {
            return new MyService(myDependency);
        }
    
        // Other configuration...
    }
    
  4. How to pass dependent objects to a constructor in Spring:

    • Pass dependent objects to a constructor by configuring them in the Spring configuration.
    // AppConfig.java
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AppConfig {
    
        @Bean
        public MyDependency myDependency() {
            return new MyDependency();
        }
    
        @Bean
        public MyService myService(MyDependency myDependency) {
            return new MyService(myDependency);
        }
    
        // Other configuration...
    }
    
  5. Constructor-based dependency injection with dependent objects in Spring:

    • Configure constructor-based dependency injection with dependent objects in a Spring project.
    // AppConfig.java
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AppConfig {
    
        @Bean
        public MyDependency myDependency() {
            return new MyDependency();
        }
    
        @Bean
        public MyService myService(MyDependency myDependency) {
            return new MyService(myDependency);
        }
    
        // Other configuration...
    }
    
  6. Injecting a hierarchy of dependent objects using Spring IoC container:

    • Utilize the Spring IoC container to inject a hierarchy of dependent objects into the constructor.
    // AppConfig.java
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AppConfig {
    
        @Bean
        public MyDependency myDependency() {
            return new MyDependency();
        }
    
        @Bean
        public AnotherDependency anotherDependency() {
            return new AnotherDependency();
        }
    
        @Bean
        public MyService myService(MyDependency myDependency, AnotherDependency anotherDependency) {
            return new MyService(myDependency, anotherDependency);
        }
    
        // Other configuration...
    }