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