Reference:https://tycoding.cn/2018/05/23/Spring-1/
上一节介绍了Spring的构造器注入,这一节介绍通过工厂方法创建Bean。
一般来说,单例类的实例只能通过静态工厂方法来创建。Spring支持通过<bean>
元素的factory-method
属性来装配工厂创建的Bean。
以下是一个典型的单例类:
package d20190124;
public class Case {
private Case() {
}
//延迟加载实例
private static class CaseSingleHolder{
static Case instance = new Case();
}
//返回实例
public static Case getInstance(){
return CaseSingleHolder.instance;
}
}
以上使用了单例模式中一种懒加载单例模式,即在调用的时候才创建实例(故称为懒加载)。
以上懒加载特点就是: 1.构造函数私有 2. 方法静态
Java中单例模式具有以下特点:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。 —> 加载实例
- 单例类必须给所有其他对象提供这一实例。 —> 返回实例对象
在spring-config.xml
中添加如下:
<bean id="case" class="d20190124.Case" factory-method="getInstance"/>
注:这样应用的场景是我们不想在加载spring-config.xml
时就实例化Bean,而是调用factory-method
所指定的方法时,才开始真正地实例化Bean。
使用要静态工厂创建Bean要注意:这里的class
属性并不是指定Bean实例的实现类,而是静态工厂类。因为Spring需要知道是用哪个工厂承诺来创建Bean的实例。其次factory-method
指定的是静态工厂方法名(必须是静态的)。
如下:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
HelloWorld id = (HelloWorld) context.getBean("hw3");
id.sayHello();
Case c = (Case) context.getBean("case");
System.out.println(c);
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
HelloWorld id = (HelloWorld) context.getBean("hw3");
id.sayHello();
// Case c = (Case) context.getBean("case");
// System.out.println(c);
运行结果分别是:
发现:两次调用main方法都已经实例化了名字是hw3
的Bean,但是,没有调用getBean()
实例化名字是case
的Bean,Spring就不会实例化该Bean。这样正印证了<factory-method>
的特点:只有在调用<factory-method>
指定的方法时才开始实例化Bean,而不是加载spring-config.xml
时就实例化。