Prototype Bean无法按预期自动装配 [英] Prototype Bean doesn't get autowired as expected

查看:105
本文介绍了Prototype Bean无法按预期自动装配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆