Spring在服务器启动时自动装入一个类
我有一个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接口。
任何建议将真正帮助。
谢谢。
正如我所说的,我是自动装配了做工精细的豆类。我只需要我的调度程序Servlet中的那些bean。
下面是其工作的解决方案......
在我的servlet调度,我得到了应用程序上下文XML和使用该要求被豆...
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
GlobalTemplateControl globalTemplateControlObject = context.getBean("globalTemplateControl", GlobalTemplateControl.class);
感谢@duffymo @Amer Qarabsa @ Spindizzy为您的建议:)
在应用程序启动Bean初始化将不能完成,豆类可以在应用程序上下文刷新后使用或bean的intialization后,它将是没有意义的执行要求,除非您检测启动bean的逻辑无论bean是否准备好。
你可以在bean中执行一些使用@PostConstruct的逻辑,在bean初始化之后执行,这样你就可以在bean初始化之后操作你的逻辑,或者你可以检测和执行逻辑在ContextRefreshedEvent之后,通过推送applicationListener并将您的逻辑放入onAppplicationEvent方法中。
一个解决方案是你的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
你可以通过调用new实例化你的GlobalTemplateScheduler。这意味着它在你的控制之下,而不是Spring的。正如您已经发现的那样,自动装配注释在这种情况下不起作用。您必须制作GlobalTemplateScheduler和您的SchedulerServlet Spring bean并对它们进行注释。请注意:如果此应用程序在群集中运行,则每个实例都有一个“全局”调度程序。 – duffymo