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

FactoryBean的使用及底層工作原理分析

 更新時間:2026年05月30日 10:10:28   作者:冰點(diǎn).  
FactoryBean接口解析與使用示例,詳解Spring框架中FactoryBean的作用和底層原理,以及如何通過FactoryBean實(shí)現(xiàn)對象的動態(tài)創(chuàng)建is裝配is代理is包裝和生命周期管理

大家好,我是冰點(diǎn),本節(jié)我們通過對FactoryBean 接口源碼解析,以及使用示例剖析,讓大家3分鐘了解FactoryBean的作用和底層工作原理。以及FactoryBean的使用場景,學(xué)以致用。

FactoryBean是Spring框架中的一個接口,用于創(chuàng)建和管理其他Bean實(shí)例的對象。

FactoryBean的底層工作原理是通過實(shí)現(xiàn)FactoryBean接口并實(shí)現(xiàn)其中的方法來創(chuàng)建和管理Bean實(shí)例。

1.FactoryBean接口源碼解析

public interface FactoryBean<T> {
    
    // 獲取由此工廠創(chuàng)建的對象實(shí)例
    T getObject() throws Exception;

    // 獲取由此工廠創(chuàng)建的對象實(shí)例的類型
    Class<?> getObjectType();

    // 判斷由此工廠創(chuàng)建的對象實(shí)例是否為單例模式
    default boolean isSingleton() {
        return true;
    }
}
  • getObject()方法:獲取由此工廠創(chuàng)建的對象實(shí)例,可以在此方法中編寫自定義的創(chuàng)建邏輯,例如從外部資源獲取對象實(shí)例。
  • getObjectType()方法:獲取由此工廠創(chuàng)建的對象實(shí)例的類型,Spring框架可以利用此方法來確定依賴注入時需要注入的具體類型。
  • isSingleton()方法:判斷由此工廠創(chuàng)建的對象實(shí)例是否為單例模式。默認(rèn)情況下,FactoryBean創(chuàng)建的對象實(shí)例是單例模式,但是可以通過覆蓋此方法來改變對象實(shí)例的作用域。

2.FactoryBean使用代碼示例

一個簡單的FactoryBean示例代碼,咱們創(chuàng)建一個隨機(jī)數(shù)生成器的實(shí)例:

import java.util.Random;
import org.springframework.beans.factory.FactoryBean;

public class RandomNumberFactoryBean implements FactoryBean<Random> {

    private int seed;

    public void setSeed(int seed) {
        this.seed = seed;
    }

    @Override
    public Random getObject() throws Exception {
        return new Random(seed);
    }

    @Override
    public Class<?> getObjectType() {
        return Random.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
  • RandomNumberFactoryBean實(shí)現(xiàn)了FactoryBean接口,并實(shí)現(xiàn)了getObject()、getObjectType()和isSingleton()方法。
  • 在getObject()方法中,它返回了一個由seed屬性指定的隨機(jī)數(shù)生成器的實(shí)例。在getObjectType()方法中,它返回了該實(shí)例的類型,即Random類。在isSingleton()方法中,它指定了該實(shí)例是一個單例模式的Bean。

要使用注解方式實(shí)例化RandomNumberFactoryBean,可以使用@Configuration@Bean注解。

首先,創(chuàng)建一個配置類,使用@Configuration注解標(biāo)記該類為配置類。然后,在該類中創(chuàng)建一個用于實(shí)例化RandomNumberFactoryBean@Bean方法,如下所示:

import java.util.Random;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public RandomNumberFactoryBean myRandom() {
        RandomNumberFactoryBean factoryBean = new RandomNumberFactoryBean();
        factoryBean.setSeed(12345);
        return factoryBean;
    }
}

在這個示例中,AppConfig類使用@Configuration注解標(biāo)記為配置類。然后,它定義了一個名為myRandom@Bean方法,該方法返回一個RandomNumberFactoryBean實(shí)例,并為其設(shè)置seed屬性值為12345。

最后,在Spring應(yīng)用程序中,使用AnnotationConfigApplicationContext類來加載該配置類,如下所示:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyApp {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Random random = context.getBean("myRandom", Random.class);
        int number = random.nextInt();
        System.out.println("Random number: " + number);
        context.close();
    }
}

在這個示例中,MyApp類使用AnnotationConfigApplicationContext類來加載AppConfig配置類,并從容器中獲取myRandom Bean實(shí)例。然后,它使用該實(shí)例生成一個隨機(jī)數(shù),并將其輸出到控制臺。

使用注解方式實(shí)例化RandomNumberFactoryBean與使用XML配置方式實(shí)例化它的區(qū)別在于,我們可以在@Bean方法中直接創(chuàng)建RandomNumberFactoryBean實(shí)例,并為其設(shè)置屬性值,而不需要使用XML配置文件。這種方式更加便捷和靈活,可以更方便地進(jìn)行測試和修改。

3. 核心幾個點(diǎn)

  • 當(dāng)Spring容器啟動時,它會掃描應(yīng)用程序中的所有Bean定義,并實(shí)例化那些需要實(shí)例化的Bean。如果遇到實(shí)現(xiàn)了FactoryBean接口的Bean定義,Spring將會為該Bean創(chuàng)建一個特殊的代理對象,以便在需要時調(diào)用FactoryBean的方法來創(chuàng)建實(shí)際的Bean實(shí)例。
  • 當(dāng)需要使用由FactoryBean創(chuàng)建的Bean時,Spring將會調(diào)用代理對象的getObject()方法來獲取實(shí)際的Bean實(shí)例。如果需要,Spring還可以調(diào)用代理對象的getObjectType()方法來確定實(shí)際Bean實(shí)例的類型。
  • 如果FactoryBean創(chuàng)建的Bean是單例模式,那么Spring將在第一次調(diào)用getObject()方法時創(chuàng)建實(shí)例,并將其緩存起來。以后每次調(diào)用getObject()方法時,都會返回同一個實(shí)例。如果FactoryBean創(chuàng)建的Bean不是單例模式,則每次調(diào)用getObject()方法時都會創(chuàng)建一個新的實(shí)例。

4. FactoryBean 到底能干什么

FactoryBean允許我們在創(chuàng)建Bean實(shí)例時編寫自定義的邏輯,并且可以通過其返回的實(shí)際Bean實(shí)例類型來實(shí)現(xiàn)更精細(xì)的依賴注入。同時,Spring框架還提供了一些內(nèi)置的FactoryBean實(shí)現(xiàn),例如ProxyFactoryBeanJndiObjectFactoryBean,可以幫助我們更方便地創(chuàng)建一些常見的Bean實(shí)例。

FactoryBean 是 Spring 框架中的一個接口,它可以創(chuàng)建和管理其他對象的實(shí)例。通過實(shí)現(xiàn) FactoryBean 接口,可以自定義對象的創(chuàng)建過程,可以實(shí)現(xiàn)一些特殊的功能。

FactoryBean 主要有以下作用:

  • 動態(tài)創(chuàng)建對象:FactoryBean 可以根據(jù)配置的參數(shù)和條件,動態(tài)地創(chuàng)建對象。這樣可以根據(jù)不同的情況創(chuàng)建不同的對象實(shí)例。
  • 對象的裝配和初始化:FactoryBean 可以對創(chuàng)建的對象進(jìn)行配置和初始化,可以通過設(shè)置不同的屬性值或者調(diào)用不同的方法來進(jìn)行裝配和初始化。
  • 對象的代理和包裝:通過 FactoryBean 可以對創(chuàng)建的對象進(jìn)行代理和包裝,可以動態(tài)地增加或修改對象的功能。
  • 對象的生命周期管理:FactoryBean 可以管理所創(chuàng)建的對象的生命周期,可以在對象創(chuàng)建前后執(zhí)行一些操作,可以在需要時銷毀對象。
  • 對象的緩存和復(fù)用:FactoryBean 可以實(shí)現(xiàn)對象的緩存和復(fù)用,可以避免重復(fù)創(chuàng)建對象,提高性能。

下面給出幾種常見的 FactoryBean 的使用示例:

  1. 動態(tài)創(chuàng)建對象
public class MyFactoryBean implements FactoryBean<Object> {
    
    @Override
    public Object getObject() throws Exception {
        // 根據(jù)配置或條件動態(tài)創(chuàng)建對象
        if (someCondition) {
            return new MyObject();
        } else {
            return new AnotherObject();
        }
    }

    @Override
    public Class<?> getObjectType() {
        // 返回實(shí)際創(chuàng)建的對象的類型
        return Object.class;
    }

    @Override
    public boolean isSingleton() {
        // 返回是否為單例對象
        return true;
    }
}
  1. 對象的裝配和初始化
public class MyFactoryBean implements FactoryBean<MyObject> {

    private String name;
    private int age;

    @Override
    public MyObject getObject() throws Exception {
        // 創(chuàng)建對象并進(jìn)行裝配和初始化
        MyObject myObject = new MyObject();
        myObject.setName(name);
        myObject.setAge(age);
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 設(shè)置屬性值的方法
    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  1. 對象的代理和包裝
public class MyFactoryBean implements FactoryBean<MyObject> {

    private MyObject target;

    @Override
    public MyObject getObject() throws Exception {
        // 對目標(biāo)對象進(jìn)行代理和包裝
        MyObjectProxy proxy = new MyObjectProxy(target);
        return proxy.getProxy();
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 設(shè)置目標(biāo)對象的方法
    public void setTarget(MyObject target) {
        this.target = target;
    }
}
  1. 對象的緩存和復(fù)用
public class MyFactoryBean implements FactoryBean<MyObject> {

    private static final Map<String, MyObject> objectCache = new ConcurrentHashMap<>();

    private String key;

    @Override
    public MyObject getObject() throws Exception {
        // 根據(jù) key 從緩存中獲取對象,如果不存在則創(chuàng)建并放入緩存
        MyObject myObject = objectCache.get(key);
        if (myObject == null) {
            myObject = new MyObject();
            objectCache.put(key, myObject);
        }
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 設(shè)置 key 值的方法
    public void setKey(String key) {
        this.key = key;
    }
}
  1. 對象的延遲初始化
public class MyFactoryBean implements FactoryBean<MyObject>, InitializingBean {

    private MyObject myObject;

    @Override
    public MyObject getObject() throws Exception {
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 在初始化時創(chuàng)建對象
    @Override
    public void afterPropertiesSet() throws Exception {
        myObject = new MyObject();
        // 執(zhí)行初始化操作
        myObject.init();
    }
}
  1. 對象的銷毀和資源釋放
public class MyFactoryBean implements FactoryBean<MyObject>, DisposableBean {

    private MyObject myObject;

    @Override
    public MyObject getObject() throws Exception {
        return myObject;
    }

    @Override
    public Class<?> getObjectType() {
        return MyObject.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    // 在銷毀時釋放資源
    @Override
    public void destroy() throws Exception {
        // 執(zhí)行銷毀操作
        myObject.release();
    }
}

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot集成mybatis?plus和dynamic-datasource注意事項(xiàng)說明

    springboot集成mybatis?plus和dynamic-datasource注意事項(xiàng)說明

    這篇文章主要介紹了springboot集成mybatis?plus和dynamic-datasource注意事項(xiàng)說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java中使用HashMap時指定初始化容量性能解析

    Java中使用HashMap時指定初始化容量性能解析

    這篇文章主要為大家介紹了Java中使用HashMap時指定初始化容量性能解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • springboot JPA?CriteriaBuilder?如何獲取指定字段

    springboot JPA?CriteriaBuilder?如何獲取指定字段

    這篇文章主要介紹了springboot JPA CriteriaBuilder如何獲取指定字段,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Servlet實(shí)現(xiàn)多文件上傳功能

    Servlet實(shí)現(xiàn)多文件上傳功能

    這篇文章主要為大家詳細(xì)介紹了Servlet實(shí)現(xiàn)文件上傳功能,還可以實(shí)現(xiàn)Servlet多文件上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 關(guān)于java中可變長參數(shù)的定義及使用方法詳解

    關(guān)于java中可變長參數(shù)的定義及使用方法詳解

    下面小編就為大家?guī)硪黄P(guān)于java中可變長參數(shù)的定義及使用方法詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • java?啟動參數(shù)?springboot?idea詳解

    java?啟動參數(shù)?springboot?idea詳解

    這篇文章主要介紹了java?啟動參數(shù)?springboot?idea的相關(guān)知識,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • 淺談JAVA 內(nèi)存流的實(shí)現(xiàn)

    淺談JAVA 內(nèi)存流的實(shí)現(xiàn)

    這篇文章主要介紹了淺談JAVA 內(nèi)存流的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 基于Java生成窮舉字典(數(shù)字+字母(大小寫)+字符)詳解

    基于Java生成窮舉字典(數(shù)字+字母(大小寫)+字符)詳解

    在密碼學(xué)、安全測試以及某些編程挑戰(zhàn)中,生成一個包含所有可能組合的字典文件是非常有用的,下面我們就來看看如何使用Java語言來生成一個包含數(shù)字、字母(大寫和小寫)以及特殊字符的窮舉字典吧
    2025-12-12
  • 工作中禁止使用Executors快捷創(chuàng)建線程池原理詳解

    工作中禁止使用Executors快捷創(chuàng)建線程池原理詳解

    這篇文章主要為大家介紹了工作中禁止使用Executors快捷創(chuàng)建線程池原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 解決使用RestTemplate時報(bào)錯RestClientException的問題

    解決使用RestTemplate時報(bào)錯RestClientException的問題

    這篇文章主要介紹了解決使用RestTemplate時報(bào)錯RestClientException的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論

清水县| 石台县| 孟津县| 灌阳县| 曲水县| 苏尼特左旗| 韶山市| 衡水市| 涡阳县| 揭阳市| 哈密市| 洛浦县| 青海省| 济南市| 昌吉市| 鄂伦春自治旗| 永春县| 获嘉县| 阿勒泰市| 北流市| 寿光市| 明水县| 炎陵县| 中牟县| 瓦房店市| 鹿邑县| 宁远县| 扬州市| 修武县| 新巴尔虎左旗| 漯河市| 习水县| 南安市| 宁陵县| 大渡口区| 定边县| 白水县| 霍邱县| 工布江达县| 措美县| 乡宁县|