簡體   English   中英

使用Java容器配置的Spring依賴注入

[英]Spring Dependency Injection using Java Container Configuration

我是Java和Spring的新手,來自C#和.NET世界,所以請耐心等待 - 我試圖做的事情可能不合時宜......

我試圖使用Java配置和注釋配置Spring DI,而不是XML配置,但是我遇到了一些問題。 這適用於獨立應用程序,而不是Web應用程序。 我已經完成了springource文檔 ,據我所知,我的基本配置應該是正確的......但事實並非如此。 請看下面的代碼:

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未被設置者注入,並且斷言失敗,因為返回的對象為null。 希望我錯過了一些非常明顯的東西。

提前致謝。

編輯回應Meriton:

謝謝Meriton的回答。

為什么Spring不知道新創建的對象? Spring是否在整個應用程序生命周期中不保持依賴關系,並在創建配置為bean的新對象時適當地注入?

我不想直接使用context.getBean(ISightingsProcessor.class)如果我可以幫助它說實話,我希望在沒有人工干預的情況下在setter方法中注入依賴 - 它看起來更干凈。

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

是的,我剛看了一下@Scope注釋 - 你是對的,需要轉到AppConfig @Bean聲明(我在這個編輯中完成),謝謝你。

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

這將調用ProcessorFactory的構造函數,然后調用構造函數創建的實例的getter。 Spring無法知道新創建的對象,因此不會注入其依賴項。 你應該向Spring詢問ProcessorFactory,例如

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

也就是說,我不知道為什么你需要類ProcessorFactory。 您也可以直接獲取ISightingsProcessor:

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

此外,“基於Java的配置”和組件掃描是聲明bean的獨立方式。 目前,您正在聲明ISightingsProcessor兩次:一次使用@ Bean-annotated工廠方法,一次使用組件掃描和類上的@Component注釋。 做其中任何一件都行。 實際上,兩者都可能導致一個bean定義覆蓋另一個。

哦, @Scope注釋用於bean定義(使用@Bean@Component注釋的那些)。 它可能會被注射點忽略( @Autowired )。

暫無
暫無

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

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