Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I want to inject an object in servlet using Spring

I have a two servlets in my application and I want an object of class A to be injected to both the servlets, and I would also like the same ApplicationContext throughout the application i.e. both servlets as mentioned in the first answer of this question on SO: Spring injection Into Servlet

Now I went through many questions like these but couldnt find something exactly that matches my question. To explain better Ill write a rough code here:

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 {

    }
}

So above are the two servelts now in applicationContext.xml I want to pass an object to both these servlets so as per normal convention I want a functionality like this:

<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>

I dont know if this is possible or not, I am new to spring and I have only basic knowledge of dependency Injection.

If anyone can help me with this I would really really appreciate it. This would clear a lot of my doubts and help me move forward in the process of learning Spring.

This is 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>
like image 692
Nick Div Avatar asked Jan 10 '14 20:01

Nick Div


1 Answers

You're mixing up two concepts: Servlets and Spring's ApplicationContext. Servlets are managed by your Servlet container, let's take Tomcat for example. The ApplicationContext is managed by Spring.

When you declare a Servlet in your deployment descriptor as

<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>

The Servlet container will create an instance of your mypackage.servletOne class, register it, and use it to handle requests. This is what it does with the DispatcherServlet which is the basis of Spring MVC.

Spring is an IoC container that uses ApplicationContext to manage a number of beans. The ContextLoaderListener loads the root ApplicationContext (from whatever location you tell it to). The DispatcherServlet uses that root context and must also load its own. The context must have the appropriate configuration for the DispatcherServlet to work.

Declaring a bean in the Spring context, like

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

regardless of the fact that it is of the same type as the <servlet> declared in web.xml, is completely unrelated. The bean above has nothing to do with the <servlet> declaration in the web.xml.

As in my answer here, because the ContextLoaderListener puts the ApplicationContext it creates into the ServletContext as an attribute, that ApplicationContext is available to any Servlet container managed object. As such, you can override the HttpServlet#init(ServletConfig) in your custom HttpServlet classes, like so

@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");
}

assuming that your root ApplicationContext contains a bean called someBeanRef.

There are other alternatives to this. This, for example.

like image 161
Sotirios Delimanolis Avatar answered Oct 21 '22 08:10

Sotirios Delimanolis