你好呀,我是沉默王二,一枚有趣的程序员,写的文章一直充满灵气,力求清新脱俗。昨天跑去王府井的小米店订购了一台小米 10,说是一周之内能到货,但我还是忍不住今天就想见到她。见我茶不思饭不想的,老婆就劝我说,与其在瞎想,还不如滚去写你的文章。于是就有了今天这篇“Spring Bean 的常用配置”,通过我和三妹对话的形式。
教妹学 Java,没见过这么放肆的标题吧?“语不惊人死不休”,没错,本篇文章的标题就是这么酷炫,不然你怎么会点进来?
我有一个漂亮如花的妹妹(见上图),她叫什么呢?我想聪明的读者能猜得出:沉默王三,没错,年方三六。父母正考虑让她向我学习,做一名正儿八经的 Java 程序员。我期初是反对的,因为程序员这行业容易掉头发。但家命难为啊,与其反对,不如做点更积极的事情,比如说写点有趣的文章教教她。
“二哥,Spring 基础篇学完后,我有一种强烈的感觉,Spring 真的好强大,就如春风佛面一般,好像学下一篇。”
“哎呀,三妹,你这个比喻虽然有些牵强,但多少有些诗意。”
“好吧,让我们开始今天的学习吧!”
01、Bean 的 Scope 配置“二哥,据说 Bean 的 Scope 类型有好几种,用于定义了 Bean 的生命周期和使用环境,你能给我具体说说吗?”
“没问题啊。”
1)singleton
也就是单例模式,如果把一个 Bean 的 Scope 定义为 singleton,意味着一个 Bean 在 Spring 容器中只会创建一次实例,对该实例的任何修改都会反映到它的引用上面。这也是 Scope 的默认配置项,可省略。
来新建一个 Writer 类,内容如下:
public class Writer {private String name;
public Writer() {
}
// getter setter
}
再来新建一个 SingletonConfig 类,内容如下:
@Configurationpublic class SingletonConfig {
@Bean
@Scope("singleton")
public Writer getWriterSingleton() {
return new Writer();
}
}
@Configuration 注解表明当前类是一个配置类,相当于 Spring 配置的一个 xml 文件。
@Bean 注解用在 getWriterSingleton() 方法上,表明当前方法返回一个 Bean 对象(Writer),然后将其交给 Spring 管理。
可以使用 Spring 定义的常量来代替字符串 singleton:
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)当然也可以完全省略,于是 SingletonConfig 瘦身了。
@Configurationpublic class SingletonConfig {
@Bean
public Writer getWriterSingleton() {
return new Writer();
}
}
新建 SingletonMain 类,代码如下:
public class SingletonMain {public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SingletonConfig.class);
Writer writer1 = context.getBean(Writer.class);
Writer writer2 = context.getBean(Writer.class);
System.out.println(writer1);
System.out.println(writer2);
writer1.setName("沉默王二");
System.out.println(writer2.getName());
context.close();
}
}
程序输出的结果如下所示:
commonuse.singleton.Writer@19dc67c2commonuse.singleton.Writer@19dc67c2
沉默王二
writer1 和 writer2 两个对象的字符串表示形式完全一样,都是 commonuse.singleton.Writer@19dc67c2;另外,改变了 writer1 对象的 name,writer2 也跟着变了。
从结果中我们可以得出这样的结论:Scope 为 singleton 的时候,尽管使用 getBean() 获取了两次 Writer 实例,但它们是同一个对象。只要更改它们其中任意一个对象的状态,另外一个也会同时改变。
2)prototype
prototype 的英文词义是复数的意思,它表示一个 Bean 会在 Spring 中创建多次实例,适合用于多线程的场景。