I must be using @Autowired wrong, but I don’t get exactly how. This is a Spring 3.0 Portal MVC app.
The services themselves are not spring-based (they’re auto-generated). There is an impl written around the service providing some custom functionality — these classes are auto wired.
The problem I’m having is that the my autowired class appears to be treated internally as static. And therefore, this code isn’t threadsafe.
Controller class:
@Controller
@RequestMapping("VIEW")
@SessionAttributes(value={"shoppingCartCommonBean"})
public class ShoppingCartAndOrderScreenHandler
{
@Autowired
AbstractServiceImpl releaseOrderService;
. . .
@ActionMapping(value = "SubmitOrder")
public void submitOrder(Model model, PortletRequest request) {
try {
ReleaseOrderContract contract = new ReleaseOrderContract();
/* Initialize contract values from request */
releaseOrderService.setServiceRequest(contract);
logger.debug("ReleaseOrderImpl Hash: " +
releaseOrderService.hashCode());
releaseOrderService.invoke();
}
. . . .
}
}
Where the autowiring is declared in the springconfig.xml as
<beans xmlns="http://www.springframework.org/schema/beans" . . . >
<context:component-scan
base-package="com.marchon.orderentry.shoppingcartandorder.requesthandler" />
. . . .
<bean class="com.marchon.orderentry.serviceimpls.ReleaseOrderServiceImpl"
id="releaseOrderService" />
. . . .
</beans>
I’ve seen some suspicious behavior under heavy load, where when multiple threads execute the same impl simultaneously, they don’t maintain consistent contracts (which is, yes, a non-static class variable in the service impl). And sure enough, when I print out the hashmap of the impl I get identical hashmaps — identical objects.
[ebContainer : 1] [ShoppingCartAndOrderScreenHandler . 208] DEBUG - ReleaseOrderImpl Hash: 1385321106
[ebContainer : 3] [ShoppingCartAndOrderScreenHandler . 208] DEBUG - ReleaseOrderImpl Hash: 1385321106
[ebContainer : 0] [ShoppingCartAndOrderScreenHandler . 208] DEBUG - ReleaseOrderImpl Hash: 1385321106
I would have thought that the auto-wiring would create copies of the bean for each instance of the controller class. But it’s not. What am I not understanding?
Spring beans are
"singleton"scope by default. If you need individual instances,"prototype":That it’s auto-wired isn’t relevant.