Mastering Spring IoC Container and Dependency Injection

IoC Container Basics

The Spring IoC (Inversion of Control) container manages application components and their lifecycle. Instead of creating objects manually, you define beans in configuration, and the container handles instantiation and wiring.

Defining Beans

A bean definition specifies how an object should be created and managed. In XML configuration:

<bean id="productService" class="com.example.service.ProductServiceImpl"/>

The id attribute uniquely identifies the bean. The class attribute specifies the concrete implementation.

Bean Scopes

Spring supports several scopes:

  • singleton: Single instance per container (default)
  • prototype: New instance each time requested
  • request, session, application, websocket: Web-aware scopes
<bean id="orderService" class="com.example.service.OrderServiceImpl" scope="prototype"/>

Lifecycle Callbacks

Initialization and destruction methods can be configured:

public class PaymentService {
    public void setup() {
        // init logic
    }
    public void cleanup() {
        // destroy logic
    }
}
<bean id="paymentService" class="com.example.service.PaymentService"
      init-method="setup" destroy-method="cleanup"/>

Singleton beans invoke init-method once at container startup. Prototype beans invoke it per creation but do not call destroy-method.

Dependency Injection with Setters

Property injection uses setter methods:

<bean id="inventoryRepository" class="com.example.repo.InventoryRepository"/>

<bean id="inventoryService" class="com.example.service.InventoryService">
    <property name="repository" ref="inventoryRepository"/>
    <property name="timeout" value="3000"/>
</bean>

name matches the property's setter (setRepository, setTimeout). ref injects another bean; value injects simple values.

Constructor Injection

For mandatory dependencies:

<bean id="emailService" class="com.example.service.EmailService">
    <constructor-arg name="host" value="smtp.example.com"/>
    <constructor-arg index="1" ref="messageFormatter"/>
</bean>

You can match arguments by name, type, or index. Multiple <constructor-arg> elements are allowed.

Injecting Collections

Spring handles lists, sets, maps, and properties:

<bean id="configManager" class="com.example.core.ConfigManager">
    <property name="servers">
        <list>
            <value>server1.prod.com</value>
            <value>server2.prod.com</value>
        </list>
    </property>
    <property name="options">
        <props>
            <prop key="threads">10</prop>
            <prop key="protocol">https</prop>
        </props>
    </property>
    <property name="metadata">
        <map>
            <entry key="env" value="production"/>
            <entry key="version" value="2.1"/>
        </map>
    </property>
</bean>

Externalized Properties

Load .properties files and reference values:

<context:property-placeholder location="classpath:app.properties"/>

<bean id="connectionPool" class="com.example.db.ConnectionPool">
    <property name="url" value="${db.url}"/>
    <property name="username" value="${db.username}"/>
</bean>

Container Types

ClassPathXmlApplicationContext loads config from classpath. FileSystemXmlApplicationContext reads from file system.

Integration: Spring & MyBatis

Combining Spring with MyBatis elimintaes manual session management. The core setup:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="typeAliasesPackage" value="com.example.domain"/>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.example.mapper"/>
</bean>

This replaces the MyBatis main configuraton file. Mapper interfaces are automatically proxied.

Finally, retrieve beans and execute operations:

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");
AccountService service = ctx.getBean(AccountService.class);
service.transfer(1001, 1002, BigDecimal.valueOf(500));

Tags: Spring IoC Dependency Injection XML Configuration

Posted on Fri, 08 May 2026 14:14:11 +0000 by SBukoski