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.pswp.cn/news/537152.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537152.shtml
英文地址,請注明出處:http://en.pswp.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…