繁体   English   中英

Spring在服务器启动时自动连线一个类

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM