Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 从后台任务注入依赖项_Spring_Spring Mvc_Dependency Injection - Fatal编程技术网

Spring 从后台任务注入依赖项

Spring 从后台任务注入依赖项,spring,spring-mvc,dependency-injection,Spring,Spring Mvc,Dependency Injection,我是spring的新手,我正在尝试找出如何将对象自动关联到控制器。该对象是在运行时从使用ServletContextListener启动和停止的任务创建的。我如何告诉spring应用程序上下文这个对象 更多详细信息 我的后台任务是用下面的代码开始的。我希望将警报服务器对象连接到控制器。我可以修改这个类来做到这一点吗 @WebListener public class ExecutorContextListener implements ServletContextListener { pr

我是spring的新手,我正在尝试找出如何将对象自动关联到控制器。该对象是在运行时从使用ServletContextListener启动和停止的任务创建的。我如何告诉spring应用程序上下文这个对象

更多详细信息

我的后台任务是用下面的代码开始的。我希望将
警报服务器
对象连接到控制器。我可以修改这个类来做到这一点吗

@WebListener
public class ExecutorContextListener implements ServletContextListener
{
   private static Logger log = Logger.getLogger(ExecutorContextListener.class);

   Thread backgroundThread;
   AlertServer alertServer;

   @Override
   public void contextInitialized(ServletContextEvent event)
   {
      // Start the AlertServer
      alertServer = new AlertServer();

      backgroundThread = new Thread(alertServer, "AlertServer");
      backgroundThread.start();

   }

   @Override
   public void contextDestroyed(ServletContextEvent event)
   {
      alertServer.stop();
      try
      {
         backgroundThread.join();
      }
      catch (InterruptedException e)
      {
         log.error("contextDestroyed Exception", e);
      }
   }
}
更新

提供的评论和回答对找到解决方案非常有帮助。有了Sotirios Delimanolis和Dave Newton提供的信息,我意识到现在我正在Spring之上构建我的解决方案,首先我真的不需要使用ServletContextListener。我真正想做的就是启动一个可供Spring控制器使用的后台线程,所以我将这段代码放在servlet-context.xml中,并开始运行

<beans:bean id="alertServer" class="com.springmvcproj.AlertServer">
    <beans:property name="serverPort" value="56543" />
</beans:bean>

<beans:bean id="AlertServerThread" class="java.lang.Thread" init-method="start">
  <beans:constructor-arg ref="alertServer"/>
</beans:bean>

正如Dave Newton在评论中所说,Spring只能将它管理的bean注入到它管理的其他bean中。用
@WebListener
注释的类是由servlet容器管理的类,因此永远不会出现在Spring上下文中。即使是这样(因为您创建了
bean
条目),它也不会与servlet容器使用的相同

解决这个问题的一种方法是使用Spring的
WebApplicationInitializer
,而不是使用
web.xml
描述符。此接口提供了一个
onStartup(ServletContext)
方法,在该方法中,您可以注册servlet、筛选器和侦听器,就像在
web.xml
@WebXXX
中一样。差不多

public void onStartup(ServletContext container) throws ServletException {
// Create the 'root' Spring application context
    final AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    rootContext.register(YourApplicationContext.class); // or some xml file
    rootContext.refresh();

    // Manage the life-cycle of the root application context
    container.addListener(new ContextLoaderListener(rootContext));

    // Create the dispatcher servlet's context
    final AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
    dispatcherContext.register(DispatcherContext.class);

    final ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
    dispatcher.setAsyncSupported(true);
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");

    container.addListener(dispatcherContext.getBean(ExecutorContextListener.class)));

    ...// more registrations
}
因此,上面假设您的
注释ConfigWebApplicationContext dispatcherContext
包含类型为
ExecutorContextListener
的bean。因为Spring正在管理这个bean,所以您可以添加
@Autowired
@Inject
来在这个
ServletContextListener
@Controller
类中注入相同的
AlertServer
实例。在这种情况下,您不会在
contextInitialized()
方法中初始化它

第二种选择是

  • AlertServer
    对象作为属性添加到
    ServletContext
  • ServletContext
    注入到
    @Controller
    类中
  • ServletContext
    属性中检索
    AlertServer
    对象

  • 上述操作是可能的,因为
    contextInitialized()
    方法总是在任何控制器开始处理请求之前运行。

    Spring使用Spring管理的对象连接。你是如何创建对象的?我在后台任务中所做的一切都是用POJO完成的。我是否需要向其中一些类添加注释?如果只有一个类,那么最好将警报服务器注入到Spring应用程序启动侦听器和控制器中。