spring框架源码十二、spring ioc高级特性之lazy-init延迟加载及FactoryBean和BeanFactory

spring ioc高级特性之lazy-init延迟加载及FactoryBean和BeanFactory

  • lazy-init延迟加载
  • FactoryBean和BeanFactory
    • BeanFactory
    • FactoryBean
      • 应用
        • UserEntity
        • UserEntityFactoryBean
        • application-context.xml
        • 测试

lazy-init延迟加载

指的是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)。

FactoryBean和BeanFactory

BeanFactory

BeanFactory是容器的顶级接口,定义了容器的一些基础行为,负责生产和管理bean的一个工厂,
具体是使用它的下级实现,例如ApplicationContext,此处我们重点分析FactoryBean。

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;
	}

}

应用

UserEntity

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;
	}
	
}

UserEntityFactoryBean

实现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;
	}

}

application-context.xml

<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();
	}

spring框架源码十二、spring ioc高级特性之lazy-init延迟加载及FactoryBean和BeanFactory_第1张图片

你可能感兴趣的:(spring,1024程序员节)