指的是bean对象的延迟创建,
ApplicationContext容器的默认行为是在启动服务时,
将所有singleton bean进行提前实例化,
ApplicationContext会创建并配置所有的singletonbean,
例如:
<bean id="testService" class="com.example.duohoob.service.TestServiceImpl" lazy-init="false"/>
如果不想让一个bean在spring启动时提前实例化,可以将bean设置为延迟加载,
<bean id="testService" class="com.example.duohoob.service.TestServiceImpl" lazy-init="true"/>
lazy-init = "true"的bean会在第一次被获取bean时被实例化,
如果一个设置提前加载的bean1,依赖了一个延迟加载的bean2,
bean1会在容器启动时被实例化,此时会去获取bean2,
所以bean2也被实例化,这也符合延迟加载的bean在第一次被调用时才实例化的规则,
延迟加载适用于singleton的bean,
对应的注解是@Lazy(true)。
BeanFactory是容器的顶级接口,定义了容器的一些基础行为,负责生产和管理bean的一个工厂,
具体是使用它的下级实现,例如ApplicationContext,此处我们重点分析FactoryBean。
spring的bean有两种,一种是普通bean,另一种是工厂bean(FactoryBean),
可以借助于它,自定义bean的创建过程。
FactoryBean
public interface FactoryBean<T> {
/**
* The name of an attribute that can be
*/
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
/**
* 返回FactoryBean生成的bean对象
* 如果isSingleton为true,该实例会被存放到spring容器的单例缓存池中
*/
@Nullable
T getObject() throws Exception;
/**
* 返回FactoryBean生成的bean类型
*/
@Nullable
Class<?> getObjectType();
/**
* 作用域是否singleton
*/
default boolean isSingleton() {
return true;
}
}
package com.duohoob.spring.dao.entity;
/**
* @author yangwei
* @date 2022年10月24日
*/
public class UserEntity {
private String name;
private String mobile;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
实现FactoryBean接口
package com.duohoob.spring.factory;
import org.springframework.beans.factory.FactoryBean;
import com.duohoob.spring.dao.entity.UserEntity;
/**
* @author yangwei
* @date 2022年10月24日
*/
public class UserEntityFactoryBean implements FactoryBean<UserEntity> {
private String userInfo; // 用户信息:name, mobile, address
public void setUserInfo(String userInfo) {
this.userInfo = userInfo;
}
/**
* 创建复杂对象UserEntity
*/
@Override
public UserEntity getObject() throws Exception {
// TODO Auto-generated method stub
UserEntity entity = new UserEntity();
String[] split = userInfo.split(",");
entity.setName(split[0]);
entity.setMobile(split[1]);
entity.setAddress(split[2]);
return entity;
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return UserEntity.class;
}
/**
* singleton
*/
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"
default-lazy-init="false">
<bean id="userEntity" class="com.duohoob.spring.factory.UserEntityFactoryBean">
<property name="userInfo" value="yw, 桐柏村, 15715740560"/>
bean>
beans>
这里的userEntity是UserEntityFactoryBean的getObject返回的对象,而不是UserEntityFactoryBean本身,
如果要获取UserEntityFactoryBean对象,bean的ID应该是&userEntity,
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-context.xml");
Object bean = context.getBean("userEntity");
System.out.println(bean);
Object factoryBean = context.getBean("&userEntity");
System.out.println(factoryBean);
((AbstractApplicationContext) context).close();
}