TestController.java
@RestController
public class TestController {
@Autowired
private TestClass testClass;
@RequestMapping(value = "/test", method = RequestMethod.GET)
public void testThread(HttpServletResponse response) throws Exception {
testClass.doSomething();
}
}
TestClass.java
@Component
@Scope("prototype")
public class TestClass {
public TestClass() {
System.out.println("new test class constructed.");
}
public void doSomething() {
}
}
如您所见,我正在尝试确定是否有新的 TestClass
访问“xxx/test”时已注入(inject)。 "new test class constructed."
只打印了一次(我第一次触发“xxx/test”),而我期望它打印一样。这意味着@Autowired
对象只能是 @Singleton
? @Scope
如何那么工作呢?
编辑:
TestController.java
@RestController
public class TestController {
@Autowired
private TestClass testClass;
@RequestMapping(value = "/test", method = RequestMethod.GET)
public void testThread(HttpServletResponse response) throws Exception {
testClass.setProperty("hello");
System.out.println(testClass.getProperty());
}
}
我试过 @Valerio Vaudi
解决方案,注册为Scope(scopeName = "request")
.这是我访问“xxx/test”时的三次结果
(第一次)
- 构建了新的测试类。
- 空
(秒)
- 空
(第三个)
- 空
我不明白为什么结果为空,因为它不会在我每次使用时都重建一个新的。
然后我尝试了@Nikolay Rusev
解决方案@Scope("prototype")
:
(第一)
- 新建一个。
- 新建一个。
- 空
(秒)
- 新建一个。
- 新建一个。
- 空
(第三个)
- 新建一个。
- 新建一个。
- 空
这很容易理解,因为每次我使用它(TestClass)时,Spring 都会自动重新生成它的一个新实例。但是第一个场景我仍然无法理解,因为它似乎为每个请求只保留一个新实例。
真正的目的是:在每个请求生命周期中,一个新的testClass
是必需的(如果需要),并且只需要一个。目前看来只有ApplicationContext
解决方案是可行的(我已经知道了),但我只想知道这是否可以通过使用 @Component
自动完成+ @Scope
+ @Autowired
.
最佳答案
以上所有答案都是正确的。 Controller 默认是 singleton
并且注入(inject)的 testClass
被实例化一次,因为默认作用域代理模式是来自 spring doc 的 DEFAULT
.
public abstract ScopedProxyMode proxyMode Specifies whether a component should be configured as a scoped proxy and if so, whether the proxy should be interface-based or subclass-based. Defaults to ScopedProxyMode.DEFAULT, which typically indicates that no scoped proxy should be created unless a different default has been configured at the component-scan instruction level.
Analogous to support in Spring XML.
See Also: ScopedProxyMode Default: org.springframework.context.annotation.ScopedProxyMode.DEFAULT
如果您希望每次需要时都注入(inject)新实例,则应将 TestClass
更改为:
@Component
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class TestClass {
public TestClass() {
System.out.println("new test class constructed.");
}
public void doSomething() {
}
}
使用这个附加配置,注入(inject)的 testClass
将不是真正的 TestClass
bean,而是 TestClass
bean 的代理,并且该代理将理解 prototype
作用域,每次需要时都会返回新的实例。
关于java - 原型(prototype) Bean 没有按预期 Autowiring ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36278595/