首页 > 编程语言 >Spring源码(9)--FactoryBean简介

Spring源码(9)--FactoryBean简介

时间:2024-09-02 23:47:28浏览次数:6  
标签:FactoryBean return 实例 -- Spring 源码 单例 null throws

FactoryBean简介

FactoryBean 是一个工厂对象,用于创建和管理其他 Bean 的实例。

FactoryBean 接口定义了一种创建 Bean 的方式,它允许开发人员在 Bean 的创建过程中进行更多的自定义操作。

通过实现 FactoryBean 接口,开发人员可以创建复杂的 Bean 实例,或者在 Bean 实例化之前进行一些额外的逻辑处理。

此接口在框架中大量使用,例如用于AOP的org.springframework.AOP.framework.ProxyFactoryBean

或 com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean。

设计模式:

工厂方法。

工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。

详情见: https://blog.csdn.net/sinat_32502451/article/details/133070351

FactoryBean

源码: org.springframework.beans.factory.FactoryBean

FactoryBean 接口具有以下方法:

  • getObject():返回此工厂管理的对象的实例。

  • getObjectType():返回此FactoryBean创建的对象类型。

  • isSingleton():工厂管理的对象是否为单例。

public interface FactoryBean<T> {

	/**
	 * 返回此工厂管理的对象的实例
	 */
	@Nullable
	T getObject() throws Exception;

	/**
	 * 返回此FactoryBean创建的对象类型
	 */
	@Nullable
	Class<?> getObjectType();

	/**
	 * 这个工厂管理的对象是单例吗?也就是说,getObject() 总是返回相同的对象(可以缓存的引用)吗?
	 */
	default boolean isSingleton() {
		return true;
	}

}

AbstractFactoryBean

AbstractFactoryBean 实现了 FactoryBean。

AbstractFactoryBean 是通过 FactoryBean 实现的简单模板超类,根据标志创建单例或原型对象。

	/**
	 *   返回单例实例或创建新的原型实例。
	 */
	@Override
	public final T getObject() throws Exception {
		if (isSingleton()) {
			return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
		}
		else {
			return createInstance();
		}
	}

	/**
	 *  子类必须重写的模板方法,以构造此工厂返回的对象。
	 */
	protected abstract T createInstance() throws Exception;
	
	@Override
	@Nullable
	public abstract Class<?> getObjectType();
	
	/**
	  *   用于销毁单例实例。
	  */
	protected void destroyInstance(@Nullable T instance) throws Exception {
	}

ListFactoryBean

ListFactoryBean 继承了 AbstractFactoryBean。间接实现了 FactoryBean。

ListFactoryBean 是 List实例的简单工厂。允许通过XML bean定义中的“list”元素集中设置列表。

ListFactoryBean 重写了 createInstance(),用于返回 List 类型的数据。

	/**
	 * 重写了 createInstance(),用于返回 List 类型的数据
	 * 
	 */
	protected List<Object> createInstance() {
		if (this.sourceList == null) {
			throw new IllegalArgumentException("'sourceList' is required");
		}
		List<Object> result = null;
		if (this.targetListClass != null) {
			result = BeanUtils.instantiateClass(this.targetListClass);
		}
		else {
			result = new ArrayList<>(this.sourceList.size());
		}
		Class<?> valueType = null;
		if (this.targetListClass != null) {
			valueType = ResolvableType.forClass(this.targetListClass).asCollection().resolveGeneric();
		}
		if (valueType != null) {
			TypeConverter converter = getBeanTypeConverter();
			for (Object elem : this.sourceList) {
				result.add(converter.convertIfNecessary(elem, valueType));
			}
		}
		else {
			result.addAll(this.sourceList);
		}
		return result;
	}

ProxyFactoryBean

源码:org.springframework.aop.framework.ProxyFactoryBean

ProxyFactoryBean 由FactoryBean实现,在Spring BeanFactory中基于bean构建AOP代理。

  /**
    *   返回代理。当客户端从该工厂bean获取bean时调用。
    *   创建此工厂返回的AOP代理的实例。该实例将被缓存为单例,并在每次调用 getObject() 时创建代理。
    */
	@Override
	@Nullable
	public Object getObject() throws BeansException {
	  //初始化切面的责任链
		initializeAdvisorChain();
		if (isSingleton()) {
		  //获取单例对象
			return getSingletonInstance();
		}
		else {
			if (this.targetName == null) {
				logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
						"Enable prototype proxies by setting the 'targetName' property.");
			}
			//获取原型对象
			return newPrototypeInstance();
		}
	}

MybatisSqlSessionFactoryBean

这个类,是mybatis常用配置的类。

源码:com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean

可以看到,在实例化bean对象(此处为SqlSessionFactory )时, 会读取配置的值,才构建sqlSessionFactory。

    @Override
    public SqlSessionFactory getObject() throws Exception {
        if (this.sqlSessionFactory == null) {
            //在返回实例化对象之前的逻辑
            afterPropertiesSet();
        }

        return this.sqlSessionFactory;
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        notNull(dataSource, "SFunction 'dataSource' is required");
        notNull(sqlSessionFactoryBuilder, "SFunction 'sqlSessionFactoryBuilder' is required");
        state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
            "SFunction 'configuration' and 'configLocation' can not specified with together");
        
        // 这里会读取配置的值,构建sqlSessionFactory
        this.sqlSessionFactory = buildSqlSessionFactory();
    }

参考资料:

https://blog.csdn.net/belongtocode/article/details/134631544

标签:FactoryBean,return,实例,--,Spring,源码,单例,null,throws
From: https://www.cnblogs.com/expiator/p/18393752

相关文章

  • 代码随想录算法训练营|Day01 LeetCode 704.二分查找,27.移除元素,977.有序数组的平方
    数组理论基础数组是存放在连续空间上的相同类型数据的集合数组的元素是不能删的,只能覆盖704.二分查找LeetCode:704.有序数组的平方classSolution{public:intsearch(vector<int>&nums,inttarget){intlength=nums.size();inti=0......
  • 飞行员配对方案问题
    借助这道题目,讲一下所有最大流建模的思路对于原问题的解集\(S\)和我们建模之后的网络的可行流集合\(T\),我们需要证明\(\foralls∈S,\existst∈T,|s|=|t|\)(前面一个绝对值符号表示\(s\)的值,后面一个绝对值符号表示\(t\)的最大流)且\(\forallt∈T,\existss∈S,|s|=|t|\)(其实上面......
  • Java-反射
    1.类加载过程类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载等七个阶段。类加载器加载就是将类的class文件读入内存后,创建一个Class对象,这个过程由类加载器完成,类加载器分为三类:启动类加载器该加载器负责加......
  • 工作流之Activiti7 和BPMN讲解
    目录1Activiti1.1简介1.2BPMN1.2.1简介1.2.2符号1.3准备工作1.3.1安装插件1.3.1.1插件1.3.1.2本地网页1.3.2pom依赖1.3.3添加配置1.3.4表介绍1.3.5常用Service服务介绍1.4无校验操作流程1.4.1部署&查看文件1.4.1.1单个文件部署方式1.4.1.2静态类部署1.4.1.3压缩......
  • H. Sakurako's Test
    H.Sakurako'sTestSakurakowillsoontakeatest.Thetestcanbedescribedasanarrayofintegers$n$andataskonit:Givenaninteger$x$,Sakurakocanperformthefollowingoperationanynumberoftimes:Chooseaninteger$i$($1\lei\len$......
  • Typora 适配高版本 Mermaid
    Typora适配高版本Mermaid查看Mermaid版本info下载最新的mermaid.min.js文件在搜索框输入CDNhttps://cdn.jsdelivr.net/npm/mermaid@11/替换Typora的window.html文件<script> constinterval=setInterval(()=>{ console.log('checkmermaid...'); if......
  • 如何高效的阅读paper--三遍阅读法
    第一遍1.阅读文章的标题、摘要和介绍2.阅读每一节的标题和副标题3.阅读总结4.浏览参考文献,看看是否有曾经读过的文章在完成第一遍后,应该做到:1.能够说出该篇论文的类型2.能够说出文章的大概内容与什么相关,基于什么理论解决了什么问题3.文章中的所有假定是否是正确有效的4.......
  • vmware与主机克隆
    目录vmware与主机克隆一实现虚拟机与hosts主机配置文件挂载通信1.配置虚拟机挂载信息2.配置vmware创建共享目录3.实现虚拟机挂载hosts主机目录二linux机器配置开机自动启动脚本三配置修改ip脚本文件vmware与主机克隆工作中会遇到一些情况,比如部署多套集群,需要测试环境,此时......
  • CF 1994 C. Hungry Games (*1600) 思维+二分
    CF1994C.HungryGames(*1600)思维+二分题目链接题意:给你一个长度为\(n\)的关卡,和一个正整数\(x\),初始分数为\(0\),通过每个关卡就会获得对应的分数。但是分数如果超过\(x\),就会清零。现在让你求出满足最终得分不为零的所有子区间数量。思路:正难则反,改求最终得分为......
  • Python用CNN+LSTM+Attention对新闻文本分类、锂离子电池健康、寿命数据预测
    全文链接:https://tecdat.cn/?p=37561原文出处:拓端数据部落公众号 分析师:WeiqiaoJue在当今的数字化时代,数据的爆炸式增长既带来了机遇,也带来了挑战。如何从海量的数据中高效地提取有价值的信息,并进行准确的分类和预测,成为了众多领域亟待解决的关键问题。本研究通过CNN+LSTM+A......