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 requestedrequest,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));