我是春天的新手,我正在试图弄清楚如何将对象自动装配到控制器。该对象是在运行时从使用ServletContextListener启动和停止的任务创建的。如何告诉spring应用程序上下文这个对象?
更多详情
我的后台任务是从下面的代码开始的。我希望将alertServer
对象连接到控制器。我可以修改这个类吗?
@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>
答案 0 :(得分:1)
正如Dave Newton在评论中所说,Spring只能将它管理的bean注入其管理的其他bean中。注释为@WebListener
的类是由servlet容器管理的类,因此永远不会出现在Spring上下文中。即使它确实存在(因为你创建了一个bean
条目),它也不会与servlet容器使用的条目相同。
解决这个问题的方法是使用Spring的WebApplicationInitializer
代替(或旁边)使用web.xml
描述符。此接口提供onStartup(ServletContext)
方法,您可以像web.xml
或@WebXXX
一样注册Servlet,过滤器和监听器。像
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
}
因此,上面假设您的AnnotationConfigWebApplicationContext dispatcherContext
包含ExecutorContextListener
类型的bean。由于Spring正在管理此bean,因此您可以添加@Autowired
或@Inject
以在此AlertServer
和ServletContextListener
类中注入相同的@Controller
实例。在这种情况下,您不会在contextInitialized()
方法中初始化它。
第二种选择是
AlertServer
对象添加为ServletContext
。ServletContext
注入您的@Controller
课程。AlertServer
属性中检索ServletContext
对象。以上是可能的,因为contextInitialized()
方法总是在任何控制器开始处理请求之前运行。