对于单例模式的创建有多种方式,比较常用的是:
这种写法是当我们第一次调用getNewInstance()方法的时候就会生成new一个对象。或者直接在类的初始化的时候生成new一个唯一对象,这样的好处是第一次调用的时候对象就已经生成了,缺点也很明显,没有调用,对象依然存在。那么spring 中如何应用单例模式生成对象的呢?
在spring中配置的Bean,如果没有明确指定,那么都是以单例模式创建的。spring 如何实现单例的?尤其对于多个bean又是如何管理的呢?网上搜了一下,对于spring单例注入采用单例注册表的方式。查看srping源代码(spring-framework-3.1.2.RELEASE),发现有一个Map结构存储了对应的信息:
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();
其中key是bean名称,key是生成对象。对于spring中的单例创建,可以简单模拟为以下代码:
对于采用map结构,也说明了当两个同样bean被注入的时候,后注入的对象会overriding前面注册的对象。
package com.mm.design;
public class SinglePattern {
private String name;
private static SinglePattern single ;
//将构造器私有化
private SinglePattern(String name){
this.name = name;
}
//单线程
public static SinglePattern getNewInstance(String name){
if(single == null){
single = new SinglePattern(name);
}
return single;
}
//多线程访问
public static SinglePattern getNewInstanceInMultThread(String name){
if(single == null){
synchronized (SinglePattern.class) {
if(single==null){
single = new SinglePattern(name);
}
}
}
return single;
}
}
这种写法是当我们第一次调用getNewInstance()方法的时候就会生成new一个对象。或者直接在类的初始化的时候生成new一个唯一对象,这样的好处是第一次调用的时候对象就已经生成了,缺点也很明显,没有调用,对象依然存在。那么spring 中如何应用单例模式生成对象的呢?
在spring中配置的Bean,如果没有明确指定,那么都是以单例模式创建的。spring 如何实现单例的?尤其对于多个bean又是如何管理的呢?网上搜了一下,对于spring单例注入采用单例注册表的方式。查看srping源代码(spring-framework-3.1.2.RELEASE),发现有一个Map结构存储了对应的信息:
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();
其中key是bean名称,key是生成对象。对于spring中的单例创建,可以简单模拟为以下代码:
package com.mm.design;
import java.util.HashMap;
import java.util.Map;
public class SinglePatternSpring {
//将单例在map中注册
private static Map<String ,SinglePatternSpring> map = new HashMap<String,SinglePatternSpring>();
static{
//将类名和对象实例 作为key和value
SinglePatternSpring single = new SinglePatternSpring();
map.put(single.getClass().getName(), single);
}
private SinglePatternSpring(){
}
public static SinglePatternSpring getNewInstance(String name){
if(name == null){
//如果传入默认为空 默认返回对象
name = SinglePatternSpring.class.getName();
}
if(map.get(name) == null){
try {
map.put(name, (SinglePatternSpring) Class.forName(name).newInstance());
} catch (Exception e) {
System.out.println("创建单例失败!");
}
}
return map.get(name);
}
}
对于采用map结构,也说明了当两个同样bean被注入的时候,后注入的对象会overriding前面注册的对象。