从头开始分析webwind框架,结合文章http://www.ibm.com/developerworks/cn/java/j-lo-restmvc/
容器部分:
ContainerFactory接口:工厂接口,用于创建IoC容器.
有2个实现类:SpringContainerFactory 和GuiceContainerFactory
通过这个接口就把Ioc容器的依赖屏蔽掉了,从而达到这个框架和Ioc的解耦,并且,减少了这个开放框架的职责.
voidinit(Config config); //使用Config信息初始化Ioc容器
List<Object>findAllBeans(); //获取所有的Bean,目标是为了后来查找所有的controller的标记方法用的.
voiddestroy(); //容器销毁
这个框架处处显示了基于接口的设计.要仔细分析.
Config接口:包装了ServletConfig和FilterConfig,两个方法:
publicServletContext getServletContext(); //得到servlet的上下文
publicString getInitParameter(String name); //获取servlet上下文初始化参数
这样的话,容器部分就这么简单,应该是使用了抽象隔离了具体实现.
现在具体看一下实现:
GuiceContainerFactory类:
先看初始化:为什么作者没有使用Guice的标注?因为解耦的缘故,所以选择手动加载Guice的注解.
public voidinit(finalConfig config) {
//获取modules参数值
Stringvalue = config.getInitParameter("modules");
if(value==null)
throw newConfigException("Initguice failed. Missing parameter '<modules>'.");
//获取Module类名的列表
String[]ss = value.split(",");
List<Module>moduleList = newArrayList<Module>(ss.length);
for(String s : ss) {
//初始化Module,类名 -->实例
Modulem = initModule(s, config.getServletContext());
if(m!=null)
moduleList.add(m);
}
if(moduleList.isEmpty())
throw newConfigException("Nomodule found.");
//创建injector
this.injector= Guice.createInjector(Stage.PRODUCTION,moduleList);
//将injactor放到servlet上下文中保存.
config.getServletContext().setAttribute(Injector.class.getName(),this.injector);
}
其中:initModule方法:
ModuleinitModule(String s, ServletContext servletContext) {
s= trim(s);
if(s.length()>0) {
//测试的好方法
if(log.isDebugEnabled())
log.debug("Initializingmodule '"+ s + "'...");
try{
//初始化
Objecto = Class.forName(s).newInstance();
if(o instanceofModule) {
//如果实现Module的类同时实现了ServletContextAware,那么就把servletContext注入到Module中
if(o instanceofServletContextAware) {
((ServletContextAware)o).setServletContext(servletContext);
}
return(Module) o;
}
throw newConfigException("Class'"+ s + "'does not implement '"+ Module.class.getName()+ "'.");
}
catch(InstantiationExceptione) {
thrownewConfigException("Cannotinstanciate class '"+ s + "'.",e);
}
catch(IllegalAccessExceptione) {
thrownewConfigException("Cannotinstanciate class '"+ s + "'.",e);
}
catch(ClassNotFoundExceptione) {
thrownewConfigException("Cannotinstanciate class '"+ s + "'.",e);
}
}
returnnull;
}
再看销毁方法:
publicvoiddestroy() {
List<Object>beans = findAllBeans();
for(Object bean : beans) {
if(bean instanceofDestroyable) {
((Destroyable)bean).destroy();
}
}
}
如果类实现了Destroyable接口的话,那么就销毁,否则什么也不做,这个算是观察者模式吧??这里面一个思考就是:如果想强制让某个类做销毁或者初始化等动作,可以定义接口,让类去实现.
最后看一下查找所有bean的方法:很简单,没有什么需要说的.
publicList<Object> findAllBeans() {
Map<Key<?>,Binding<?>> map = injector.getBindings();
Set<Key<?>>keys = map.keySet();
List<Object>list = newArrayList<Object>(keys.size());
for(Key<?> key : keys) {
Objectbean = injector.getInstance(key);
list.add(bean);
}
returnlist;
}
不对spring做分析,因为需要导入很多的jar包.可见Guice的速度肯定比spring快很多.
浙公网安备 33010602011771号