2013-01-20 53 views
3

我是新來的Java和Spring,從C#和.NET世界的未來,所以多多包涵 - 我所試圖做的可能是沒譜......春天依賴注入使用Java容器配置

我正在嘗試使用Java配置和註釋來配置Spring DI,但不是XML配置,但是我遇到了一些問題。這是一個獨立的應用程序,而不是一個Web應用程序。我已經通過the springsource documentation工作,並據我所知,我的基本配置應該是正確的......但不是。請看看下面的代碼:

Java的配置註解類:

package birdalerter.common; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 

import birdalerter.process.ISightingsProcessor; 
import birdalerter.process.SightingsProcessor; 

@Configuration 
@ComponentScan({"birdalerter.process", "birdalerter.common"}) 
public class AppConfig { 
    @Bean 
    @Scope("prototype") 
    public ISightingsProcessor sightingsProcessor(){ 
     return new SightingsProcessor(); 
    } 
} 

配置組件實現ISightingsProcessor接口:

package birdalerter.process; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.LinkedBlockingQueue; 

import org.springframework.stereotype.Component; 

import birdalerter.domainobjects.IBirdSighting; 
@Component 
public class SightingsProcessor implements ISightingsProcessor{ 

    private LinkedBlockingQueue<IBirdSighting> queue; 
    private List<ISightingVisitor> sightingVisitors = new ArrayList<ISightingVisitor>(); 

    public SightingsProcessor(){ 
    } 

    ... 
} 

配置工廠組件:

package birdalerter.process; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Required; 
import org.springframework.context.annotation.Scope; 
import org.springframework.stereotype.Component; 

@Component 
public class ProcessorFactory { 
    private ISightingsProcessor sightingsProcessor; 

    @Autowired 
    @Required 
    private void setSightingsProcessor(ISightingsProcessor sightingsProcessor){ 
     this.sightingsProcessor = sightingsProcessor; 
    } 

    public ISightingsProcessor getSightingsProcessor(){ 
     return this.sightingsProcessor; 
    } 
} 

電線了AnnotationConfigApplicationContext和測試:

@Test 
public void testProcessingDI(){ 
    @SuppressWarnings("resource") 
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 
    context.register(AppConfig.class); 
    context.refresh(); 


    ISightingsProcessor processor = new ProcessorFactory().getSightingsProcessor(); 
    System.out.println(processor); 
    Assert.assertTrue(processor != null); 
} 

的SightingsProcessor沒有被設定器注入和斷言失敗作爲返回的對象爲空。希望我錯過了一些非常明顯的事情。

在此先感謝。

編輯響應梅里:

感謝您的回答梅里。

爲什麼Spring不知道新創建的對象? Spring是否不在整個應用程序生命週期中維護依賴關係,並在創建配置爲Bean的新對象時根據需要進行注入?

我不想直接使用context.getBean(ISightingsProcessor.class),如果我可以幫助它是誠實的,我希望在setter方法中注入的依賴沒有手動干預 - 它看起來更乾淨。

我使用ProcessorFactory作爲ISightingsProcessor接口擴展Runnable - 實現對象將作爲線程啓動。應用程序可配置爲具有n *個線程,每個線程都在循環迭代中啓動。我認爲這是不可能的(我可能是錯的,請告知如果是的話)在方法聲明中有@Autowired註釋,因此我使用工廠提供注入的ISightingsProcessor具體類的新實例。

是我剛剛看了一下關於@Scope註解 - 你是對的,需要移動到AppConfig@Bean聲明(這是我在這個編輯所做的),感謝。

+0

對於SightingsProcessor成員,你不應該在ProcessFactory中擁有@Resource批註嗎? –

+0

如果靜態DI正常工作(儘管存在「@範圍」註釋),它與「ProcessorFactory」中的非靜態「ISightingsProcessor」實例有關。 – Mojo

回答

0
ISightingsProcessor processor = new ProcessorFactory().getSightingsProcessor(); 

這調用了ProcessorFactory的構造函數,然後調用構造函數創建的實例的getter。 Spring不知道這個新創建的對象,因此不會注入它的依賴關係。你應該問春天的ProcessorFactory代替,例如用

ProcessorFactory pf = context.getBean(ProcessorFactory.class); 
ISightingsProcessor processor = pf.getSightingsProcessor(); 

這麼說,我不知道爲什麼你需要一流的ProcessorFactory可言。你還不如直接將ISightingsProcessor:

ISightingsProcessor processor = context.getBean(ISightingsProcessor.class); 

此外,「Java配置」和組件掃描是獨立的方式來聲明豆。目前,您因此聲明瞭兩次ISightingsProcessor:一次使用@ Bean註釋的工廠方法,一次使用組件掃描和類的@Component註釋。做這兩者中的任何一個都行。實際上,兩者都可能導致一個bean定義覆蓋另一個。

哦,並且@Scope註釋用於bean定義(那些註釋用@Bean@Component)。在注射點上可能會被忽略(@Autowired)。