前言
这里把使用 Spring
过程中遇到的问题做个记录,有些给出了解决方案,有些没有,欢迎同道读者斧正!
如何正确的创建 prototype
类型的 Spring bean
这里先尝试的去创建一个 prototype
的 bean
1 | (ConfigurableBeanFactory.SCOPE_PROTOTYPE) |
然后,我们在Controller 中注入这个 prototype bean
1 |
|
然后我们开始请求这个 http 接口
不断的刷新页面,返回的结果都是一模一样!我们再来看看日志
从上面的日志上我们看到这个 prototype bean
的构造方法只被调用了一次!
到这里,我感到奇怪了,为什么这个 prototype bean
成了 singleton bean
了?
这个时候我想了 《Spring揭秘》 中看到的正解, 之前这个现象出现的原因是 HelloController
是 singleton
类型的,这个 bean
只会被初始化一次, 而 HelloController
依赖的 ProtoTypeComponent
也只会被注入一次!
到这里,谜底揭晓:
singleton bean
依赖的 prototype bean
会 “变成” singleton bean
这里,解决这个问题的第一个方案也出现了:
依赖 prototype bean
也必须是 prototype bean
很明显这个方案不能解决很多状况, 我们继续这个问题
再来翻翻 《Spring 揭秘》
找找答案
我们看到了两个答案
“1. 使用方法注入
- 继承 ApplicationContextAware 每次去获取bean
使用方法注入
在传统的 xml 配置方式中我们需要这样配置
1 | <bean id="protoTypeBean" class="...impl.ProtoTypeService" singleton="false"/> |
getProtoTypeBean 方法定义如下
1 | private ProtoTypeService protoTypeBean; |
现在我们更倾向于使用注解,那么基于注解怎么实现上面这种方式呢?
我们这里引入 @Lookup
注解
1 | /** |
从上面的代码能看出:
这个注解只能修饰方法,根据方法的返回值类型创建对应的Bean,底层机制是调用 org.springframework.beans.factory.BeanFactory#getBean(Class, Object...)
或 org.springframework.beans.factory.BeanFactory#getBean(String, Object...)
先来使用 @Lookup
注解改成一下我们尝试创建 有状态的 prototype bean
修正的代码如下:
1 |
|
让我们运行起 tomcat
看看结果:
很明显,我们成功的创建了 prototype bean
!
继承 ApplicationContextAware 每次去获取bean
这里不推荐使用 ApplicationContextAware
所以不给出方法了。