刚看完gof的登记式单例,联想到spring容器的单例管理,根据自己的想法,写一个java语言的登记式单例模式,先记录下来。等看spring容器对bean的管理源码时再看其单例管理是如何实现的(spring容器应该是根据配置文件在加载时就用一个map缓存单例实例,取实例时根据scope属性在对应的缓存中找获取实例),然后对比学习。
下面是代码:
登记管理类
package com.shuidexiongdi.pattern.singleton.reg;
import java.util.HashMap;
import java.util.Map;
/**
* 单例注册管理类
* @author Djq
*
*/
public abstract class SingletonRegistryManager {
private static Map singletonMap = new HashMap();
/**
* 获取实例
* @param className
* @return
*/
public static Object getInstance(String className) {
if(isRegistred(className)) {
return singletonMap.get(className);
}
return null;
}
/**
* 获取实例
* @param clazz
* @return
*/
public static Object getInstance(Class clazz) {
return getInstance(clazz.getName());
}
/**
* 注册
* @param className
*/
public synchronized static void registry(String className) {
if(!singletonMap.containsKey(className)) {
try {
singletonMap.put(className, Class.forName(className).newInstance());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 注册
* @param clazz
*/
public synchronized static void registry(Class clazz) {
registry(clazz.getName());
}
/**
* 反注册
* @param className
*/
public synchronized static void unRegistry(String className) {
if(singletonMap.containsKey(className)) {
singletonMap.remove(className);
}
}
/**
* 反注册
* @param clazz
*/
public synchronized static void unRegistry(Class clazz) {
unRegistry(clazz.getName());
}
public synchronized static boolean isRegistred(String className) {
return singletonMap.containsKey(className);
}
public synchronized static boolean isRegistred(Class clazz) {
return isRegistred(clazz.getName());
}
}
可注册为单例类的类:
package com.shuidexiongdi.pattern.singleton.reg;
public class SingletonOne {
protected SingletonOne () {
}
public static SingletonOne getInstance() {
if(SingletonRegistryManager.isRegistred(SingletonOne.class)) {
return (SingletonOne)SingletonRegistryManager.getInstance(SingletonOne.class);
}
return new SingletonOne();
}
}
测试:
package com.shuidexiongdi.pattern.singleton.reg.test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.shuidexiongdi.pattern.singleton.reg.SingletonOne;
import com.shuidexiongdi.pattern.singleton.reg.SingletonRegistryManager;
public class SingletonResgistryManagerTest {
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void registry() {
assertFalse(SingletonRegistryManager.isRegistred(SingletonOne.class));
//注册
SingletonRegistryManager.registry(SingletonOne.class);
assertTrue(SingletonRegistryManager.isRegistred(SingletonOne.class));
}
@Test
public void unRegistry() {
//注册
SingletonRegistryManager.registry(SingletonOne.class);
//反注册
SingletonRegistryManager.unRegistry(SingletonOne.class);
assertFalse(SingletonRegistryManager.isRegistred(SingletonOne.class));
}
@Test
public void getInstance() {
//未注册
Object obj = SingletonRegistryManager.getInstance(SingletonOne.class);
assertNull(obj);
//注册
SingletonRegistryManager.registry(SingletonOne.class);
Object notObj = SingletonRegistryManager.getInstance(SingletonOne.class);
assertNotNull(notObj);
assertTrue(notObj instanceof SingletonOne);
//再次获取实例
Object notObj2 = SingletonRegistryManager.getInstance(SingletonOne.class);
assertSame(notObj, notObj2);
//反注册
SingletonRegistryManager.unRegistry(SingletonOne.class);
Object afterUnRegistryObj = SingletonRegistryManager.getInstance(SingletonOne.class);
assertNull(afterUnRegistryObj);
}
}
package com.shuidexiongdi.pattern.singleton.reg.test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.shuidexiongdi.pattern.singleton.reg.SingletonOne;
import com.shuidexiongdi.pattern.singleton.reg.SingletonRegistryManager;
public class SingletonOneTest {
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void getInstance() {
//未注册单例
Object obj = SingletonOne.getInstance();
assertNotNull(obj);
//第二次获取
Object obj2 = SingletonOne.getInstance();
assertNotSame(obj, obj2);
//注册单例
SingletonRegistryManager.registry(SingletonOne.class);
Object afterRegObj = SingletonOne.getInstance();
assertNotNull(afterRegObj);
//第二次获取
Object afterRegObj2 = SingletonOne.getInstance();
assertSame(afterRegObj, afterRegObj2);
//反注册单例
//注册单例
SingletonRegistryManager.unRegistry(SingletonOne.class);
Object afterUnRegObj = SingletonOne.getInstance();
assertNotNull(afterUnRegObj);
//第二次获取
Object afterUnRegObj2 = SingletonOne.getInstance();
assertNotSame(afterUnRegObj, afterUnRegObj2);
}
}
package com.shuidexiongdi.pattern.singleton.reg.test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({SingletonOneTest.class, SingletonResgistryManagerTest.class})
public class TestAllSuite {
}