Spring 3.0中的@Autowired——创建静态bean?
我一定是错误地使用了@Autowired,但我不知道具体是如何使用的。这是一个 Spring 3.0 Portal MVC 应用程序。
服务本身不是基于 spring 的(它们是自动生成的)。有一个围绕服务编写的实现,提供一些自定义功能——这些类是自动连接的。
我遇到的问题是我的自动装配类似乎在内部被视为静态的。因此,这段代码不是线程安全的。
控制器类:
@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();
}
. . . .
}
}
自动装配是在 springconfig.xml 中声明的,因为
<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>
我在重负载下看到了一些可疑的行为,当多个线程同时执行相同的 impl 时,它们不保持一致的契约(是的,这是一个非- 服务实现中的静态类变量)。果然,当我打印出 impl 的哈希图时,我得到了相同的哈希图——相同的对象。
[ebContainer : 1] [ShoppingCartAndOrderScreenHandler . 208] DEBUG - ReleaseOrderImpl Hash: 1385321106
[ebContainer : 3] [ShoppingCartAndOrderScreenHandler . 208] DEBUG - ReleaseOrderImpl Hash: 1385321106
[ebContainer : 0] [ShoppingCartAndOrderScreenHandler . 208] DEBUG - ReleaseOrderImpl Hash: 1385321106
我本以为自动装配会为控制器类的每个实例创建 bean 的副本。但事实并非如此。我不明白什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Spring bean 是默认情况下
“singleton”
范围。如果您需要单独的实例,“prototype”
:它的自动连接并不相关。
Spring beans are
"singleton"
scope by default. If you need individual instances,"prototype"
:That it's auto-wired isn't relevant.
Spring bean 默认情况下是单例的。如果您需要releaseOrderService 不是单例,则需要适当地设置bean 范围。请参阅 Bean 作用域
Spring beans are by default singletons. If you need your releaseOrderService to be something other than a singleton, you need to set the bean scope appropriately. see Bean Scopes