Spring中BeanFactory和FactoryBean的区别

先介绍一下Spring的IOC容器到底是个什么东西,都说是一个控制反转的容器,将对象的控制权交给IOC容器,其实在看了源代码之后,就会发现IOC容器只是一个存储单例的一个ConcurrentHashMap<String, BeanDefinition>

BeanDefinition只是一个将Object包装的对象,带有实例的其他属性,比如对应的Class等,而Spring默认创建的IOC容器为new DefaultListableBeanFactory(),可以看一下这个对象的属性

	/** Map from serialized id to factory instance. */private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =new ConcurrentHashMap<>(8);/** Optional id for this factory, for serialization purposes. */@Nullableprivate String serializationId;/** Whether to allow re-registration of a different definition with the same name. */private boolean allowBeanDefinitionOverriding = true;/** Whether to allow eager class loading even for lazy-init beans. */private boolean allowEagerClassLoading = true;/** Optional OrderComparator for dependency Lists and arrays. */@Nullableprivate Comparator<Object> dependencyComparator;/** Resolver to use for checking if a bean definition is an autowire candidate. */private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();/** Map from dependency type to corresponding autowired value. */private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);//这个Map就是专门储存实例的/** Map of bean definition objects, keyed by bean name. */private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);/** Map of singleton and non-singleton bean names, keyed by dependency type. */private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);/** Map of singleton-only bean names, keyed by dependency type. */private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);/** List of bean definition names, in registration order. */private volatile List<String> beanDefinitionNames = new ArrayList<>(256);/** List of names of manually registered singletons, in registration order. */private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);/** Cached array of bean definition names in case of frozen configuration. */@Nullableprivate volatile String[] frozenBeanDefinitionNames;/** Whether bean definition metadata may be cached for all beans. */private volatile boolean configurationFrozen = false;

而DefaultListableBeanFactory继承了BeanFactory的接口,并实现的这些方法。

BeanFactory

BeanFactory是Spring最核心的接口,也是Spring中最开始的地方,这个接口定义了一些常用的方法,也标明了常用方法的定义

public interface BeanFactory {/*** Used to dereference a {@link FactoryBean} instance and distinguish it from* beans <i>created</i> by the FactoryBean. For example, if the bean named* {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}* will return the factory, not the instance returned by the factory.*/String FACTORY_BEAN_PREFIX = "&";//key值获取实例,也叫按bean的名称或ID获取对应的实例Object getBean(String name) throws BeansException;//按bean名称以及对应的class获取实例<T> T getBean(String name, Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;//按class类型获取bean实例<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);//判断是否有对应的bean名称boolean containsBean(String name);//判断对应的bean名称是否为单例boolean isSingleton(String name) throws NoSuchBeanDefinitionException;//判断对应的bean名称是否为多例boolean isPrototype(String name) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;//按bean名称获取对应的class@NullableClass<?> getType(String name) throws NoSuchBeanDefinitionException;String[] getAliases(String name);}

不过这里面有个常量FACTORY_BEAN_PREFIX这个跟FactoryBean有关。

FactoryBean

也是注入Bean实现的一种方法,先看一下这个接口:

public interface FactoryBean<T> {//获取对象@NullableT getObject() throws Exception;//获取对象对应的class@NullableClass<?> getObjectType();//是否为单例,默认为是default boolean isSingleton() {return true;}}

用法是实现这个接口,并且注入到Spring的IOC容器当中,示例:

@Component
public class SpringTest03FactoryBean implements FactoryBean<Fish> {public Fish getObject() throws Exception {return new Fish();}public Class<?> getObjectType() {return Fish.class;}public boolean isSingleton() {return true;}}

当时在从容器中取这个对应的bean名称的时候,确实返回getObject()中返回的对象,但是如果需要获取这个FactoryBean的对象的话,需在bean名称前面加个&,才能获取到对应的FactoryBean实现类的实例

这个看起来用的不多但是,在Mybatis和Spring的融合包中能够看到FactoryBean的身影,是专门将动态代理的dao接口注入到Spring的容器当中,这个后面再说

接下来看看在Spring源码中是在哪里处理了这个&符号

在Spring加载FactoryBean的时候,仅仅是将它当作一个普通的Bean注入

而在getBean的时候就会有区分

在AbstractBeanFactory的1658行,如果带有&则直接返回FactoryBean的实例

否则接着往下走

直接获取 factoryBeanObjectCache 对应的key值,没有话会先加载到factoryBeanObjectCache 

这两种其实是两个不同的类,只是名字看着看不多而已

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中数字和字符串可以直接相加_用c语言或者python将文件中特定字符串后面的数字相加...

匿名用户1级2014-08-31 回答代码应该不难吧。既然用爬虫爬下来了&#xff0c;为什么爬取数据的时候没做处理呢。之前用过Scrapy爬虫框架&#xff0c;挺好用的&#xff0c;你可研究下。代码&#xff1a;#!codingutf-8import osimport reimport random# 获取当前目录文件列表def …

Spring中Aware的用法以及实现

Aware 在Spring当中有一些内置的对象是未开放给我们使用的&#xff0c;例如Spring的上下文ApplicationContext、环境属性Environment&#xff0c;BeanFactory等等其他的一些内置对象&#xff0c;而在我们可以通过实现对应的Aware接口去拿到我们想要的一些属性&#xff0c;一般…

c#字符型转化为asc_C#字符串和ASCII码的转换

//字符转ASCII码&#xff1a;public static int Asc(string character){if (character.Length 1){System.Text.ASCIIEncoding asciiEncoding new System.Text.ASCIIEncoding();int intAsciiCode (int)asciiEncoding.GetBytes(character)[0];return (intAsciiCode);}else{thr…

topcoder srm 625 div1

problem1 link 假设第$i$种出现的次数为$n_{i}$&#xff0c;总个数为$m$&#xff0c;那么排列数为$T\frac{m!}{\prod_{i1}^{26}(n_{i}!)}$ 然后计算回文的个数&#xff0c;只需要考虑前一半&#xff0c;得到个数为$R$&#xff0c;那么答案为$\frac{R}{T}$. 为了防止数字太大导致…

Spring的组件赋值以及环境属性@PropertySource

PropertySource 将指定类路径下的.properties一些配置加载到Spring当中&#xff0c; 有个跟这个差不多的注解PropertySources Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented public interface PropertySources {PropertySource[] value();} 使用…

python语音识别框架_横评:五款免费开源的语音识别工具

编者按&#xff1a;本文原作者 Cindi Thompson&#xff0c;美国德克萨斯大学奥斯汀分校(University of Texas at Austin)计算机科学博士&#xff0c;数据科学咨询公司硅谷数据科学(Silicon Valley Data Science&#xff0c;SVDS)首席科学家&#xff0c;在机器学习、自然语言处理…

csharp read excel file get sheetName list

1 /// <summary>2 /// 3 /// 塗聚文4 /// 201208035 /// Geovin Du6 ///找到EXCEL的工作表名称 要考慮打開的文件的進程問題7 /// </summary>8 /// <param name"filename">…

Spring Bean的生命周期以及IOC源码解析

IOC源码这一块太多只能讲个大概吧&#xff0c;建议还是去买本Spring IOC源码解析的书来看比较好&#xff0c;我也是自己看源代码以及视频整理的笔记 Bean的生命周期大概可以分为四个阶段&#xff0c;具体的等会再说&#xff0c;先看看IOC的源码吧 1、bean的创建 2、bean的属…

python3绘图_python3绘图示例2(基于matplotlib:柱状图、分布图、三角图等)

#!/usr/bin/env python# -*- coding:utf-8 -*-from matplotlib import pyplot as pltimport numpy as npimport pylabimport os,sys,time,math,random# 图1-给已有的图加上刻度filer‘D:\jmeter\jmeter3.2\data\Oracle数据库基础.png‘arrnp.array(file.getdata()).reshape(fil…

bzoj4152-[AMPPZ2014]The_Captain

Description 给定平面上的n个点&#xff0c;定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|)&#xff0c;求从1号点走到n号点的最小费用。 Input 第一行包含一个正整数n(2<n<200000)&#xff0c;表示点数。 接下来n行&#xff0c;每行包含两个整数x[i],yi&#xff0c;…

python日志统计_python试用-日志统计

最近两天尝试用python代替bash写Linux Shell脚本来统计日志。发现python写起来比bash更简单和容易阅读&#xff0c;发现不少惊喜。所以写了一个粗糙的脚本来统计日志。目标1、通过简单命令和脚本统计事件发生数2、日志限定文本类型假定环境日志文件&#xff1a;1.logtest:aaa,1…

Spring AOP两种使用方式以及如何使用解析

AOP是一种面向切面编程思想&#xff0c;也是面向对象设计&#xff08;OOP&#xff09;的一种延伸。 在Spring实现AOP有两种实现方式&#xff0c;一种是采用JDK动态代理实现&#xff0c;另外一种就是采用CGLIB代理实现&#xff0c;Spring是如何实现的在上篇已经讲到了Spring Be…

如何用python生成可执行程序必须经过_python怎么生成可执行文件

.py文件&#xff1a;对于开源项目或62616964757a686964616fe58685e5aeb931333363393664者源码没那么重要的&#xff0c;直接提供源码&#xff0c;需要使用者自行安装Python并且安装依赖的各种库。(Python官方的各种安装包就是这样做的).pyc文件&#xff1a;有些公司或个人因为机…

Jmeter 老司机带你一小时学会Jmeter

Jmeter的安装 官网下载地址&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 作为Java应用&#xff0c;是需要JDK环境的&#xff0c;因此需要下载安装JAVA&#xff0c;并且作必要的的环境变量配置。 一、bin目录 examples:    目录中有CSV样例 jmeter.bat/jmeter…

MongoDB位运算基本使用以及位运算应用场景

最近在公司业务上用到了二进制匹配数据&#xff0c;但是MongoDB进行二进制运算&#xff08;Bitwise&#xff09;没用过&#xff0c;网上博客文章少&#xff0c;所以就上官网看API&#xff0c;因此记录一下&#xff0c;顺便在普及一下使用二进制位运算的一些应用。 在MongoDB的…

好用的下拉第三方——nicespinner

1.简介 GitHub地址&#xff1a;https://github.com/arcadefire/nice-spinner Gradle中添加&#xff1a; allprojects {repositories {...maven { url "https://jitpack.io" }} }dependencies {implementation com.github.arcadefire:nice-spinner:1.3.7 }2.使用 xml文…

Mybatis配置文件参数定义

官网有时候进不去&#xff0c;所以就记录一下Mybatis的配置文件的各项参数定义&#xff0c;大家也可以上官网查询&#xff0c;官方文档&#xff0c;进不进的去看各自的缘分了 properties 定义配置&#xff0c;在这里配置的属性可以在整个配置文件使用&#xff1b;可以加载指定…

python和java后期发展_Python与java的发展前景谁最大

Python和Java是目前IT行业内两大编程语言&#xff0c;很多人都喜欢拿来比较&#xff0c;一个是后起之秀&#xff0c;潜力无限&#xff1b;一个是行业经典&#xff0c;成熟稳定。对于许多想从事IT行业的同学来说&#xff0c;这两门语言真的很难抉择。那么&#xff0c;Python和Ja…

JDK源码学习笔记——Enum枚举使用及原理

一、为什么使用枚举 什么时候应该使用枚举呢&#xff1f;每当需要一组固定的常量的时候&#xff0c;如一周的天数、一年四季等。或者是在我们编译前就知道其包含的所有值的集合。 利用 public final static 完全可以实现的功能&#xff0c;为什么要使用枚举&#xff1f; public…