我有以下控制器和服务
@Controller
public class MyController
{
@Autowired
private MyService myService;
@RequestMapping(method=RequestMethod.GET, value="/connect.do")
public String connect(Model model)
{
invokeService();
return "xxx";
}
private void invokeService()
{
myService.test();
}
}
@Service
public class MyService
{
private int value1 = 200;
private int value2 = 333;
private String value3 ;
private String value4 ;
private String value5 ;
....
public void test()
{
System.out.println(value1++);
foo();
}
private void foo()
{
}
}
当我使用2个浏览器连接到应用程序时,输出为" 200"和" 201",这意味着Spring将相同的MyService实例注入控制器以进行不同的连接。
我需要输出为" 200"和" 200"当我使用2个不同的连接来访问应用程序时,因为我需要在" test()"之间共享values1,values2,value3等。和" foo()"。怎么在春天做?基本上,我希望Spring为不同的连接注入不同的实例。我在Service bean中尝试了@Scope(" prototype")但它没有用。
我可以通过使用:
使其工作@Controller
public class MyController
{
private void invokeService()
{
new MyService.test();
}
}
我只是想知道如何在Spring中这样做。
提出这个问题的另一种方法是:如何拥有多个控制器实例(每个用户连接一个)而不是一个服务于所有连接的控制器实例?
编辑:我可以通过使用以下代码和2个浏览器连接看到原型(输出:200 200 200 200)和单件(输出:200 201 202 203)的区别
private void invokeService()
{
myService = applicationContext.getBean( MyService.class );
new MyService.test();
myService = applicationContext.getBean( MyService.class );
new MyService.test();
}
但是当我把" applicationContext.getBean(MyService.class)"而在postConstructor中:
public class MyController implements ApplicationContextAware {
private SearchService searchService;
@PostConstruct
public void init() {
searchService = applicationContext.getBean( SearchService.class );
}
protected ApplicationContext applicationContext;
@Override
public void setApplicationContext( ApplicationContext applicationContext ) throws BeansException {
this.applicationContext = applicationContext;
}
}
并使用" @Scope(BeanDefinition.SCOPE_PROTOTYPE)"在MyService上,输出仍然是" 200"和" 201"当我使用2个浏览器连接到应用程序时
答案 0 :(得分:2)
@Autowired
不会与@Scope("prototype")
混合启用代理生成(这可能不是您想要的 - 它会很快变得复杂)。
改为MyController
ApplicationContextAware
:
public class MyController implements ApplicationContextAware {
public MyService getMyService() {
return applicationContext.getBean( MyService.class );
}
protected ApplicationContext applicationContext;
@Override
public void setApplicationContext( ApplicationContext applicationContext ) throws BeansException {
this.applicationContext = applicationContext;
}
}
现在@Scope(BeanDefinition.SCOPE_PROTOTYPE)
将按预期工作。
请注意,每次致电MyService
时,您都会获得getMyService()
的新实例。
为什么你的方法(和我的旧方法)不起作用? MyController
是一个单例,因此字段myService
只连接一次 - 每次访问字段时Spring都不会给你一个新的bean实例,原因有两个:
它会以其他方式破裂。例如,当您调用bean的两个方法时:
myService.foo(); myService.bar(); //你真的想要一个新豆吗?
PS:如果你使用Spring&lt; 3.1.2,您将需要指定bean的ID,因为getBean(Class<?> type)
对于这些版本来说非常慢。