Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Inversion of Control and XML Dependency Injection in Spring

Tech 3

Inversion of Control (IoC) shifts the responsibility of object creation and lifecycle management away from the objects themselves, delegating it to an external container. Dependency Injection (DI) serves as the primary mechanism to achieve this, where required components are supplied to an object rather than the object constructing them directly. This approach eliminates tight coupling caused by hard-coded instantiation.

Within the Spring ecosystem, the IoC container manages application components known as Beans. These beans can be defined using XML, annotations, or code-based configurations.

XML-Based Dependency Injection

Consider a class hierarchy where Customer extends a abstract User class.

java public abstract class User { protected String username; }

java public class Customer extends User { private int loyaltyPoints; private Location residentialArea;

public Customer(String username, int loyaltyPoints) {
    this.username = username;
    this.loyaltyPoints = loyaltyPoints;
}

public Customer(String username, int loyaltyPoints, Location residentialArea) {
    this.username = username;
    this.loyaltyPoints = loyaltyPoints;
    this.residentialArea = residentialArea;
}

public void setLoyaltyPoints(int loyaltyPoints) {
    this.loyaltyPoints = loyaltyPoints;
}

@Override
public String toString() {
    return "Customer{username='" + username + "', loyaltyPoints=" + loyaltyPoints + ", location=" + residentialArea + "}";
}

}

The Location class represents a reference type dependency.

java public class Location { private String state; private String municipality;

public Location() {}

public Location(String state, String municipality) {
    this.state = state;
    this.municipality = municipality;
}

public String getState() { return state; }
public void setState(String state) { this.state = state; }
public String getMunicipality() { return municipality; }
public void setMunicipality(String municipality) { this.municipality = municipality; }

@Override
public String toString() {
    return "Location{state='" + state + "', municipality='" + municipality + "'}";
}

}

To bootstrap the container and retrieve beans:

java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Application { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("service-config.xml"); User client1 = context.getBean("client1", User.class); System.out.println(client1); } }

Constructor Argument Injection

Dependencies can be injected during instantiation using the constructor-arg element.

By Parameter Name:

xml

By Parameter Index:

xml

Setter Method Injection

Properties can be assigned after construction using the property element. This requires the target class to provide corresponding setter methods for the fields.

xml

Injecting Object References

When a dependency is another bean, the ref attribute is used instead of value.

xml

Retrieving and verifying the reference injection:

java ApplicationContext context = new ClassPathXmlApplicationContext("service-config.xml"); User client4 = context.getBean("client4", User.class); User client5 = context.getBean("client5", User.class); System.out.println(client4); System.out.println(client5);

Configuring Bean Scope

By default, Spring beans are scoped as singletons. Requesting the same bean ID yields the exact same instance.

java User clientA = context.getBean("client5", User.class); User clientB = context.getBean("client5", User.class); System.out.println(clientA == clientB); // Outputs: true

To instruct the container to produce a new instance for every request, set the scope attribute to prototype.

xml

With the prototype scope, the equality check evaluates to false:

java User clientA = context.getBean("client5", User.class); User clientB = context.getBean("client5", User.class); System.out.println(clientA == clientB); // Outputs: false

Lazy Initialization

The ApplicationContext pre-instantiates all singleton beans during startup. This fail-fast behavior exposes configuraton errors immediately. If a singleton bean should only be instantiated upon its first invocation, the lazy-init attribute can be set to true.

xml

Verifying the deferred instantiation:

java public class Application { public static void main(String[] args) throws InterruptedException { ApplicationContext context = new ClassPathXmlApplicationContext("service-config.xml"); System.out.println("Container initialized."); Thread.sleep(2000);

    User lazyClient = context.getBean("lazy_client", User.class);
    System.out.println("Lazy bean retrieved.");
}

}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.