Lazy Loading
Lazy-init means lazy loading of Bean. The default behavior of the ApplicationContext container is that all Singleton Beans are eagerly instantiated when the server starts.
Configuration Method
<!-- Default bean configuration -->
<bean id="wzkTestBean" class="wzk.WzkTestBean" lazy-init="false" />
falsemeans immediate loading, instant initialization when Spring startstruemeans lazy loading, initialization only on first call
If a bean1 set to immediate loading references a bean2 set to lazy loading, bean1 will be initialized when the container starts, and at this point, bean2 will also be instantiated.
You can also use the default-lazy-init attribute to control global lazy initialization:
<beans default-lazy-init="true">
<!-- no beans will be eagerly pre-instantiated... -->
</beans>
When a bean’s scope is prototype, even if lazy-init=false is set, the container will not immediately initialize at startup. Instead, it will be instantiated only when the getBean method is called.
Application Scenarios
- Enabling lazy loading can improve container startup performance and operation performance
- For infrequently used Beans, instantiating only when occasionally needed saves resources
FactoryBean and BeanFactory
Basic Introduction
BeanFactory interface is the top-level interface of the container, defining the container’s basic behavior, responsible for producing and managing Bean factories. Its specific use is through sub-interface types such as ApplicationContext.
FactoryBean is a special type of Bean in Spring that can generate instances of a certain type. With its help, you can customize the Bean creation process. Spring has two types of Beans:
- Regular Bean
- Factory Bean (FactoryBean)
FactoryBean is similar to static factory methods and instance factory methods, but is more frequently used in the Spring framework and when integrating with third-party frameworks.
FactoryBean Interface Methods
public interface FactoryBean<T> {
T getObject() throws Exception; // Get instantiated object
Class<?> getObjectType(); // Return object type
boolean isSingleton(); // Whether singleton
}
Code Example
WzkCompany Entity Class
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WzkCompany {
private String name;
private String address;
private String money;
}
WzkCompanyFactoryBean Implementation Class
public class WzkCompanyFactoryBean implements FactoryBean<WzkCompany> {
private String wzkCompanyInfo;
public void setWzkCompanyInfo(String wzkCompanyInfo) {
this.wzkCompanyInfo = wzkCompanyInfo;
}
@Override
public WzkCompany getObject() throws Exception {
WzkCompany wzkCompany = new WzkCompany();
String[] strs = wzkCompanyInfo.split(",");
wzkCompany.setName(strs[0]);
wzkCompany.setAddress(strs[1]);
wzkCompany.setMoney(strs[2]);
return wzkCompany;
}
@Override
public Class<?> getObjectType() {
return WzkCompany.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
XML Configuration
<bean id="wzkCompanyBean" class="wzk.factory.WzkCompanyFactoryBean">
<property name="companyInfo" value="Company Name,Company Address,1000"></property>
</bean>
Test Run
// Get the object created by FactoryBean
Object wzkCompany = applicationContext.getBean("wzkCompanyBean");
// Output: WzkCompany(name=Company Name, address=Company Address, money=1000)
// Get the FactoryBean itself, need to add & prefix
Object factoryBean = applicationContext.getBean("&wzkCompanyBean");
// Output: wzk.factory.WzkCompanyFactoryBean@xxxx
Post-Processors
Spring provides two extension interfaces for post-processing Beans:
- BeanPostProcessor
- BeanFactoryPostProcessor
Execution order: Factory initializes BeanFactory → Bean objects → After BeanFactory initialization, use BeanFactoryPostProcessor → After Bean instantiation, use BeanPostProcessor
Note: An object is not necessarily a SpringBean, but a SpringBean is always an object.
BeanPostProcessor
BeanPostProcessor is bean-level processing, which can handle specific Beans.
public interface BeanPostProcessor {
// Executed before initialization method
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
// Executed after initialization method
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
Explanation:
- The initialization method refers to the method specified by
init-method - By default, it processes all Beans in the entire Spring container
- You can use the
beanNameparameter to determine which specific Bean to process - Processing occurs after Spring container instantiation and dependency injection
BeanFactoryPostProcessor
BeanFactoryPostProcessor is BeanFactory-level processing, which handles the entire Bean factory. A typical application is PropertyPlaceholderConfigurer.
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
You can use the getBeanDefinition method to get the BeanDefinition object and modify the property values defined in the Bean tag.
Note: When the BeanFactoryPostProcessor method is called, the Bean has not yet been instantiated. At this point, the Bean has just been parsed as a BeanDefinition object.
Summary
| Concept | Description |
|---|---|
| BeanFactory | Top-level IoC container interface, responsible for producing and managing Beans |
| FactoryBean | Special Bean for customizing Bean creation process |
| BeanPostProcessor | Bean-level post-processing, executes before and after initialization |
| BeanFactoryPostProcessor | Factory-level post-processing, executes before Bean instantiation |