【发布时间】:2013-02-06 18:36:00
【问题描述】:
据我所知,Spring bean 默认是单例的。
我想要的是考虑实例属性使 bean 成为线程安全的。
我将尝试使用一个简单的示例向您展示。
考虑以下代码:
@Controller
public class MyServlet {
@Autowired
private HelloService service;
@RequestMapping(value="/hello", method = RequestMethod.GET)
public void sayHello(HttpServletRequest req, HttpServletResponse res) throws IOException {
service.doStuff();
}
}
public class HelloService {
private int i = 1;
public void doStuff() {
System.out.println("Started " + i);
i++;
System.out.println(Thread.currentThread().getName() + " Done " + i);
}
}
输出将是这样的:
32911580@qtp-28064776-0 - Started 1
7802158@qtp-28064776-2 - Started 2
32911580@qtp-28064776-0 - Done 3
7802158@qtp-28064776-2 - Done 3
这证明“i”变量在多个线程之间共享。
我也尝试将 HelloService bean 定义为原型,像这样
<bean id="helloService" class="my.package.HelloService" scope="prototype" />
但结果是一样的。
我发现解决此问题的唯一方法是: - 将声明移到 doStuff() 方法中,但这不是我想要的 - 制作 doStuff() 方法,但这意味着有锁
我想要的是在每次调用时都有一个新的 HelloService 实例。
谁能帮帮我? 提前致谢。
更新
我使用查找方法通过方法注入找到了解决方案。 http://static.springsource.org/spring/docs/3.1.1.RELEASE/spring-framework-reference/html/beans.html#beans-factory-lookup-method-injection
【问题讨论】:
-
这不是一个现实的例子。在 99% 的情况下,Spring 服务是无状态的。你有一个有状态的 Spring 服务的具体实例吗?
-
也许您可以尝试将 i 声明为 volatile。不确定这是否能解决您的问题。
-
Spring 部分无关紧要。您在问如何使代码线程安全。
标签: spring thread-safety code-injection autowired