2012-09-12 35 views
2

我有一個自定義的ServletContextListener,用於初始化和啓動Cron4J調度器。在Spring的WebApplicationInitializer中排序監聽器

public class MainListener implements ServletContextListener { 
    @Value("${cron.pattern}") 
    private String dealHandlerPattern; 

    @Autowired 
    private DealMoqHandler dealMoqHandler; 
} 

我在自動綁定監聽某些對象,如圖所示,想爲春天來管理聽者的實例。我通過WebApplicationInitializer使用了編程web.xml配置,但到目前爲止,Listener沒有被自動裝配(每當我嘗試訪問所謂的自動裝配對象時,都是NullPointerExceptions)。

我已經嘗試添加的ContextLoaderListener後添加我的客戶監聽器,如下圖所示:

public class CouponsWebAppInitializer implements WebApplicationInitializer { 
    @Override 
    public void onStartup(ServletContext container) throws ServletException { 
     AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); 
     rootContext.register(SpringAppConfig.class); 

     // Manage the lifecycle of the root application context 
     container.addListener(new ContextLoaderListener(rootContext)); 

     container.addListener(new MainListener()); //TODO Not working 
    } 

我檢查這些過去的問題Spring - Injecting a dependency into a ServletContextListenerdependency inject servlet listener並試圖執行的contextInitialized方法中下面的代碼我聽衆:

WebApplicationContextUtils 
     .getRequiredWebApplicationContext(sce.getServletContext()) 
     .getAutowireCapableBeanFactory() 
     .autowireBean(this); 

不過,我只是得到以下異常:

Exception sending context initialized event to listener instance of class com.enovax.coupons.spring.CouponsMainListener: java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered? 
at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:90) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE] 

如何在添加偵聽器之前確保Spring已經完成實例化?

回答

2

我的錯誤。事實證明原始帖子中的代碼是正確的,並且聽衆正按照正確的順序添加。

問題是我用@WebListener批註(Servlet 3.0)註釋了我的自定義偵聽器。這導致Web應用程序忽略WebApplicationInitializer中的我的addListener()代碼,並實例化Spring的ContextLoaderListener的自定義偵聽器AHEAD。

下面的代碼塊顯示錯誤代碼:

@WebListener /* should not have been added */ 
public class CouponsMainListener implements ServletContextListener { 
    @Autowired 
    private Prop someProp; 
} 
0

不能使用Spring bean使用new - Java不關心春春沒有辦法修改new運營商的行爲。如果您自己創建對象,則需要自己連線。

你還需要小心你在初始化過程中做了什麼。在使用Spring時,使用這個(簡化的)模型:首先,Spring創建所有的bean(所有bean都調用new)。然後開始連線。

所以當你開始使用autowired字段時你必須特別小心。你不能總是立即使用它們,你需要確保Spring完成所有事情的初始化。

在某些情況下,您甚至不能在@PostProcess方法中使用自動佈線字段,因爲Spring由於循環依賴性而無法創建該bean。

所以我的猜測是「每當我嘗試訪問」爲時尚早。

出於同樣的原因,您不能在WebApplicationInitializer中使用WebApplicationContextUtils:尚未完成設置Spring。

+0

我剛纔在調試時意識到,手動實例化對象不允許Spring自動裝載它,就像你說的那樣。儘管我犯了一個完全不同的錯誤(詳細內容在我的自我回答中)。不過,謝謝你的澄清。 –