2017-08-15 55 views
2

我有一個spring應用程序。我是autowiring類,他們工作正常。 對於如Spring在服務器啓動時自動裝入一個類

@Controller 
public class SearchController { 
    @Autowired 
    private EnvironmentControl envControl; 
    @Autowired 
    private SearchControl searchControl; 
... 

但現在我有叫ScheduleServlet服務器啓動類,它使用init方法來安排的東西......

public class SchedulerServlet extends HttpServlet { 
    @Override 
    public void init(ServletConfig config) throws ServletException { 

    super.init(config); 
    this.LOGGER.info("timer servlet is initialized "); 
    try { 
     InitialContext ic = new InitialContext(); 
     TimerManager tm = (TimerManager) ic.lookup("java:comp/env/tm/TimerManager"); 
     Timer timer = tm.schedule(new GlobalTemplateScheduler(), 0, 3600000);// one hour interval 
     System.out.println("Timer..... " + timer); 
    } 
... 

在此我GlobalTemplateScheduler類有計劃執行timerExpired方法每間隔一小時後。

public class GlobalTemplateScheduler implements TimerListener { 

    @Autowired 
    private TemplateControl templateControl; 

    @Override 
    public void timerExpired(Timer timer) { 
     try { 
      templateControl.updateMappings(names); 
     } catch (Exception e) { 
      this.LOGGER.error(e.getMessage()); 
      e.printStackTrace(); 
     } 
... 

所以我必須autowire templateControl我得到空。這應該在服務器啓動時發生。

而且裏面updateMappings有(這是工作在瀏覽器請求正常,但需要做的是在服務器啓動時),也自動裝配作爲構造帶參數的數據源對象。

注:我不能用了ApplicationListener接口。

任何建議將真正幫助。

謝謝。

+1

你可以通過調用new實例化你的GlobalTemplateScheduler。這意味着它在你的控制之下,而不是Spring的。正如您已經發現的那樣,自動裝配註釋在這種情況下不起作用。您必須製作GlobalTemplateScheduler和您的SchedulerServlet Spring bean並對它們進行註釋。請注意:如果此應用程序在羣集中運行,則每個實例都有一個「全局」調度程序。 – duffymo

回答

0

正如我所說的,我是自動裝配了做工精細的豆類。我只需要我的調度程序Servlet中的那些bean。

下面是其工作的解決方案......

在我的servlet調度,我得到了應用程序上下文XML和使用該要求被豆...

ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); 
GlobalTemplateControl globalTemplateControlObject = context.getBean("globalTemplateControl", GlobalTemplateControl.class); 

感謝@duffymo @Amer Qarabsa @ Spindizzy爲您的建議:)

0

在應用程序啓動Bean初始化將不能完成,豆類可以在應用程序上下文刷新後使用或bean的intialization後,它將是沒有意義的執行要求,除非您檢測啓動bean的邏輯無論bean是否準備好。

你可以在bean中執行一些使用@PostConstruct的邏輯,在bean初始化之後執行,這樣你就可以在bean初始化之後操作你的邏輯,或者你可以檢測和執行邏輯在ContextRefreshedEvent之後,通過推送applicationListener並將您的邏輯放入onAppplicationEvent方法中。

0

一個解決方案是你的servlet中使用Spring的容器。爲此目的有許多implementations,例如AnnotationConfigApplicationContext。 Spring的文檔描述瞭如何使用ClassPathXmlApplicationContext

假設GlobalTemplateScheduler也是一個bean,那麼關鍵的一點是:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); 

GlobalTemplateScheduler sheduler = context.getBean("sheduler", GlobalTemplateScheduler.class); 

sheduler.someMethod(); 

的XML,它使用的的ClassPathXmlApplicationContext的含量小。但是你需要啓用組件掃描:我可以建議的另一種方法是使用Spring的DispatcherServlet將所有bean連接在一起。它可以使用相同的XML,只是加載它的問題。好處是,你並不需要自行加載應用程序上下文並啓動一個bean作爲切入點

有很多教程如何使用這個servlet的。

如果您dont't喜歡寫XML,您可以使用WebApplicationInitializer

相關問題