如何在Spring中管理java servlet托管(或DI)?

Nig*_*olf 2 java spring tomcat servlets dependency-injection

我有一个带有一些旧HTTPServlet的项目,我想要一种方法来管理Spring中Servlet的创建/生命周期,这样我就可以做一些像DI这样的事情并通过Spring/Hibernate集成传递数据库对象.

首先,我web.xml按如下方式设置Spring应用程序上下文;

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)

接下来我有我的servlet定义web.xml;

<servlet>
    <servlet-name>oldHttpServlet</servlet-name> 
    <display-name>oldHttpServlet</display-name>
    <servlet-class>com.package.MyServlet</servlet-class>
</servlet>
Run Code Online (Sandbox Code Playgroud)

在我的春天,application-context.xml我想做一些bean def如下;

<bean id="oldHttpServlet" class="com.package.MyServlet"></bean>
Run Code Online (Sandbox Code Playgroud)

我认为上面我需要在我的servlet中实现一些接口,在Spring app-context.xml中保持上面的bean定义,然后在web.xml中更改servlet定义...我不确定什么是最简单的更改,因为在MyServelet.java端需要担心一些继承,看起来像这样;

class MyServlet extends MyAbstractServlet{
  void doStuff(){
     //YOu know...
  }
}
Run Code Online (Sandbox Code Playgroud)

和MyAbstractServlet;

class MyAbstractServlet extends HttpServlet{
  doPost(){
     //Some post implementation here...
  }
}
Run Code Online (Sandbox Code Playgroud)

在Spring中包装MyServlet并将其从那里加载而不是通过web.xml进行实例化的最佳方法是什么?

我假设最好的方法是使用Springs HttpRequestHandler然后使用HttpRequestHandlerServletweb.xml代替当前的servlet.但是我不确定如何实现HttpRequestHandler接口来处理myAbstractServlet中现有的doPost()内容...

the*_*dam 5

如果你需要将依赖项注入到servlet中,那么我将使用Spring的HttpRequestHandlerServlet.您创建了HttpRequestHandler的实现(它有一个方法:

public void handleRequest(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException;
Run Code Online (Sandbox Code Playgroud)

你需要实现它 - 它相当于你在doGet/doPost中拥有的东西.所有HttpRequestHandler实现的实例都应该由spring处理(设置注释驱动的配置并使用@Component注释它)或使用XML配置来设置这些bean.

在您的web.xml中,为HttpRequestHandlerServlet创建映射.如果你命名servlet与你的HttpRequestHandler命名相同,那么Spring将使HttpRequestHandlerServlet自动使用匹配的HttpRequestHandler处理请求.

由于HttpRequestHandler是一个Spring bean,因此可以让Spring将所需的所有服务注入其中.

如果您仍然不想使用HttpRequestHandler代替Servlet,那么剩下的就是一些"编程柔道",比如使用Spring utils检索WebApplicationContext并通过"每个名称"从那里获取bean.Servlet不是由Spring实例化的,因此它无法管理它们.您必须为servlet创建一个基类,并自己管理DI作为初始化步骤.

代码看起来像这样(在servlet中):

WebApplicationContext webContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
CertainBeanClass bean = (CertainBeanClass) webContext.getBean("certainBean");
Run Code Online (Sandbox Code Playgroud)

[编辑]实际上,由于评论者的一个建议的,有IS一个选择.它仍然需要您在servlet init方法中进行手动设置.这是这样的:

public void init(ServletConfig config) {
    super.init(config);
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
Run Code Online (Sandbox Code Playgroud)

您也可以尝试使用Servlet上的@Configurable注释进行编织,但这可能会或可能不会起作用(我认为Servlet可能会在Spring上下文设置之前初始化,因此它仍然无法实现其魔力) .