java - 原型(prototype) Bean 没有按预期 Autowiring

标签 java spring spring-mvc spring-web

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 docDEFAULT .

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/

相关文章:

Java Spring Data @EnabledJPARepositories 问题

java - 上传文件使用 HttpUrlConnection 时出错

java - 如何解决 android 上的多版本 jar 依赖关系?

java - 如何在Spring MVC中管理对同一文件夹但HTTP参数不同的两个HTTP请求?

java - Geb 和 Spring-Boot 元素未找到错误

Spring MVC Controller 单元测试未调用 @ControllerAdvice

java - 同一 Controller Spring MVC 中的多个用户

java在指定类上设置/获取静态继承字段

java - 用于在集合中递归存储类对象的数据结构java

java - Spring MVC 可以用于在 Swing 应用程序中实现 MVC 模式吗?