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

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

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

前言

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

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

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

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

下面基于 UserService 類,通過幾個實戰(zhàn)案例來展示 FactoryBean 的不同用法

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

基本用法

在這個例子中,我們創(chuàng)建了一個簡單的 UserServiceFactoryBean,用于創(chuàng)建 UserService 的實例。

@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; // 直接注入
// 或者通過 ApplicationContext 獲取
ApplicationContext context = ...;
UserService us = context.getBean(UserService.class);

創(chuàng)建多例對象

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

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

此時,每次通過 Spring 容器獲取的 UserService 實例都將是新的,以下兩個Controller中注入的UserService將是兩個不同的對象:

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

創(chuàng)建代理

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

@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

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

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

利用 SPI 獲取對象

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 接口全限定名對應(yīng)的文件,列出所有實現(xiàn)類的全限定名。Spring 將加載并實例化這些實現(xiàn)類,并通過 daoFactoryBean 提供訪問。

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

容器中注入Partition時,將得到這里的第一個IdPartition實例。

ServiceListFactoryBean獲取所有SPI對象

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

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

FactoryBean應(yīng)用場景

1. 延遲初始化

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

2. 依賴注入的高級用法

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

3. 集成第三方庫

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

4. 自定義作用域

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

5. 工廠方法的封裝

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

6. 與AOP集成

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

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

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

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

相關(guān)文章

  • Springboot如何使用外部yml啟動

    Springboot如何使用外部yml啟動

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

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

    下面小編就為大家?guī)硪黄钊肜斫鈐ava中i++和++i的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • Java 程序員容易犯的10個SQL錯誤

    Java 程序員容易犯的10個SQL錯誤

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

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

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

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

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

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

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

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

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

    Java編程中的一些常見問題匯總

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

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

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

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

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

最新評論