欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中FactoryBean的高級(jí)用法實(shí)戰(zhàn)教程

 更新時(shí)間:2024年09月10日 10:46:55   作者:碼到三十五  
FactoryBean是Spring框架的高級(jí)特性,允許自定義對(duì)象的創(chuàng)建過(guò)程,適用于復(fù)雜初始化邏輯,本文給大家介紹Spring中FactoryBean的高級(jí)用法實(shí)戰(zhàn),感興趣的朋友跟隨小編一起看看吧

前言

FactoryBean 是 Spring 框架中的一個(gè)高級(jí)特性,它允許開發(fā)者通過(guò)自定義的方式控制對(duì)象的創(chuàng)建過(guò)程。當(dāng)需要編寫復(fù)雜的初始化邏輯,而這些邏輯不適合直接放在類的構(gòu)造函數(shù)或初始化方法中時(shí),FactoryBean 提供了一個(gè)很好的解決方案。通過(guò)實(shí)現(xiàn) FactoryBean 接口,可以在一個(gè)單獨(dú)的方法(通常是 getObject())中封裝所有的初始化邏輯,并將這個(gè)邏輯的結(jié)果(即對(duì)象實(shí)例)返回給 Spring 容器。

FactoryBean 接口定義了三個(gè)關(guān)鍵方法:

  • T getObject(): 返回由該工廠創(chuàng)建的對(duì)象的實(shí)例。
  • boolean isSingleton(): 指定返回的實(shí)例是否為單例。
  • Class<?> getObjectType(): 返回 getObject() 方法返回的對(duì)象類型。

Spring 框架內(nèi)部廣泛使用 FactoryBean,提供了超過(guò)50個(gè) FactoryBean 的實(shí)現(xiàn),用于創(chuàng)建和配置各種復(fù)雜的對(duì)象。

下面基于 UserService 類,通過(guò)幾個(gè)實(shí)戰(zhàn)案例來(lái)展示 FactoryBean 的不同用法。

class UserService {
  public void save() {
     System.out.println("save user ...") ;
  }
}

基本用法

在這個(gè)例子中,我們創(chuàng)建了一個(gè)簡(jiǎn)單的 UserServiceFactoryBean,用于創(chuàng)建 UserService 的實(shí)例。

@Component
public class UserServiceFactoryBean implements FactoryBean<UserService> {
    @Override
    public UserService getObject() throws Exception {
        return new UserService();
    }
    @Override
    public Class<?> getObjectType() {
        return UserService.class;
    }
    @Override
    public boolean isSingleton() {
        return true; // 默認(rèn)返回單例
    }
}

使用方式:

@Resource
private UserService userService; // 直接注入
// 或者通過(guò) ApplicationContext 獲取
ApplicationContext context = ...;
UserService us = context.getBean(UserService.class);

創(chuàng)建多例對(duì)象

isSingleton() 方法返回 false,以創(chuàng)建多例對(duì)象。

@Override
public boolean isSingleton() {
    return false; // 返回非單例
}

此時(shí),每次通過(guò) Spring 容器獲取的 UserService 實(shí)例都將是新的,以下兩個(gè)Controller中注入的UserService將是兩個(gè)不同的對(duì)象:

@Component
public class UserController {
  @Resource
  private UserService userService ;
}
@Component
public class CommonService {
  @Resource
  private UserService userService ;
}

創(chuàng)建代理

使用 FactoryBean 創(chuàng)建代理對(duì)象是一種常見(jiàn)用法,尤其是在需要為對(duì)象添加橫切關(guān)注點(diǎn)(如日志、事務(wù)管理等)時(shí)。

@Override
public PersonService getObject() throws Exception {
    ProxyFactory factory = new ProxyFactory(new UserService());
    factory.addAdvice(new MethodInterceptor() {
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("Before method call");
            Object result = invocation.proceed();
            System.out.println("After method call");
            return result;
        }
    });
    return (UserService) factory.getProxy();
}

獲取原始 FactoryBean

有時(shí)候,可能需要獲取 FactoryBean 本身而不是它創(chuàng)建的對(duì)象。

// 通過(guò)類型獲取
UserServiceFactoryBean factoryBean = context.getBean(UserServiceFactoryBean.class);
// 或者通過(guò)名稱獲取,添加 '&' 前綴
UserServiceFactoryBean factoryBeanByName = context.getBean("&userServiceFactoryBean");

利用 SPI 獲取對(duì)象

Spring 提供的 ServiceFactoryBeanServiceListFactoryBean 可以方便地用于基于 SPI 機(jī)制的服務(wù)加載。

@Configuration
public class AppConfig {
    @Bean
    public ServiceFactoryBean<DAO> daoFactoryBean() {
        ServiceFactoryBean<DAO> fb = new ServiceFactoryBean<>();
        fb.setServiceType(Partition.class);
        return fb;
    }
}

META-INF/services 目錄下創(chuàng)建與 Partition 接口全限定名對(duì)應(yīng)的文件,列出所有實(shí)現(xiàn)類的全限定名。Spring 將加載并實(shí)例化這些實(shí)現(xiàn)類,并通過(guò) daoFactoryBean 提供訪問(wèn)。

com.diguobobo.helper.IdPartition
com.diguobobo.helper.DatePratition

容器中注入Partition時(shí),將得到這里的第一個(gè)IdPartition實(shí)例。

ServiceListFactoryBean獲取所有SPI對(duì)象

如果你需要獲取 SPI 接口的所有實(shí)現(xiàn),而不是單個(gè)實(shí)現(xiàn),可以使用 ServiceListFactoryBean。這個(gè) Bean 工廠會(huì)返回一個(gè)包含所有 SPI 實(shí)現(xiàn)的列表。配置方式與 ServiceFactoryBean 類似,但返回的將是一個(gè)列表,而不是單個(gè)對(duì)象。

@Configuration  
public class AppConfig {  
    @Bean  
    public ServiceListFactoryBean<DAO> daoListFactoryBean() {  
        ServiceListFactoryBean<DAO> fb = new ServiceListFactoryBean<>();  
        fb.setServiceType(Partition.class);  
        return fb;  
    }  
}  
// 使用時(shí)注入List<Partition>  
@Autowired  
private List<Partition> daos;

FactoryBean應(yīng)用場(chǎng)景

1. 延遲初始化

默認(rèn)情況下,Spring容器中的Bean會(huì)在容器啟動(dòng)時(shí)進(jìn)行初始化。但是,通過(guò)FactoryBean,你可以控制對(duì)象的創(chuàng)建時(shí)機(jī),直到真正需要該對(duì)象時(shí)才進(jìn)行創(chuàng)建。這可以通過(guò)在FactoryBean中實(shí)現(xiàn)特定的邏輯來(lái)延遲調(diào)用getObject()方法實(shí)現(xiàn)。

2. 依賴注入的高級(jí)用法

FactoryBean允許開發(fā)者在依賴注入過(guò)程中進(jìn)行更精細(xì)的控制。例如,你可以根據(jù)特定的條件動(dòng)態(tài)地選擇不同的Bean實(shí)例進(jìn)行注入,或者根據(jù)環(huán)境變量、配置屬性等動(dòng)態(tài)地創(chuàng)建Bean實(shí)例。

3. 集成第三方庫(kù)

當(dāng)需要將第三方庫(kù)中的對(duì)象集成到Spring容器中時(shí),如果這些對(duì)象的創(chuàng)建過(guò)程比較復(fù)雜或者不符合Spring的默認(rèn)Bean創(chuàng)建規(guī)則,你可以通過(guò)實(shí)現(xiàn)FactoryBean來(lái)封裝這些復(fù)雜的創(chuàng)建邏輯。這樣,就可以像使用其他Spring Bean一樣使用這些第三方庫(kù)中的對(duì)象了。

4. 自定義作用域

雖然FactoryBean本身并不直接提供作用域的定義(作用域通常由Spring容器管理),但你可以通過(guò)FactoryBean來(lái)控制對(duì)象的創(chuàng)建過(guò)程,從而實(shí)現(xiàn)自定義作用域的效果。例如,可以通過(guò)FactoryBean來(lái)管理具有自定義生命周期的對(duì)象,如數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)會(huì)話等。

5. 工廠方法的封裝

有時(shí)可能需要使用某個(gè)類的靜態(tài)工廠方法來(lái)創(chuàng)建對(duì)象實(shí)例。雖然Spring支持通過(guò)@Bean注解來(lái)引用靜態(tài)工廠方法,但實(shí)現(xiàn)FactoryBean提供了一種更加封裝和靈活的方式來(lái)處理這種情況。你可以在FactoryBean中實(shí)現(xiàn)調(diào)用靜態(tài)工廠方法的邏輯,并將FactoryBean本身注冊(cè)為Spring容器中的Bean。

6. 與AOP集成

FactoryBean可以與Spring的AOP(面向切面編程)功能集成,用于在對(duì)象創(chuàng)建過(guò)程中應(yīng)用橫切關(guān)注點(diǎn)(如事務(wù)管理、日志記錄等)。雖然通常這些橫切關(guān)注點(diǎn)會(huì)應(yīng)用在Bean的方法調(diào)用上,但通過(guò)在FactoryBean中實(shí)現(xiàn)特定的邏輯,你也可以在對(duì)象創(chuàng)建過(guò)程中應(yīng)用這些關(guān)注點(diǎn)。

7. 復(fù)雜依賴的解耦

復(fù)雜的應(yīng)用中,Bean之間可能存在復(fù)雜的依賴關(guān)系。通過(guò)實(shí)現(xiàn)FactoryBean,你可以將這些復(fù)雜的依賴關(guān)系封裝在FactoryBean內(nèi)部,從而簡(jiǎn)化Bean之間的依賴關(guān)系。這樣,其他Bean只需要依賴于FactoryBean創(chuàng)建的實(shí)例,而不需要關(guān)心這些實(shí)例背后的復(fù)雜創(chuàng)建邏輯和依賴關(guān)系。

到此這篇關(guān)于Spring中FactoryBean的高級(jí)用法實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)Spring FactoryBean用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot如何使用外部yml啟動(dòng)

    Springboot如何使用外部yml啟動(dòng)

    這篇文章主要介紹了Springboot如何使用外部yml啟動(dòng)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 深入理解java中i++和++i的區(qū)別

    深入理解java中i++和++i的區(qū)別

    下面小編就為大家?guī)?lái)一篇深入理解java中i++和++i的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • Java 程序員容易犯的10個(gè)SQL錯(cuò)誤

    Java 程序員容易犯的10個(gè)SQL錯(cuò)誤

    本文介紹了Java 程序員容易犯的10個(gè)SQL錯(cuò)誤。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • Spring使用xml方式整合第三方框架流程詳解

    Spring使用xml方式整合第三方框架流程詳解

    這篇文章主要介紹了Spring使用xml方式整合第三方框架流程,Spring會(huì)在應(yīng)用上下文中為某個(gè)bean尋找其依賴的bean,Spring中bean有三種裝配機(jī)制,分別是:在xml中顯式配置、在java中顯式配置、隱式的bean發(fā)現(xiàn)機(jī)制和自動(dòng)裝配
    2023-02-02
  • Spring超詳細(xì)講解AOP面向切面

    Spring超詳細(xì)講解AOP面向切面

    面向?qū)ο缶幊淌且环N編程方式,此編程方式的落地需要使用“類”和 “對(duì)象”來(lái)實(shí)現(xiàn),所以,面向?qū)ο缶幊唐鋵?shí)就是對(duì) “類”和“對(duì)象” 的使用,面向切面編程,簡(jiǎn)單的說(shuō),就是動(dòng)態(tài)地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程
    2022-10-10
  • Java基于Tcp的基礎(chǔ)聊天功能實(shí)例

    Java基于Tcp的基礎(chǔ)聊天功能實(shí)例

    這篇文章主要介紹了Java基于Tcp的基礎(chǔ)聊天功能,結(jié)合實(shí)例形式分析了java基于tcp協(xié)議的數(shù)據(jù)傳輸實(shí)現(xiàn)聊天功能相關(guān)操作技巧,需要的朋友可以參考下
    2020-01-01
  • Java將不同的List集合復(fù)制到另一個(gè)集合常見(jiàn)的方法

    Java將不同的List集合復(fù)制到另一個(gè)集合常見(jiàn)的方法

    在Java中,有時(shí)候我們需要將一個(gè)List對(duì)象的屬性值復(fù)制到另一個(gè)List對(duì)象中,使得兩個(gè)對(duì)象的屬性值相同,這篇文章主要介紹了Java將不同的List集合復(fù)制到另一個(gè)集合常見(jiàn)的方法,需要的朋友可以參考下
    2024-09-09
  • Java編程中的一些常見(jiàn)問(wèn)題匯總

    Java編程中的一些常見(jiàn)問(wèn)題匯總

    這篇文章主要介紹了Java編程中的一些常見(jiàn)問(wèn)題匯總,本文總結(jié)的都是一些Java代碼中比較典型的錯(cuò)誤,需要的朋友可以參考下
    2014-09-09
  • 淺談spring-boot 允許接口跨域并實(shí)現(xiàn)攔截(CORS)

    淺談spring-boot 允許接口跨域并實(shí)現(xiàn)攔截(CORS)

    本篇文章主要介紹了淺談spring-boot 允許接口跨域并實(shí)現(xiàn)攔截(CORS),具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • java 如何讀取遠(yuǎn)程主機(jī)文件

    java 如何讀取遠(yuǎn)程主機(jī)文件

    這篇文章主要介紹了java 如何讀取遠(yuǎn)程主機(jī)文件的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02

最新評(píng)論