我想使用Spring在servlet中注入一个对象

时间:2014-01-10 20:41:24

标签: java spring servlets

我的应用程序中有两个servlet,我希望将一个A类对象注入到两个servlet中,我也希望整个应用程序中都有相同的ApplicationContext,即这个问题的第一个答案中提到的两个servlet在SO上: Spring injection Into Servlet

现在我经历了很多像这样的问题,但找不到与我的问题相符的东西。为了更好地解释,我在这里写一个粗略的代码:

public class servletOne extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    }
}

public class servletTwo extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    }
}

以上是applicationContext.xml中的两个servelts我想将一个对象传递给这两个servlet,因此按照惯例,我想要这样的功能:

<bean id="servletFirst" class="mypackage.servletOne">
        <property name="message" ref="classObject" />


</bean>
<bean id="servletFirst" class="mypackage.servletTwo">
        <property name="message" ref="classObject" />


</bean>

<bean id="classObject" class="mypackage.classA">

    </bean>

我不知道这是否可能,我是春天的新手,我只有依赖注入的基本知识。

如果有人能帮助我,我真的很感激。这将清除我的许多疑虑并帮助我在学习Spring的过程中继续前进。

这是web.xml

    <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>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>servletOne</servlet-name>
        <servlet-class>mypackage.servletOne</servlet-class>
    </servlet>
<servlet>
        <servlet-name>servletTwo</servlet-name>
        <servlet-class>mypackage.servletTwo</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>servletOne</servlet-name>
        <url-pattern>/servletOne</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>servletTwo</servlet-name>
        <url-pattern>/servletTwo</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>
            300
        </session-timeout>
    </session-config>
</web-app>

2 个答案:

答案 0 :(得分:15)

你混淆了两个概念:Servlets和Spring的ApplicationContext。 Servlet由Servlet容器管理,让我们以Tomcat为例。 ApplicationContext由Spring管理。

在部署描述符中将Servlet声明为

<servlet>
    <servlet-name>servletOne</servlet-name>
    <servlet-class>mypackage.servletOne</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>servletOne</servlet-name>
    <url-pattern>/servletOne</url-pattern>
</servlet-mapping>

Servlet容器将创建mypackage.servletOne类的实例,注册它,并使用它来处理请求。这就是它使用DispatcherServlet所做的事情,它是Spring MVC的基础。

Spring是一个IoC容器,它使用ApplicationContext来管理许多bean。 ContextLoaderListener加载根ApplicationContext(从您告诉它的任何位置)。 DispatcherServlet使用该根上下文,并且还必须加载它自己的上下文。上下文必须具有适当的配置才能使DispatcherServlet起作用。

在Spring上下文中声明一个bean,比如

<bean id="servletFirst" class="mypackage.servletOne">
        <property name="message" ref="classObject" />
</bean>

,无论它与web.xml中声明的<servlet>的类型相同,都是完全不相关的。上面的bean与web.xml中的<servlet>声明无关。

在我的回答here中,因为ContextLoaderListener将其创建的ApplicationContext作为属性放入ServletContext,所以任何ApplicationContext都可以使用Servlet容器管理对象。因此,您可以覆盖自定义HttpServlet#init(ServletConfig)类中的HttpServlet,例如

@Override
public void init(ServletConfig config) throws ServletException {
   super.init(config);

   ApplicationContext ac = (ApplicationContext) config.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

   this.someObject = (SomeBean)ac.getBean("someBeanRef");
}

假设您的根ApplicationContext包含一个名为someBeanRef的bean。

还有其他替代方案。 This, for example.

答案 1 :(得分:-2)

如果您想使用@Autowired或通过applicationContext.xml设置属性,请使用@Controller注释

为您的课程添加注释