我有一个弹簧应用程序。我正在自动上课,他们工作正常。 例如
@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();
}
...
所以我必须自动装配templateControl,我得到null。这应该在服务器启动时发生。
进一步在updateMappings里面有一个数据源对象,它也被自动装配为constructor-arg(这在浏览器请求上工作正常但需要在服务器启动时执行)。
注意:我无法使用ApplicationListener接口。
任何建议都会有所帮助。
三江源。
答案 0 :(得分:0)
在应用程序启动时,bean初始化将无法完成,bean可以在应用程序上下文刷新之后或在bean初始化之后使用,在启动时执行需要bean的逻辑是没有意义的,除非您检测是否豆子准备好了。
你可以在bean中使用@PostConstruct执行一些逻辑,这将在bean初始化之后执行,这样你就可以在bean初始化之后以一种方式操作你的逻辑,或者你可以在之后检测并执行逻辑ContextRefreshedEvent通过命令applicationListener并将你的逻辑放在onAppplicationEvent方法中。
答案 1 :(得分:0)
一种解决方案是在servlet中使用Spring的Container。为此目的有许多implementations,例如AnnotationConfigApplicationContext。 Spring的文档描述了如何使用ClassPathXmlApplicationContext
假设GlobalTemplateScheduler也是一个bean,那么关键点是:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
GlobalTemplateScheduler sheduler = context.getBean("sheduler", GlobalTemplateScheduler.class);
sheduler.someMethod();
ClassPathXmlApplicationContext使用的XML内容很小。但是您需要启用组件扫描:
<context:component-scan base-package="foo.bar.baz" />
我可以建议另一种方法是使用Spring的DispatcherServlet将所有bean连接在一起。它可以使用相同的XML,只需加载它即可。好处是您不需要自己加载应用程序上下文并启动bean作为入口点
有很多教程如何使用这个servlet。
如果您不想编写XML,可以使用WebApplicationInitializer
答案 2 :(得分:0)
正如我所说,我自动装配的咖啡豆工作正常。我只需要调度程序Servlet中的那些bean。
这是有效的解决方案......
在我的调度程序servlet中,我获得了应用程序上下文xml并使用了所需的bean ...
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
GlobalTemplateControl globalTemplateControlObject = context.getBean("globalTemplateControl", GlobalTemplateControl.class);
感谢@duffymo @Amer Qarabsa @Spindizzy的建议:)