【问题标题】:How to mage java servlet managed (or DI) in Spring?如何在 Spring 中管理 Java servlet(或 DI)?
【发布时间】:2012-12-31 17:02:54
【问题描述】:

我有一个带有一些旧 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>

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

<servlet>
    <servlet-name>oldHttpServlet</servlet-name> 
    <display-name>oldHttpServlet</display-name>
    <servlet-class>com.package.MyServlet</servlet-class>
</servlet>

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

<bean id="oldHttpServlet" class="com.package.MyServlet"></bean>

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

class MyServlet extends MyAbstractServlet{
  void doStuff(){
     //YOu know...
  }
}

还有 MyAbstractServlet;

class MyAbstractServlet extends HttpServlet{
  doPost(){
     //Some post implementation here...
  }
}

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

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

【问题讨论】:

  • 你不能在 Spring 中创建 servlet,它是容器决定何时以及创建多少 sevlet 实例,你可以手动自动装配 servlet 字段 stackoverflow.com/questions/467235/…
  • 谢谢,正是我想要的!

标签: java spring tomcat servlets dependency-injection


【解决方案1】:

如果您需要将依赖项注入到 servlet 中,我会选择 Spring 的 HttpRequestHandlerServlet。您创建 HttpRequestHandler 的实现(它有一个方法:

public void handleRequest(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException;

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

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

由于 HttpRequestHandler 是一个 Spring bean,您可以让 Spring 将您需要的所有服务注入其中。

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

代码如下所示(在 servlet 中):

WebApplicationContext webContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
CertainBeanClass bean = (CertainBeanClass) webContext.getBean("certainBean");

[编辑] 事实上,正如其中一位评论者所建议的那样,IS 还有一种选择。不过,它仍然需要您在 servlets init 方法中进行手动设置。这是它的样子:

public void init(ServletConfig config) {
    super.init(config);
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}

你也可以在 Servlet 上使用 @Configurable 注解来试试运气,但这可能会或可能不会起作用(我认为 Servlet 可能会在 Spring 上下文设置之前被初始化,所以它仍然没有可能这样做它的魔力)。

【讨论】:

  • 这就是我的想法......但是我怎么能保留我当前的 doGet/doPost 代码并将其包装在 handleRequest 中......? IE。 HandleRequest 是一个调用 doPost 等方法的包装器?
  • 如果您真的必须重用旧的 servlet,那么您可以创建一个 spring 托管的 servlet 实例并从 handleRequest 调用它,但我认为这与将 servlet 重构为 HttpRequestHandlers 的工作量相同. PS。你确定你不想使用 MVC 框架吗? Spring MVC 感觉非常轻量级!如果 Spring MVC 比 Spring 过于繁重——你可能会研究 Guice(由 Google 提供)——它很容易与纯 servlet 集成。
  • 感谢编辑!这就是我在@Boris Treukhov 评论中指出的方式。谢谢。
【解决方案2】:

Servlet 的理想用途应该是作为 Controller 和底层容器管理它的生命周期,所以我们不需要 Spring 来管理它的实例

所以我可以做一些事情,比如 DI,并通过 Spring/Hibernate 集成传入数据库对象。

你不应该在你的 dao/services 中依赖 Servlet,你的 servlet 应该调用非常适合使用 Spring DI 上下文管理的服务

【讨论】:

  • 我不确定你的意思。我想在 MyServlet 中 @Autowire 事物(服务),要执行此自动连接,我需要让 Spring 知道 MyServlet 实例......我可以在不重写一半服务器核心的情况下做到这一点,即以某种方式将其包装起来?
  • 我已经回答了有关如何解决您的问题的建议。您需要将 servlet 迁移为 HttpReqestHandlers,但签名是相同的。在 Servlet 本身上没有 Spring-way 这样做。
  • 是的,你可以通过创建一个从 Spring 上下文读取 bean 并返回它的 ServiceLocator 来做到这一点
  • 您使用的是原始 servlet 还是使用 SpringMVC 框架而不是 servlet?
  • SpringBeanAutowiringSupport.autowire(this, config.getServletContext()) inside init(config) 已停止工作? :D 或者我错过了什么
【解决方案3】:

关于 SpringBeanAutowiringSupport,javadoc 中的注释:

注意:如果有访问 ServletContext 的显式方式,则首选这种方式而不是使用此类。 WebApplicationContextUtils 类允许基于 ServletContext 轻松访问 Spring 根 Web 应用程序上下文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2023-03-05
    • 2016-04-22
    相关资源
    最近更新 更多