[英]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.