tags:

views:

27

answers:

2

I am exposing a bean that is not thread safe via Spring's http invoker. What I want is that every remote call should get a new instance of the bean. I started by setting the scope to prototype for the bean that I am exposing in the Dispatcher servlet XML. But it still seemed to create only one instance. So all client threads were concurrently accessing the same bean instance.

Next I also set the scopr to prototype for HttpInvokerProxyFactoryBean in the client spring-config.xml. But even then I see a single instance of the bean being returned.

Any ideas on what I am doing wrong? Or has anyone else faced this problem.

Thanks in advance.

Here are the relevant snippets

DispatcherServlet-servlet.xml

    <bean id="fuBeanImpl" class="com.fubar.FuBeanImpl" scope="prototype">
</bean>

<bean id="fuBeanService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
    <property name="service" ref="fuBeanImpl"/>
    <property name="serviceInterface" value="com.fubar.FuBean"/>

</bean>

spring-config.xml

    <bean id="fuBeanService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean" scope="prototype">
    <property name="serviceUrl">
        <value>http://fubar/fuBeanService&lt;/value&gt;
    </property>
    <property name="serviceInterface">
        <value>com.fubar.FuBean</value>
    </property>
    <property name="httpInvokerRequestExecutor">
        <bean class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor"/>
    </property>
</bean>
+1  A: 

This is because your HttpInvokerServiceExporter bean is still a singleton, and it has a reference to the prototype-scoped fuBeanImpl bean. So the exporter gets a single instance of FuBeanImpl and never asks for a new one. This is the problem with singleton-scoped beans referring to on-singleton-scoped beans - the reference "collapses" the prototype, effectively.

You need to make HttpInvokerServiceExporter a prototype-scoped bean also, although this might have side-effects. For example, you haven't told us what is referring to the HttpInvokerServiceExporter - probably a url-mapping definition somewhere?


edit: Since you've clarified that you're using a SimpleUrlhandlerMapping, then what you can do is to inject that with the name of the handler bean, rather than a direct bean reference to it. This means that the handler bean (i.e. the fuBeanService bean) can be a prototype, even though the SimpleUrlhandlerMapping is a singleton.

skaffman
Thanks skaffman. Yes, the HttpInvokerServiceExporter is referrenced by org.springframework.web.servlet.handler.SimpleUrlHandlerMapping to map the dispatcher servlet context path. This means that all beans in the chain have to be prototypes.
golfradio
@golfradio: Not true. See edited answer.
skaffman
+1  A: 

There is another current question Prototype Scope not working about an almost identical problem.

Both of these solutions should work here also:

seanizer
Thanks seanizer. In my case tight coupling will not help unless I actually change the modify the HttpInvokerServiceExporter class.
golfradio