[英]Spring autowire a class on server startup
我有一个春季申请表。 我正在自动装配课程,并且它们运行良好。 例如
@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的进一步内部,还有一个数据源对象,该对象也被自动装配为构造函数arg(这在浏览器请求上工作正常,但需要在服务器启动时进行)。
注意:我不能使用ApplicationListener接口。
任何建议都会有帮助。
谢谢。
在应用程序启动时,bean的初始化不会完成,可以在应用程序上下文刷新之后或在初始化Bean之后使用Bean,除非您检测到该Bean是否已被启动,否则在启动时执行要求Bean的逻辑是没有意义的。准备好了没。
您可以在bean中使用@PostConstruct执行一些逻辑,该逻辑将在bean初始化之后执行,因此您可以在bean初始化之后以某种方式操纵逻辑,也可以在ContextRefreshedEvent之后通过以下方式检测和执行逻辑:阻碍applicationListener并将逻辑放入onAppplicationEvent方法中。
一种解决方案是在servlet中使用Spring的Container。 有许多用于此目的的实现 ,例如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
就像我说的那样,我正在自动接线的咖啡豆工作正常。 我只需要在Scheduler Servlet中使用那些bean。
这是有效的解决方案...
在我的调度程序servlet中,我获得了应用程序上下文xml并使用了所需的bean。
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
GlobalTemplateControl globalTemplateControlObject = context.getBean("globalTemplateControl", GlobalTemplateControl.class);
感谢@duffymo @Amer Qarabsa @Spindizzy的建议:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.