2012-11-18 127 views
1
@Service 
public class LogProcessorServiceImpl { 
    @Autowired 
    private static ApplicationConfigurationService applicationConfigurationService; 

    public static void processPageRequestsLogs() { 
     if(applicationConfigurationService==null) { 
      System.out.println("autowire failed"); 
     } 

我有這樣的ApplicationConfigurationService服務autowired到處都是,它工作正常。這個類的包被掃描,所以這不是問題。這可能與這種特定方法的調用方式有關。我有一個在所有其他servlet之後加載的servlet,並且它以60秒的延遲執行上述方法的計時器觸發。我假設所有的自動裝配應該完成。爲什麼Spring autowire會失敗?

public class ProcessSchedulerServlet implements javax.servlet.Servlet { 
    Timer timer=new Timer(); 

    @Override 
    public void init(ServletConfig arg0) throws ServletException { 
     timer.scheduleAtFixedRate(new TimerTask() { 
      public void run() { 
       LogProcessorServiceImpl.processPageRequestsLogs(); 
      } 
     }, 60*1000, 120*1000); 
    } 

這裏就是一旦發生,因爲我真正使用ApplicationConfigurationService:

autowire failed 
Exception in thread "Timer-1" java.lang.NullPointerException 
at com.siteadmin.services.impl.LogProcessorServiceImpl.processPageRequestsLogs(LogProcessorServiceImpl.java:39) 
at com.siteadmin.servlets.ProcessSchedulerServlet$1.run(ProcessSchedulerServlet.java:20) 
at java.util.TimerThread.mainLoop(Timer.java:555) 
at java.util.TimerThread.run(Timer.java:505) 

=== 2012年11月18日================ ============================================

另請參見:How to go about Spring autowiring?

回答

3

你不能在春天自動編寫靜態字段,這是討論的here

作爲替代選擇,如果您的LogProcessorService駐留在root web application context中,您可以使用彈簧WebApplicationContextUtils實用程序類自動裝配它。

public class ProcessSchedulerServlet implements javax.servlet.Servlet { 
    Timer timer=new Timer(); 

    @Autowired 
    LogProcessorService logProcessorService; 

    @Override 
    public void init(ServletConfig arg0) throws ServletException { 
     WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()) 
      .getAutowireCapableBeanFactory().autowireBean(this); 

     final LogProcessorService svc = this.logProcessorService; 
     timer.scheduleAtFixedRate(new TimerTask() { 
     public void run() { 
      svc.processPageRequestsLogs(); 
     } 
     }, 60*1000, 120*1000); 

一般來說,你應該避免使用Java單例,其中使用Spring單例就足夠了。

此外,如果您聲明LogProcessorServiceImpl@Service註釋,這意味着它是一個單身人士,所以你不應該使用靜態字段。

P.S.這個答案是關於自動裝配,它假定這個想法與TimerTask是正確的,在真正的應用程序考慮使用Spring Scheduling API

+0

原來我撒謊,這是我嘗試自動裝配靜態屬性的唯一地方。註釋應該檢測到它被放置在靜態屬性上並報告它的問題。我想知道如果沒有它,我會在春季浪費多少時間。謝謝,鮑里斯。 – jacekn

+0

@jacekn只是一個小小的澄清 - 在這裏我們手動自動裝入ProcessSchedulerServlet的字段,因爲Servlet是使用servlet容器而不是Spring應用程序上下文實例化的。應用程序服務是由Spring管理的主要候選項,所以將它們放到Spring容器中是合理的。 –

相關問題