【问题标题】:Resolving Singletons in Spring Boot Rest Controllers with Kotlin使用 Kotlin 解决 Spring Boot Rest 控制器中的单例
【发布时间】:2020-08-13 16:47:51
【问题描述】:

我是 Spring 和 Spring Boot 的新手,我尝试了不同的方法来解析 Bean。在我的示例中,我有一个应该 始终 是单例的 Bean。令我惊讶的是,似乎有一种方法可以将这个 bean 解析为,我认为是“原型”。

谁能向我解释为什么在方法showSingletonBeans的签名中解决它不是单例?

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

@Service("stackSingletonBean")
// @Scope("singleton")
class MySingletonBean {
    init {
        println("Created MySingletonBean " + this.hashCode())
    }
}

@RestController
class MyController {

    @Autowired
    // @Qualifier("singletonBean")
    lateinit var memberSingletonBean: MySingletonBean

    @Autowired
    lateinit var singeltonFactory: ObjectFactory<MySingletonBean>

    fun buildSingleton() : MySingletonBean {
        return singeltonFactory.`object`
    }

    @Lookup
    fun getSingletonInstance() : MySingletonBean? {
        return null
    }

    @GetMapping("/")
    fun showSingletonBeans(@Autowired stackSingletonBean: MySingletonBean) {
        println("member " + memberSingletonBean.hashCode() )
        println("stack " + stackSingletonBean.hashCode())
        println("lookup:" + getSingletonInstance().hashCode())
        println("factory: " + buildSingleton().hashCode())
    }
}

日志是这样的:

2020-08-13 18:44:32.604  INFO 172175 --- [           main] com.example.demo.DemoApplicationKt       : No active profile set, falling back to default profiles: default
2020-08-13 18:44:33.118  INFO 172175 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-08-13 18:44:33.124  INFO 172175 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-08-13 18:44:33.124  INFO 172175 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-08-13 18:44:33.164  INFO 172175 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-08-13 18:44:33.164  INFO 172175 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 528 ms
Created MySingletonBean 1747702724
2020-08-13 18:44:33.286  INFO 172175 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-13 18:44:33.372  INFO 172175 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-08-13 18:44:33.379  INFO 172175 --- [           main] com.example.demo.DemoApplicationKt       : Started DemoApplicationKt in 1.011 seconds (JVM running for 1.24)
2020-08-13 18:44:37.341  INFO 172175 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-08-13 18:44:37.341  INFO 172175 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-08-13 18:44:37.344  INFO 172175 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
Created MySingletonBean 562566586
member 1747702724
stack 562566586
lookup:1747702724
factory: 1747702724
Created MySingletonBean 389331797
member 1747702724
stack 389331797
lookup:1747702724
factory: 1747702724

【问题讨论】:

    标签: spring spring-boot kotlin


    【解决方案1】:

    解析控制器方法参数实际上是完全不同的机制。它与依赖注入和@Autowired注解无关:注解可以被移除并且不会改变行为。

    尽管自 Spring Framework 5.0 起,@Autowired 在技术上可以在单个方法或构造函数参数上声明,但框架的大部分部分都忽略了此类声明。积极支持自动装配参数的核心 Spring 框架的唯一部分是 spring-test 模块中的 JUnit Jupiter 支持(有关详细信息,请参阅 TestContext 框架参考文档)。 https://docs.spring.io/

    在您的情况下,stackSingletonBeanModelAttributeMethodArgumentResolver 实例化。它不知道 @Service 注释及其范围:它只是在每个请求上使用默认构造函数。

    模型属性来源于模型,或者使用默认构造函数创建,然后添加到模型中。

    注意@ModelAttribute 的使用是可选的 — 例如,设置它的属性。默认情况下,任何不是简单值类型(由 BeanUtils#isSimpleProperty 确定)且未被任何其他参数解析器解析的参数都被视为使用 @ModelAttribute 注释。 Web on Reactive Stack

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-17
      • 2019-07-29
      • 2019-03-27
      • 2020-01-24
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多