模块工厂 TLObjectFactory 负责模块的创建、初始化和存储。每次程序运行,首先实例化模块工厂,然后由模块工厂启动主模块。
源码:
public class TLObjectFactory extends TLBaseModule {
public static final String FACTORY_GETMODULE = "getModule";
public static final String FACTORY_MODULEINSTANCE = "instance";
public static final String FACTORY_MODULENAME = "moduleName";
public static final String FACTORY_NEWMODULENAME = "newModuleName";
public static final String SESSIONDATAMODULE="sessionData";
protected HashMap<String, ArrayList<Object>> objects ;
protected HashMap<String, HashMap<String,String>> modulesClass;
public TLObjectFactory(String name) {
super(name);
}
public void destroyModule(){
Object module;
TLMsg msg=createMsg().setAction("destroy");
for (String key : modules.keySet())
{
module=modules.get(key);
if(module instanceof IObject)
{
putLog(((IObject) module).getName()+" is destoryed", LogLevel.WARN);
putMsg((IObject) module,msg);
}
}
}
@Override
protected void init() {
}
@Override
protected TLMsg checkMsgAction(Object fromWho, TLMsg msg) {
TLMsg returnMsg = null;
switch (msg.getAction()) {
case FACTORY_GETMODULE:
returnMsg = getModule(fromWho, msg);
break;
case "getObjects":
String classname = (String) msg.getParam("classname");
returnMsg = createMsg().setParam("object", objects.get(classname));
break;
case "registObject":
registObject(fromWho, msg);
break;
case "getModuleInFactory":
returnMsg=getModuleInFactory(fromWho,msg);
break;
case "registInFactory":
modules.put((String) msg.getParam(FACTORY_MODULENAME), msg.getParam(INSTANCE));
break;
case "removeFromFactory":
modules.remove((String) msg.getParam(FACTORY_MODULENAME));
break;
default:
}
return returnMsg;
}
private TLMsg getModuleInFactory(Object fromWho, TLMsg msg) {
Object module=modules.get(msg.getParam(FACTORY_MODULENAME));
return createMsg().setParam(FACTORY_MODULEINSTANCE, module);
}
private void registObject(Object fromWho, TLMsg msg) {
Object object = msg.getParam("object");
if (object == null)
object = fromWho;
String name = (String) msg.getParam("classname");
if (name == null || name.isEmpty())
name = object.getClass().getSimpleName();
ArrayList<Object> objs = objects.get(name);
if (objs == null) {
objs = new ArrayList<>();
objects.put(name, objs);
}
objs.add(object);
}
protected TLMsg getModule(Object fromWho, TLMsg msg) {
String moduleName = (String) msg.getParam(FACTORY_MODULENAME);
String newModuleName = (String) msg.getParam(FACTORY_NEWMODULENAME);
String msingleton = (String) msg.getParam("singleton");
if (newModuleName == null) {
newModuleName =moduleName;
}
return creatAndConfigModule(newModuleName,moduleName,msingleton);
}
protected TLMsg creatAndConfigModule(String newModuleName,String moduleName,String msingleton) {
Object module;
Boolean singleton=isSingleton( moduleName, msingleton);
TLMsg returnMsg = createMsg();
if (singleton==true )
{
if( modules.get(newModuleName) != null)
{
module = modules.get(newModuleName);
}
else {
module=getFromSession(newModuleName);
}
if(module!=null){
returnMsg.setParam(FACTORY_MODULEINSTANCE, module);
returnMsg.setParam(FACTORY_MODULENAME, newModuleName);
return returnMsg;
}
}
module = createModule( moduleName,newModuleName);
if (module != null)
{
if (singleton==true)
{
modules.put(newModuleName, module);
putToSession(newModuleName,module);
returnMsg.setParam("singleton", "true");
}
else
returnMsg.setParam("singleton", "false");
returnMsg.setParam("new", "true");
}
returnMsg.setParam(FACTORY_MODULEINSTANCE, module);
returnMsg.setParam(FACTORY_MODULENAME, newModuleName);
return returnMsg;
}
private Boolean isSingleton(String moduleName,String msingleton){
String singletonInConfig="true";
if(modulesClass.get(moduleName)!=null)
singletonInConfig= modulesClass.get(moduleName).get("singleton");
Boolean singleton=true;
if((msingleton != null && msingleton.equals("false")) || (singletonInConfig!=null && singletonInConfig.equals("false")))
singleton=false ;
return singleton ;
}
private Object getFromSession(String moduleName){
String inSession = null;
if(modulesClass.get(moduleName)!=null)
inSession= modulesClass.get(moduleName).get("inSession");
if(inSession==null || inSession.equals("false"))
return null;
TLBaseSessionData sessionData= getSessionObj();
TLMsg returnMsg =putMsg(sessionData,createMsg().setAction("getSessionData").setParam("key",moduleName));
Object module =returnMsg.getParam("value");
if(module!=null)
{
modules.put(moduleName,module);
return module;
}
return null ;
}
private Boolean putToSession(String moduleName,Object module){
String inSession = null;
if(modulesClass.get(moduleName)!=null)
inSession= modulesClass.get(moduleName).get("inSession");
if(inSession==null || inSession.equals("false"))
return false;
TLBaseSessionData sessionData= getSessionObj();
putMsg(sessionData,createMsg().setAction("putSessionData")
.setParam("key",moduleName).setParam("value",module));
return true;
}
private TLBaseSessionData getSessionObj(){
TLBaseSessionData sessionData= (TLBaseSessionData) modules.get(SESSIONDATAMODULE);
if(sessionData==null)
{
sessionData= (TLBaseSessionData) createModule(SESSIONDATAMODULE,SESSIONDATAMODULE);
modules.put(SESSIONDATAMODULE,sessionData);
}
return sessionData;
}
protected Object createModule(String moduleName,String newModuleName) {
String classFilename;
String configFile = null;
HashMap<String ,String> moduleConfig=modulesClass.get(moduleName);
HashMap<String, String> params = null;
if(moduleConfig!=null)
{
configFile= moduleConfig.get("configfile");
params=getModuleParams(moduleName);
String proxyModule= moduleConfig.get("proxyModule");
if(proxyModule !=null && !proxyModule.isEmpty())
{
moduleName =proxyModule;
}
classFilename = modulesClass.get(moduleName).get("classfile");
}
else {
classFilename =moduleName;
}
Object module = createObject(newModuleName, classFilename);
if (module != null)
{
configModule( module, configFile, params);
}
return module;
}
protected void configModule(Object module, String configfile,HashMap<String, String> params) {
if( module==null)
return ;
if(module instanceof TLBaseModule)
{
((TLBaseModule) module).start(configfile,params);
}
}
protected HashMap<String, String> getModuleParams(String moduleName){
HashMap<String, String> moduleConfig=modulesClass.get(moduleName);
if(moduleConfig==null)
return null;
HashMap<String, String> params = null;
for (String key : moduleConfig.keySet()) {
if(!key.equals("name")&& !key.equals("classfile")&& !key.equals("singleton")){
if(params==null)
params = new HashMap<>();
params.put(key,moduleConfig.get(key));
}
}
return params;
}
protected Object createObject(String moduleName, String className) {
Class<?> cls = null; // 取得Class对象
try {
cls = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
putLog(className+" 没有找到类文件",LogLevel.ERROR);
return null;
}
Constructor<?> cons = null;
try {
cons = cls.getConstructor(String.class, TLObjectFactory.class);
} catch (NoSuchMethodException e1) {
try {
cons = cls.getConstructor(String.class);
} catch (NoSuchMethodException e2) {
Object obj = null;
try {
obj = cls.newInstance();
} catch (InstantiationException e3) {
putLog(className+" 实例化异常 e3",LogLevel.ERROR);
e3.printStackTrace();
} catch (IllegalAccessException e4) {
putLog(className+" 非法访问 e4",LogLevel.ERROR);
e4.printStackTrace();
}
return obj;
}
try {
return cons.newInstance(moduleName); // 为构造方法传递参数
} catch (InstantiationException e5) {
putLog(className+" 实例化异常 e5",LogLevel.ERROR);
e5.printStackTrace();
} catch (IllegalAccessException e6) {
putLog(className+" 非法访问 e6",LogLevel.ERROR);
e6.printStackTrace();
} catch (InvocationTargetException e7) {
putLog(className+" 反射异常 e7",LogLevel.ERROR);
e7.printStackTrace();
}
}
try {
return cons.newInstance(moduleName, this);
} catch (InstantiationException e8) {
putLog(className+" 实例化异常 e8",LogLevel.ERROR);
e8.printStackTrace();
} catch (IllegalAccessException e9) {
putLog(className+" 非法访问 e9",LogLevel.ERROR);
e9.printStackTrace();
} catch (InvocationTargetException e10) {
putLog(className+" 反射异常 e10",LogLevel.ERROR);
e10.printStackTrace();
}
return null;
}
}
主要属性:
HashMap<String, HashMap<String,String>> modulesClass
模块类表。格式:模块名->模块参数(类名、配置文件名、其他参数)
模块参数中,类名为必须,根据类名创建模块,其他参数为可选。配置文件名如果没有指定,则查找默认配置,格式: 模块名_config.xml。如果找到则用该文件配置模块。
模块工厂也是对TLBaseModule的继承,因此也具备普通模块的功能。一般情况我们只是用它创立、获取模块,主要用的消息action为“getModule”’。
对于多线程编程中,有些模块为主线程下才可用或被多线程公用,这样里面增加了session模块,一些模块可以存储到session里,不同的环境session实现不同,在tomcat中,通过context实现session。对于一个模块是否存到session中,在配置文件里面可配置。
前面提到,在TLBaseModule的putMsg中,我们封装了模块的获取,因此一般情况也无需特意给模块工厂发送消息获取模块。
具体应用环境中,由于不同的环境配置文件目录不同,因此具体应用中要新建立一个模块工厂类继承该模块工厂。新建的类主要设置配置文件目录,见后续案例。