2016-03-13 62 views
3

我開發了一個自定義Spring Boot自動配置,以減輕與專有消息庫的工作。自定義springboot自動配置不檢測豆

主要的自動配置類本質上是如下:

@Configuration 
@ConditionalOnClass({LibServer.class, LibClient.class}) 
@EnableConfigurationProperties(LibProperties.class) 
public class LibAutoConfiguration { 

    @Autowired 
    LibProperties props; 

    @Bean 
    @ConditionalOnMissingBean(LibServer.class) 
    public LibServer lbServ() { 
     // create and configure a server object 
    } 

    @Bean 
    @ConditionalOnMissingBean(LibClient.class) 
    public LibClient lbClient() { 
     //create and configure a client object 
    } 
} 

看來不過是有條件的註釋沒有檢測到主@SpringBootApplication註解類中聲明豆。

它只檢測在單獨的@Configuration註釋類中聲明的bean。

也就是說,如果我將兩個@Bean註解的方法返回一個LibServer,並在主類我結束了在兩個具有LibServer和兩個LibClient對象(自動配置者和顯式聲明的)一個LibClient對象。

本地彈簧引導自動配置(例如DataSource之一)也可以檢測主類中聲明的bean(例如@Bean註釋方法jdbcTemplate)。

即使對於在主類中聲明的bean,我如何獲得適當的bean檢測?

編輯

一個完整的多模塊Maven項目表現出的行爲是在https://github.com/AlexFalappa/spring-boot-testcase

+0

你的_main class_是什麼樣的,你如何運行你的應用程序? – Morfic

+0

你不是自己導入你的'LibAutoConfiguration',是嗎?自動配置類_must_必須在'spring.factories'中定義,而不是直接加載。在這種情況下,這很重要,因爲我們需要首先處理所有用戶配置,然後檢查是否必須創建這些bean。 –

+0

@StéphaneNic​​oll:我的自定義自動配置位於一個maven模塊中,該模塊包含相關的'spring.factories'文件,並且通過聲明對專有消息庫的依賴,充當起始模塊。該應用程序位於不同的Maven模塊中,這取決於前者。 –

回答

0

你不是自己導入你的LibAutoConfiguration,是嗎?

這是提示:你的主類在你的自動配置類的父包中。所以你實際上是通過組件掃描來導入@Configuration。事實證明,當你處理那個類時(通過顯式的導入而不是通過自動配置),沒有bean被創建,所以它創建它們。您的應用程序類將在稍後處理並創建這些bean。

如果您將定義移到其他地方,它可能會可能工作(因爲您已經用LibConfig自己弄清楚了),但這不是確定性的。

TL;DR確保您的自動配置代碼位於單獨的空間中,並且是而不是組件掃描的目標。我已將您的DemoLibboApplication移至demo包,並且按預期工作。

+0

就是這樣。也許這值得在Spring Boot文檔中創建自己的auto-configuration_部分。 –

+0

好的,我創建了[#5404](https://github.com/spring-projects/spring-boot/issues/5404) –

-1

如果你設置你的調試日誌級別application.propertieslogging.level.org.springframework=DEBUG),你會發現,春節將檢測這兩個定義。然而,你也將看到the order in which this happens may not be what you expected,因爲它是從磁帶庫的配置從主類實例豆第一,事後,因此你會得到2個實例(剝離時間戳,使其友好):

Bean定義這

o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'autoConfigurationReport' 
a.ConfigurationClassBeanDefinitionReader : Registering bean definition for @Bean method af.spring.boot.libbo.LibAutoConfiguration.lbServ() 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'org.springframework.boot.autoconfigure.condition.BeanTypeRegistry' 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'autoConfigurationReport' 
a.ConfigurationClassBeanDefinitionReader : Registering bean definition for @Bean method af.spring.boot.libbo.LibAutoConfiguration.lbClient() 
a.ConfigurationClassBeanDefinitionReader : Registering bean definition for @Bean method af.DemoLibboApplication.libServ() 
a.ConfigurationClassBeanDefinitionReader : Registering bean definition for @Bean method af.DemoLibboApplication.libClient() 

Bean的實例

o.s.b.f.s.DefaultListableBeanFactory  : Creating shared instance of singleton bean 'lbServ' 
o.s.b.f.s.DefaultListableBeanFactory  : Creating instance of bean 'lbServ' 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'libAutoConfiguration' 
Autoconfiguring LibServer 
o.s.b.f.s.DefaultListableBeanFactory  : Eagerly caching bean 'lbServ' to allow for resolving potential circular references 
o.s.b.f.s.DefaultListableBeanFactory  : Finished creating instance of bean 'lbServ' 
o.s.b.f.s.DefaultListableBeanFactory  : Creating shared instance of singleton bean 'lbClient' 
o.s.b.f.s.DefaultListableBeanFactory  : Creating instance of bean 'lbClient' 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'libAutoConfiguration' 
Autoconfiguring LibClient 
o.s.b.f.s.DefaultListableBeanFactory  : Eagerly caching bean 'lbClient' to allow for resolving potential circular references 
o.s.b.f.s.DefaultListableBeanFactory  : Finished creating instance of bean 'lbClient' 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'lib.CONFIGURATION_PROPERTIES' 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor' 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.store' 
o.s.b.f.s.DefaultListableBeanFactory  : Creating shared instance of singleton bean 'libServ' 
o.s.b.f.s.DefaultListableBeanFactory  : Creating instance of bean 'libServ' 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'demoLibboApplication' 
o.s.b.f.s.DefaultListableBeanFactory  : Eagerly caching bean 'libServ' to allow for resolving potential circular references 
o.s.b.f.s.DefaultListableBeanFactory  : Finished creating instance of bean 'libServ' 
o.s.b.f.s.DefaultListableBeanFactory  : Creating shared instance of singleton bean 'libClient' 
o.s.b.f.s.DefaultListableBeanFactory  : Creating instance of bean 'libClient' 
o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'demoLibboApplication' 
o.s.b.f.s.DefaultListableBeanFactory  : Eagerly caching bean 'libClient' to allow for resolving potential circular references 
o.s.b.f.s.DefaultListableBeanFactory  : Finished creating instance of bean 'libClient' 

您還可以看到在AUTO-CONFIGURATION REPORT,在當前的實現當LibAutoConfiguration的條件語句進行評估,它們匹配,通常會創建豆類:

Positive matches: 
----------------- 
... 
LibAutoConfiguration#lbClient matched 
    - @ConditionalOnMissingBean (types: af.libbo.LibClient; SearchStrategy: all) found no beans (OnBeanCondition) 

LibAutoConfiguration#lbServ matched 
    - @ConditionalOnMissingBean (types: af.libbo.LibServer; SearchStrategy: all) found no beans (OnBeanCondition) 
... 

但是,如果添加相同的條件下,以你的主類,你會看到,它會在LibAutoConfiguration根據定義,創建豆,並試圖創造那些DemoLibboApplication時,它實際上找到前面創建的豆類和跳過實例:

Negative matches: 
----------------- 
... 
DemoLibboApplication#libClient did not match 
    - @ConditionalOnMissingBean (types: af.libbo.LibServer; SearchStrategy: all) found the following [lbServ] (OnBeanCondition) 

DemoLibboApplication#libServ did not match 
    - @ConditionalOnMissingBean (types: af.libbo.LibServer; SearchStrategy: all) found the following [lbServ] (OnBeanCondition) 
...