簡體   English   中英

Spring Java Config擴展了抽象配置

[英]Spring java config extending an abstract configuration

在我們的軟件中,我們使用spring java config。 我們有一個設置,其中一個配置擴展了一個抽象配置。 請看一下這個測試用例:

import java.util.concurrent.atomic.AtomicInteger;
    import org.junit.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    public class SpringConfigTest {

      @Test
      public void test() {
        final AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
        ctx.getBeansOfType(AtomicInteger.class).entrySet().stream().forEach(
            b -> System.out.println(b.getKey() + " : " + b.getValue() + " (" + b.getValue().hashCode() + ")"));
      }

      @Configuration
      public static class MyConfig extends AbstractConfig {

        @Bean(name = "anotherName")
        public AtomicInteger myBean() {
          return new AtomicInteger(5);
        }
      }

      public static abstract class AbstractConfig {

        @Bean
        public AtomicInteger myBean() {
          return new AtomicInteger(10);
        }
      }
    }

這個想法是, MyConfig覆蓋AbstractConfig並且在創建的ApplicationContext中只有一個名為anotherName AtomicInteger類型的bean。

結果是:

anotherName : 5 (2109798150)
myBean : 5 (1074389766)

如此說來,有兩個bean(兩個實例-每個名稱一個),並且更令人驚訝:使用相同的方法( MyConfig#myBean() )創建它們。

這種行為對我們來說似乎很奇怪:我們期望spring要么尊重通常的java繼承方式,僅從MyConfig創建bean ...否則至少會創建兩個獨立的bean(“ 10”和“ 5”)將AbstractConfig視為獨立配置。

在調查此問題時,我們還嘗試在MyConfig類上注冊方法名稱:

public static class MyConfig extends AbstractConfig {

    @Bean(name = ["anotherName", "myBean"])
    public AtomicInteger myBean() {
    ...

這次我們只有一個bean: anotherName : 5 (2109798150)

..對我們來說更是令人驚訝的。

有人知道這是否是正確的行為,還是我們只是錯誤地使用了它? 我們應該在春季的吉拉州提高票價嗎? 提前致謝!

我不是Spring專業人士,但是我會說行為是設計使然。 為了實現您想要的(我希望我猜對了)“注入此bean而不是另一個”,您將在bean上使用@Primary ,以根據情況使用@Conditional@Profile來有選擇地啟用配置。

在Spring中,可以先按類型接線bean,然后按名稱接線。 因此,@Qualifier(“ myBeanName”)可以消除自動裝配具有相同類型的多個bean的歧義,例如

因此:非抽象bean被賦予了另一個名稱這一事實,導致它在應用程序上下文中被視為另一個bean。

您可以在非配置類中聲明Bean。 這稱為“精簡”模式,但在應用程序上下文中它仍然是bean。 另請參見精簡模式下的答案。

我不知道一個bean可以給多個名稱,但是由於默認情況下Spring bean是單例,因此在第二種情況下只能創建一個bean,因為“ myBean”已經存在,並且只有一個bean具有該名稱可以在應用程序上下文中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM