Prototype Bean无法按预期自动装配 [英] Prototype Bean doesn't get autowired as expected
问题描述
TestController.java
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
TestClass.java
@Component
@Scope("prototype")
public class TestClass {
public TestClass() {
System.out.println("new test class constructed.");
}
public void doSomething() {
}
}
正如你所看到的,我正在试图弄清楚访问时是否注入了新的 TestClass
XXX /测试。 构建了新的测试类。
只打印了一次(第一次触发xxx / test),而我期望它打印得相同。这是否意味着 @Autowired
对象只能是 @Singleton
?那么 @Scope
如何工作?
As you can see, I'm trying to figure out whether a new TestClass
has been injected when visit "xxx/test". "new test class constructed."
got printed only once(first time I triggered "xxx/test") while I was expecting it printed equally. Is that mean @Autowired
object can only be @Singleton
? How does @Scope
work then?
编辑:
TestController.java
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
解决方案,注册为范围(scopeName =request)
。这是我访问xxx / test时的三次结果
I tried @Valerio Vaudi
solution, registered as Scope(scopeName = "request")
. Here is the three time result when I visit "xxx/test"
(第一次)
- 构建新的测试类。
- null
(秒)
- null
(第三)
- null
我不明白为什么结果为null,因为每次使用它都不会重建一个新的。
I don't understand why the result is null since it doens't reconstruct a new one each time I use it.
然后我尝试了 @Nikolay Rusev
解决方案 @Scope(prototype)
:
Then I tried @Nikolay Rusev
solution @Scope("prototype")
:
(第一次)
- 新构建的。
- 新构建的。
- null
(秒)
- 新构建的。
- 新构建的。
- null
(第三)
- 新构建的。
- 新构建的。
- null
这是rath因为每次使用它(TestClass)都很容易理解,Spring会自动重新生成它的新实例。但是第一个场景我仍然无法理解,因为它似乎只为每个请求保留了一个新实例。
This is rather easy to understand since each time I use it(TestClass), Spring auto-regenerate a new instance of it. But the first scene I still cannot understand since it seems to retain only one new instance for each request.
真正的目的是:请求生命周期,需要一个新的 testClass
(如果需要),只需要一个。此时似乎只有 ApplicationContext
解决方案是可行的(我已经知道),但我只是想知道这是否可以通过自动完成@Component
+ @Scope
+ @Autowired
。
The real purpose is: In each request lifecycle, a new testClass
is required(if needed), and only one is required. At this moment it seems only ApplicationContext
solution is feasible(which I already knew), but I just want to know if this could be done automatically by using @Component
+ @Scope
+ @Autowired
.
推荐答案
以上所有答案都是正确的。控制器默认为 singleton
,注入的 testClass
实例化一次,因为默认的作用域代理模式是 DEFAULT
来自 spring doc 。
all the answers above are correct. Controller by default is singleton
and the injected testClass
is instantiated once, because default scoped proxy mode is DEFAULT
from spring doc.
public abstract ScopedProxyMode proxyMode指定是否应将
组件配置为作用域代理如果是这样,代理是否应该是基于接口或基于子类的
。默认为
ScopedProxyMode.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.
类似于Spring XML中的支持。
Analogous to support in Spring XML.
另请参阅:ScopedProxyMode默认值:
org.springframework.context.annotation.ScopedProxyMode。 DEFAULT
See Also: ScopedProxyMode Default: org.springframework.context.annotation.ScopedProxyMode.DEFAULT
如果你想在每次需要时注入新实例,你应该更改你的 TestClass
to:
if you want new instance to be injected every time you need, you should change your TestClass
to :
@Component
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class TestClass {
public TestClass() {
System.out.println("new test class constructed.");
}
public void doSomething() {
}
}
使用这个额外的配置,注入的 testClass
将不是真正的 TestClass
bean但代理到 TestClass
bean,这个代理将理解 prototype
范围,并将返回新实例每次都需要。
with this additional configuration the injected testClass
will not be really a TestClass
bean but proxy to TestClass
bean and this proxy will understand the prototype
scope and will return new instance every time is needed.
这篇关于Prototype Bean无法按预期自动装配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!