spring的Bean默认都是单例的, 如何实现多例呢?
-
对于Controller来说, 在类级别加上注解
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
即可 -
对于Service来说, 仅仅上加上@Scope注解是不够的, 因为Controller是单例的, 只有第一次调用Controller中使用了Service的方法时才会创建Service注入, 第二次调用同一个方法时, 它不会再次创建Service.
解决方法(三选一)
-
让Service以代理方式注入, 在@Scope注解添加poxyMode属性。这样虽然Controller本身是单例的,但每次都能从代理获取Service。proxyMode属性有两个值:
ScopedProxyMode.INTERFACES
和ScopedProxyMode.TARGET_CLASS
,前一个表示Service是一个接口(使用了JDK的动态代理),后一个表示Service是一个类(使用了CGLIB动态代理)。关于动态代理, 可参考我的另一篇博客java 代理模式 从静态代理到动态代理 -
在Controller和Service都加上
@Scope(“prototype”)
, 但是这种方法的为了一个Service的多例, 让Controller失去了单例的优势. -
首先在Service上添加多例注解
@Scope(“prototype”)
, 然后通过ApplicationContext
的getBean()
方法, 但这种方法破坏了IOC注入的优美展现形式,和new一样不便于管理和修改。如何获取ApplicationContext可参考我的另一篇博客springboot 通过ApplicationContextAware获取ApplicationContext上下文容器
附: @Scope的value属性表
属性 | 含义 |
---|---|
ConfigurableBeanFactory.SCOPE_SINGLETON,即“singleton” | 单例 |
ConfigurableBeanFactory.SCOPE_PROTOTYPE,即“prototype” | 多例 |
WebApplicationContext.SCOPE_REQUEST,即“request” | request表示请求,即在一次http请求中,被注解的Bean都是同一个Bean,不同的请求是不同的Bean |
WebApplicationContext.SCOPE_SESSION,即“session” | session表示会话,即在同一个会话中,被注解的Bean都是使用的同一个Bean,不同的会话使用不同的Bean |
网友评论