最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring BeanFactory和FactoryBean有哪些區(qū)別

 更新時(shí)間:2023年02月14日 09:11:13   作者:每天都要進(jìn)步一點(diǎn)點(diǎn)  
這篇文章主要介紹了Spring BeanFactory 與 FactoryBean 的區(qū)別詳情,BeanFactory 和 FactoryBean 的區(qū)別卻是一個(gè)很重要的知識(shí)點(diǎn),在本文中將結(jié)合源碼進(jìn)行分析講解,需要的小伙伴可以參考一下

一、簡(jiǎn)介

在Spring中,有這么2個(gè)接口:BeanFactory和FactoryBean,名字很相似,很多小伙伴經(jīng)常混淆,在面試的時(shí)候也經(jīng)常會(huì)被問BeanFactory和FactoryBean兩者的區(qū)別。本篇文章將詳細(xì)介紹它們的區(qū)別,并結(jié)合示例,幫助大家對(duì)BeanFactory和FactoryBean有一個(gè)很好的認(rèn)識(shí)。

二、BeanFactory

BeanFactory是Spring IoC 容器的頂層接口,主要負(fù)責(zé)實(shí)例化、定位、配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴。

BeanFactory只是一個(gè)接口,并不是IOC容器的具體實(shí)現(xiàn),但是Spring容器給出了很多種實(shí)現(xiàn),如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是附加了某種功能的實(shí)現(xiàn)。BeanFactory主要的實(shí)現(xiàn)類(包括抽象類):

  • AbstractBeanFactory:抽象Bean工廠,絕大部分的實(shí)現(xiàn)類,都是繼承于它;
  • DefaultListableBeanFactory:Spring默認(rèn)的工廠類;
  • XmlBeanFactory:前期使用XML配置用的比較多的時(shí)候用的Bean工廠;
  • AbstractXmlApplicationContext:抽象應(yīng)用容器上下文對(duì)象;
  • ClassPathXmlApplicationContext:從 xml 的配置文件中獲取 bean 并且管理它們;

BeanFactory是Bean工廠,它是一個(gè)接口,定義如下:

public interface BeanFactory {
	/**
	 * 區(qū)分FactoryBean實(shí)例,例如,如果bean命名為myJndiObject是一個(gè)FactoryBean,通過&myJndiObject將返回工廠,而不是由工廠返回的實(shí)例
	 */
	String FACTORY_BEAN_PREFIX = "&";
	/**
	 * 返回指定bean的實(shí)例
	 */
	Object getBean(String name) throws BeansException;
	/**
	 * 返回指定bean的實(shí)例,并指定返回類型
	 */
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	/**
	 * 返回指定bean的實(shí)例,并指定創(chuàng)建bean實(shí)例時(shí)使用的參數(shù)
	 */
	Object getBean(String name, Object... args) throws BeansException;
	/**
	 * 返回的bean實(shí)例唯一匹配給定的對(duì)象類型
	 */
	<T> T getBean(Class<T> requiredType) throws BeansException;
	/**
	 * 返回的bean實(shí)例唯一匹配給定的對(duì)象類型,并指定創(chuàng)建bean實(shí)例時(shí)使用的參數(shù)
	 */
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
	/**
	 * 返回一個(gè)指定bean提供者
	 */
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
	/**
	 * 返回一個(gè)指定bean提供者
	 */
	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
	/**
	 * 判斷工廠中是否包含給定名稱的bean定義,若有則返回true
	 */
	boolean containsBean(String name);
	/**
	 * 判斷bean的作用域是否是singleton:?jiǎn)卫J?
	 */
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	/**
	 * 判斷bena的作用域是否是prototype:多例模式
	 */
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
	/**
	 * 檢查具有指定名稱的bean是否與指定的類型匹配
	 */
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
	/**
	 * 檢查具有指定名稱的bean是否與指定的類型匹配
	 */
	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
	/**
	 * 用給定的名稱確定bean的類型
	 */
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;
	/**
	 * 用給定的名稱確定bean的類型
	 */
	@Nullable
	Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
	/**
	 * 返回給定bean名稱的所有別名 
	 */
	String[] getAliases(String name);
}

下面列舉一下ClassPathXmlApplicationContext的使用示例:

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-config.xml");
User user = (User) applicationContext.getBean("user");
user.hello();

三、FactoryBean

一般情況下,Spring通過反射利用bean的class屬性指定實(shí)現(xiàn)類來實(shí)例化bean。在某些情況下,實(shí)例化bean的過程比較復(fù)雜,如果按照傳統(tǒng)的方式,則需要在<bean>中提供大量的配置信息,配置方式的靈活性是受限的,這時(shí)采用編碼的方式可能會(huì)得到一個(gè)簡(jiǎn)單的方案。

Spring為此提供了一個(gè)FactoryBean工廠類接口,用戶可以通過實(shí)現(xiàn)該接口定制實(shí)例化bean的邏輯。

FactoryBean是一個(gè)能生產(chǎn)或修飾對(duì)象生成的工廠Bean,當(dāng)我們實(shí)現(xiàn)了FactoryBean接口,重寫getObject()方法并返回一個(gè)實(shí)例時(shí),Spring會(huì)按照我們指定的內(nèi)容去注冊(cè)Bean,來達(dá)到定制實(shí)例化Bean的效果。

FactoryBean定義如下:

public interface FactoryBean<T> {
	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
	/**
	 * 返回需要?jiǎng)?chuàng)建的Bean
	 */
	@Nullable
	T getObject() throws Exception;
	/**
	 * 返回FactoryBean創(chuàng)建的Bean類型
	 */
	@Nullable
	Class<?> getObjectType();
	/**
	 * 是否單例Bean,默認(rèn)是單例的,存入Spring容器中單例緩存池
	 */
	default boolean isSingleton() {
		return true;
	}
}

當(dāng)配置文件中<bean>的class屬性配置的實(shí)現(xiàn)類是FactoryBean時(shí),通過getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的對(duì)象,相當(dāng)于FactoryBean#getObject()代理了getBean()方法。

下面我們通過一個(gè)簡(jiǎn)單的FactoryBean案例,實(shí)現(xiàn)自定義注入Bean對(duì)象:

public class Student implements Serializable {
    private String id;
    private String name;
    private int age;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
@Component
public class MyFactoryBean implements FactoryBean<Student> {
    @Override
    public Student getObject() throws Exception {
        Student student = new Student();
        student.setId(UUID.randomUUID().toString());
        student.setName("張三");
        student.setAge(20);
        return student;
    }
    @Override
    public Class<?> getObjectType() {
        return Student.class;
    }
    @Override
    public boolean isSingleton() {
        return true;
    }
}

簡(jiǎn)單測(cè)試一下Spring是否幫助我們創(chuàng)建Student這個(gè)Bean對(duì)象:

public void test2() {
        System.out.println("========返回工廠中的實(shí)例========");
        //返回工廠中的實(shí)例,調(diào)用FactoryBean.getObject()創(chuàng)建實(shí)例
        Student student1 = (Student) applicationContext.getBean("myFactoryBean");
        System.out.println(student1);
        System.out.println("========返回工廠本身========");
        //返回工廠本身,通過構(gòu)造方法初始化實(shí)例
        Object bean = applicationContext.getBean("&myFactoryBean");
        System.out.println(bean);
    }

運(yùn)行結(jié)果如下:

========返回工廠中的實(shí)例========
Student{id='5aa54f31-3d4a-4bc0-989a-5149f393c3db', name='張三', age=20}
========返回工廠本身========
com.wsh.springtransactiondemo.factorybean.MyFactoryBean@24e95e44

可以看到,根據(jù)"myFactoryBean"的名稱獲取到的實(shí)際上是FactoryBean工廠調(diào)用getObject()返回的對(duì)象,而不是MyFactoryBean工廠本身,如果要獲取MyFactoryBean工廠本身實(shí)例,那么需要在名稱前面加上'&'符號(hào)。如下:

  • getBean("myFactoryBean"):返回MyFactoryBean工廠中g(shù)etObject()方法返回的實(shí)例對(duì)象;
  • getBean("&myFactoryBean"):返回MyFactoryBean工廠本身的實(shí)例;

為什么要使用FactoryBean?

在某些情況下,對(duì)于實(shí)例Bean對(duì)象比較復(fù)雜的情況下,如果使用傳統(tǒng)方式創(chuàng)建bean會(huì)比較復(fù)雜,如xml配置繁瑣等,于是Spring就提供了FactoryBean接口,讓用戶通過實(shí)現(xiàn)該接口來自定義該Bean接口的實(shí)例化過程。

四、總結(jié)

Spring 中為我們提供了兩種類型的 bean,一種就是普通的 bean,我們通過getBean(id) 方法獲得是該 bean 的實(shí)際類型,另外還有一種 bean是FactoryBean,也就是工廠 bean,我們通過getBean(id) 獲得是該工廠所產(chǎn)生的 Bean的實(shí)例,而不是FactoryBean的實(shí)例。

  • BeanFactory:Bean工廠,它是一個(gè)用于管理Bean的一個(gè)工廠,在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)來進(jìn)行管理的;
  • FactoryBean:工廠Bean,它是一個(gè)支持我們自定義Bean對(duì)象的工廠;

到此這篇關(guān)于Spring BeanFactory和FactoryBean有哪些區(qū)別的文章就介紹到這了,更多相關(guān)Spring BeanFactory和FactoryBean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)動(dòng)態(tài)代理的實(shí)例代碼

    Java實(shí)現(xiàn)動(dòng)態(tài)代理的實(shí)例代碼

    代理模式是常用的java設(shè)計(jì)模式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等,這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)動(dòng)態(tài)代理的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • zookeeper監(jiān)聽器原理的詳解

    zookeeper監(jiān)聽器原理的詳解

    今天小編就為大家分享一篇關(guān)于zookeeper監(jiān)聽器原理的詳解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 淺談Spring Cloud中的API網(wǎng)關(guān)服務(wù)Zuul

    淺談Spring Cloud中的API網(wǎng)關(guān)服務(wù)Zuul

    這篇文章主要介紹了淺談Spring Cloud中的API網(wǎng)關(guān)服務(wù)Zuul,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • spring解決循環(huán)依賴

    spring解決循環(huán)依賴

    這篇文章主要介紹了spring如何解決循環(huán)依賴,幫助大家更好的理解和使用spring框架,感興趣的朋友可以了解下
    2020-09-09
  • SpringBoot實(shí)現(xiàn)MQTT消息發(fā)送和接收方式

    SpringBoot實(shí)現(xiàn)MQTT消息發(fā)送和接收方式

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)MQTT消息發(fā)送和接收方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java 二分法檢索算法代碼實(shí)現(xiàn)詳解

    Java 二分法檢索算法代碼實(shí)現(xiàn)詳解

    這篇文章主要介紹了Java 二分法檢索算法代碼實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • Java基于接口實(shí)現(xiàn)模擬動(dòng)物聲音代碼實(shí)例

    Java基于接口實(shí)現(xiàn)模擬動(dòng)物聲音代碼實(shí)例

    這篇文章主要介紹了Java基于接口實(shí)現(xiàn)模擬動(dòng)物聲音代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Java集合框架概覽之ArrayList源碼刨析

    Java集合框架概覽之ArrayList源碼刨析

    本文主要從一個(gè)簡(jiǎn)單的代碼入手,對(duì)ArrayList?的最常用的源碼進(jìn)行刨析,文中源碼摘自?JDK1.8,源碼的注釋部分博主也加入了自己的翻譯,歡迎讀者食用
    2023-03-03
  • 關(guān)于mybatis的一級(jí)緩存和二級(jí)緩存的那些事兒

    關(guān)于mybatis的一級(jí)緩存和二級(jí)緩存的那些事兒

    MyBatis自帶的緩存有一級(jí)緩存和二級(jí)緩存,今天我們就來學(xué)習(xí)一下,文中有非常詳細(xì)的總結(jié),對(duì)正在學(xué)習(xí)的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • 從Springboot項(xiàng)目中下載文件的具體過程

    從Springboot項(xiàng)目中下載文件的具體過程

    最近在做一個(gè)臨時(shí)的項(xiàng)目,APP端在檢測(cè)到程序有更新時(shí),需要去后臺(tái)下載新的安裝包,接下來通過本文給大家分享從Springboot項(xiàng)目中下載文件的具體過程,感興趣的朋友一起看看吧
    2021-07-07

最新評(píng)論

大石桥市| 揭阳市| 南陵县| 阿巴嘎旗| 高雄市| 景德镇市| 梅河口市| 新绛县| 盖州市| 呼和浩特市| 类乌齐县| 六盘水市| 永昌县| 镇宁| 和硕县| 泾源县| 蓬溪县| 浦城县| 改则县| 南召县| 宝坻区| 赤水市| 清苑县| 昌宁县| 长宁区| 三亚市| 和平区| 息烽县| 温州市| 汉川市| 黄大仙区| 东宁县| 枝江市| 聂荣县| 嘉兴市| 辉县市| 鹤峰县| 中江县| 延庆县| 科尔| 镇坪县|