如何解决使用Kotlin解决Spring Boot Rest Controller中的单例?
我是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
解决方法
解析控制器方法参数实际上是完全不同的机制。它与依赖项注入和@Autowired
批注无关:批注可以删除,并且不会改变行为。
尽管从Spring Framework 5.0开始,@ Autowired在技术上可以在单个方法或构造函数参数上声明,但是该框架的大多数部分都忽略了此类声明。积极支持自动装配参数的核心Spring框架的唯一部分是spring-test模块中的JUnit Jupiter支持(有关详细信息,请参见TestContext框架参考文档)。
https://docs.spring.io/
在您的情况下,stackSingletonBean
由ModelAttributeMethodArgumentResolver实例化。它不知道@Service
注释也不知道其范围:它只是在每个请求上使用默认构造函数。
模型属性源自模型,或使用默认构造函数创建,然后添加到模型中。
请注意,@ ModelAttribute的使用是可选的,例如用于设置其属性。默认情况下,任何不是简单值类型(由BeanUtils#isSimpleProperty确定)且未被其他任何参数解析器解析的参数都将被视为使用@ModelAttribute注释。 Web on Reactive Stack
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。