成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

考察你對 Spring 基本功掌握能力

開發 前端
在 Spring Boot 應用程序中,有時需要為同一個類創建多個實例(Bean),并且每個實例可能有不同的配置或用途。雖然可以通過在 @Configuration 配置類中定義多個 @Bean 方法來實現這一點,但在需要創建大量實例的情況下,這種方法不僅冗余,而且難以維護。

1. 簡介

在 Spring Boot 應用程序中,有時需要為同一個類創建多個實例(Bean),并且每個實例可能有不同的配置或用途。雖然可以通過在 @Configuration 配置類中定義多個 @Bean 方法來實現這一點,但在需要創建大量實例的情況下,這種方法不僅冗余,而且難以維護。

在本篇文章中,我們將學習如何在Spring框架中使用注解來創建同一類的多個beans。

2. 實戰案例

2.1 使用Java配置

這是使用注解創建多個同類 bean 的最簡單易行的方法。在這種方法中,我們將使用基于 Java 的配置類來配置同一類中的多個 Bean,如下示例:

public class Person {
  private String name ;
  private Integer age ;


  public Person(String name, Integer age) {
    this.name = name ;
    this.age = age ;
  }
  // getters, setters
  @Override
  public String toString() {
    return "Person [name=" + name+ ", age=" + age+ "]" ;
  }
}

接下來,我們將構建一個名為 PersonConfig 的配置類,并在其中定義 Person 類的多個 Bean:

@Configuration
public class PersonConfig {
  @Bean
  public Person person1() {
    return new Person("Pack", 22) ;
  }


  @Bean
  public Person person2() {
    return new Person("xxgg", 24) ;
  }
}

在這里,@Bean 注解實例化兩個bean,并將它們注冊到Spring容器中。接下來,我們可以初始化Spring容器,并從Spring容器中請求任何bean。這種策略還使得實現依賴注入變得簡單。我們可以使用自動裝配直接將一個bean(例如person1)注入到同類型的另一個bean(例如person2)中。

這種方法的局限是,在典型的基于Java的配置風格中,我們需要使用new關鍵字手動實例化bean。因此,如果相同類的bean數量增加,我們需要先注冊它們,并在配置類中創建這些bean。這使得它成為一種更偏向于Java的方法,而不是Spring特有的方法。

2.2 使用@Component注解

在這種方法中,我們將使用@Component注解來創建多個bean,這些bean將從Person類繼承屬性。首先,我們將創建多個子類,即PersonOne和PersonTwo,它們擴展自Person超類:

@Component
public class PersonOne extends Person {


  public PersonOne() {
    super("Pack", 22) ;
  }
}
@Component
public class PersonTwo extends Person {


  public PersonTwo() {
    super("xxxooo", 24) ;
  }
}

這種方法的問題是,它不會為同一個類創建多個實例。相反,它創建的是從超類繼承屬性的類的bean。因此,我們只能在繼承類沒有定義任何額外屬性的情況下使用這種解決方案。此外,使用繼承會增加代碼的整體復雜性。

2.3 使用BeanFactoryPostProcessor

利用 BeanFactoryPostProcessor 接口的自定義實現來創建同一類的多個 Bean 實例。我們將通過以下步驟來實現:

  • 創建自定義 Bean 類并使用 FactoryBean 接口對其進行配置
  • 使用 BeanFactoryPostProcessor 接口實例化同一類型的多個 Bean 

自定義 Bean 實現

為了更好地理解這種方法,我們將進一步擴展同一實力。假設有一個 Human 類,它依賴于 Person 類的多個實例:

public class Human implements InitializingBean {


  private Person personOne;
  private Person personTwo;


  @Override
  public void afterPropertiesSet() throws Exception {
    Assert.notNull(personOne, "Pack is alive!");
    Assert.notNull(personTwo, "Jook is alive!");
  }
  @Autowired
  public void setPersonOne(Person personOne) {
    this.personOne = personOne ;
    this.personOne.setName("Pack") ;
    this.personOne.setAge(22) ;
  }
  @Autowired
  public void setPersonTwo(Person personTwo) {
    this.personTwo = personTwo ;
    this.personTwo.setName("Jook") ;
    this.personTwo.setAge(24) ;
  }
}

InitializingBean 接口會調用 afterPropertiesSet() 方法來檢查 BeanFactory 是否設置了所有 Bean 屬性,以及是否滿足了其他依賴條件。此外,我們將使用setter注入法注入并初始化兩個 Person 類 Bean:personOne 和 personTwo。接下來,我們將創建一個實現 FactoryBean 接口的 Person 類。

@Qualifier(value = "personOne, personTwo")
public class Person implements FactoryBean<Object> {
  private String name ;
  private Integer age ;


  public Person() {
  }
  public Class<Person> getObjectType() {
      return Person.class ;
  }
  public Object getObject() throws Exception {
      return new Person() ;
  }
  public boolean isSingleton() {
      return true ;
  }
}

這里要注意的是 @Qualifier 注解的使用,它包含了類級別上多個 Person 類型的名稱或 bean id。在這種情況下,在類級別使用 @Qualifier 是有原因的,我們接下來就會看到。

自定義 BeanFactory 實現

任何實現 BeanFactoryPostProcessor 的類都會在創建任何 Spring Bean 之前執行。BeanFactoryPostProcessor 會掃描所有使用 @Qualifier 注釋的類。此外,它還會從注解中提取名稱(Bean ID),并用指定的名稱手動創建該類類型的實例:

public class PersonFactoryPostProcessor implements BeanFactoryPostProcessor {


  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    Map<String, Object> map = beanFactory.getBeansWithAnnotation(Qualifier.class) ;
    for (Map.Entry<String, Object> entry : map.entrySet()) {
      createInstances(beanFactory, entry.getKey(), entry.getValue()) ;
    }
  }


  private void createInstances(ConfigurableListableBeanFactory beanFactory, String beanName, Object bean) {
    Qualifier qualifier = bean.getClass().getAnnotation(Qualifier.class) ;
    for (String name : extractNames(qualifier)) {
      Object newBean = beanFactory.getBean(beanName) ;
      beanFactory.registerSingleton(name.trim(), newBean) ;
    }
  }


  private String[] extractNames(Qualifier qualifier) {
    return qualifier.value().split(",") ;
  }
}

在這里,自定義 BeanFactoryPostProcessor 實現會在 Spring 容器初始化后被調用。

最后,配置上面定義的Human及BeanFactoryPostProcessor

@Configuration
public class PersonConfig {
  @Bean
  public PersonFactoryPostProcessor PersonFactoryPostProcessor() {
    return new PersonFactoryPostProcessor();
  }
  @Bean
  public Person person() {
    return new Person() ;
  }
  @Bean
  public Human human() {
    return new Human() ;
  }
}

這種方法的局限性在于其復雜性。所以不鼓勵使用這種方法。盡管有其局限性,但這種方法更符合 Spring 的特性,可以使用注解實例化多個相似類型的 Bean。

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2010-09-26 08:56:10

Oracle

2014-11-20 14:39:12

網絡傳輸

2024-08-29 08:36:32

2020-10-21 09:18:50

程序員前端Github

2015-01-15 09:21:24

TCP窗口

2025-05-28 08:15:00

字符集編碼字符

2009-10-10 16:57:33

布線工藝要求

2020-11-20 14:16:20

Python開發表格

2017-04-12 10:40:34

公有云

2022-03-31 15:17:04

JavaSocketServlet容器

2020-11-06 09:05:18

前端web開發

2011-07-22 16:43:37

java

2017-02-27 21:30:29

數據中心光纖電纜

2020-12-07 10:38:13

Python開發語言

2011-11-28 09:26:57

2023-06-28 11:58:00

2020-09-16 14:17:42

flat方法

2009-11-10 11:54:12

VB.NET按鈕

2023-06-25 08:38:09

多線程循環打印

2025-04-11 07:50:00

虛析構函數C++開發
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲播放一区 | 国产精品视频区 | 精品欧美一区二区三区久久久 | 可以看黄的视频 | 伊人网影院 | 亚洲精品美女视频 | 伊人久久在线观看 | 国产精品视频一二三区 | 欧美精品乱码久久久久久按摩 | 福利一区在线观看 | 久久国产免费 | 欧美a∨ | 久久精品免费 | 天天干亚洲 | 伊人春色在线观看 | 午夜精品一区二区三区在线观看 | 欧美aⅴ在线观看 | a久久久久久 | 成在线人视频免费视频 | 久久爱综合 | av免费在线观看网站 | 在线永久看片免费的视频 | 国产精品久久久久久一区二区三区 | 亚洲视频在线观看 | 91精品国产综合久久精品 | 91看国产 | 久久久久久久一区二区三区 | 国产精品久久久久久妇女6080 | 久久久人成影片一区二区三区 | 国产免费一级片 | 91久久久久久久久久久久久 | 国产精品一区二区av | 激情三区 | 日本一区二区在线视频 | 香蕉视频91 | 欧美亚洲国产日韩 | 天天看片天天干 | 国产精品久久久久久av公交车 | 男女视频在线观看网站 | 欧美片网站免费 | 成人小视频在线观看 |