2015-09-17 78 views
1

我正在開發一個Spring Boot應用程序,並嘗試使用基於Java註釋的bean創建(使用@Configuration和@Bean)而不是熟悉的舊的基於XML的bean創建。我很困惑。如果我嘗試在XML中創建一個bean但未能設置@Required屬性,那麼當創建應用程序上下文時,我會得到一個BeanInitializationException。在迄今爲止的基於註釋的bean創建的嘗試中,雖然看起來並不是這樣。Spring @Required屬性創建@Bean帶註釋的bean

例如:

public class MyClass { 
    ... 
    @Required 
    public void setSomeProp(String val){ 
    } 
} 

然後在Spring XML:

<bean class="MyClass"/> 

這將在應用程序啓動(和IntelliJ標誌吧)炸燬,因爲所需的屬性未設置。但是,這似乎不是這樣的:

@Configuration 
public class MyConfig { 
    @Bean 
    public MyClass myClass() { 
     return new MyClass(); 
    } 
} 

即使未設置所需的屬性,此應用程序啓動就好了。我必須在這裏錯過一些東西,因爲這在Spring中似乎是一個非常關鍵的特性。

UPDATE

我做了一些挖&調試和事實證明,在bean定義以某種方式被標記跳過檢查@Required字段設置。在Spring類'RequiredAnnotationBeanPostProcessor'中,布爾方法'shouldSkip()'對於以這種方式創建的bean返回true。當我使用調試器強制該方法返回錯誤的bean創建確實炸燬了預期的異常。

鑑於我正在製作一個非常基本的Spring Boot應用程序,我傾向於(像Zergleb所建議的)將其作爲錯誤提交。

更新2 一些進一步的調試透露,即使場是越來越設置強制檢查仍然拋出同樣的異常,就好像它尚未確定。所以也許敦尼是正確的,並且沒有辦法使用@Bean符號。

+1

提交錯誤報告:https://github.com/spring-projects/spring-boot/issues/3981 – pedorro

回答

1

正如您所說,我也無法獲得@Required如期運行,這可能是一個錯誤,需要報告。我還有一些其他建議對我有用。與@Configuration

//With the bean set up as usual These all worked 
@Bean 
public MyClass myClass() { 
    return new MyClass(); 
} 

註釋

類當你使用組件掃描按預期工作註釋類@Component和負載。(組件掃描部分是很重要的,你要麼需要你@Configuration類,要麼有@ ComponentScan或許刪除@Configuration與@SpringBootApplication取代,這將使掃描組件,而無需將它們連接起來使用@Bean CONFIGS)

使用@Autowired(所需= TRUE)//˚F有BeanCreationException的Bean //不存在類型爲[java.lang。字符串]發現依賴

//No more @Component 
public class MyClass { 
    ... 
    @Autowired(required=true) //Fails 
    public void setSomeProp(String val){ 
    } 
} 

@Autowired需要= FALSE //不會崩潰

public class MyClass { 
    ... 
    @Autowired(required=false) //Simply never gets called if missing 
    public void setSomeProp(String val){ 
    } 
} 

如果test.property缺少@Value //不行的//無法解析佔位符「測試在字符串值.property」「$ {} test.property

public class MyClass { 
    @Value("${test.property}") 
    String someProp; 

    //This getter is not neccesary neither is a setter 
    public String getSomeProp() { 
     return this.someProp; 
    } 
} 

@Value用默認值//不會崩潰//當getSomeProp被稱爲返回‘我的默認值’(除非你有test.property =你的應用中的任何東西cation.properties文件,那麼它會返回「任何東西」

public class MyClass { 
    @Value("${test.property:My Default Value}") 
    String someProp; 

    //This getter is not neccesary neither is a setter 
    public String getSomeProp() { 
     return this.someProp; //Returns "My Default Value" 
    } 
} 

裏面你@Configuration文件也失敗,如果它不能找到任何東西來填充字符串someProp在myClass方法

@Bean 
public MyClass myClass(String someProp) { //Fails being unable to populate this arg 
    MyClass myObj = new MyClass(); 
    myObj.setSomeProp(someProp); 
    return ; 
} 
+0

不幸的是,類定義不在我的控制之下,因此使用@Component和component-scan定義它不是一個選項在這裏。 – pedorro

0

如果這當然不會因爲您自己創建了MyClass的對象(新的MyClass()),因此不會評估註釋。如果使用@Bean方法創建一個bean,那麼容器只會確保所有依賴項都存在(方法參數),並且遵守bean範圍,這意味着如果它是單例bean,則每個應用程序上下文僅創建一個bean 。創建bean /對象本身完全是開發人員的責任。

xml <bean>標籤的等效項用@Component註釋該類,其中該bean完全由容器創建,因此評估註釋。

+0

我對此的進一步調查表明,這實際上應該起作用。目前不存在的唯一原因是它似乎被標記爲跳過該檢查 - 請參閱我的原始問題的更新。 – pedorro

+0

進一步調查你可能就在這裏。在這種情況下,支票似乎只是被打破了,所以他們通過跳過它來解決它。 – pedorro

+0

我在後期使用的示例使用了即使使用@Bean創建bean也要處理的註釋,所以我認爲說不評估註釋是不準確的。 – Zergleb