3、tomcat中的设计模式。

这是我主要要写的内容,其中的模式主要是以GOF四人帮的教材作为参考,然后对tomcat中的源码做分析,从而从中分析一些设计模式出来。

[size=18][color=blue]1、Jmx的应用。[/color][/size]
也即MBean的应用,用来处理对象的生存问题。
在tomcat里主要是要实现javax.management.MBeanRegistration这个接口,这就成为一个可注册组件。
abstract public interface MBeanRegistration{
public ObjectName preRegister(MBeanServer server,
ObjectName name) throws Exception ;
public void postRegister(Boolean registrationDone);
public void preDeregister() throws Exception ;
public void postDeregister();
}


通过注册这个组件,就可以在需要的时候取来用。
 public void initialize()
throws LifecycleException
{
oname=new ObjectName( "Catalina:type=Server");
Registry.getRegistry(null, null).registerComponent(this, oname, null );
}


通过如下方法来读取文件的信息,来注册组件。
public class StandardEngine extends ContainerBase
implements Engine {
public void init() {
if( mbeansFile == null ) {
String defaultMBeansFile=getBaseDir() + "/conf/tomcat5-mbeans.xml";
File f=new File( defaultMBeansFile );
if( f.exists() ) mbeansFile=f.getAbsolutePath();
}
if( mbeansFile != null ) {
readEngineMbeans();
}
if( mbeans != null ) {
try {
Registry.getRegistry(null, null).invoke(mbeans, "init", false);
} catch (Exception e) {
log.error("Error in init() for " + mbeansFile, e);
}
}
}
private void readEngineMbeans() {
try {
MbeansSource mbeansMB=new MbeansSource();
File mbeansF=new File( mbeansFile );
mbeansMB.setSource(mbeansF);

Registry.getRegistry(null, null).registerComponent
(mbeansMB, domain + ":type=MbeansFile", null);
mbeansMB.load();
mbeansMB.init();
mbeansMB.setRegistry(Registry.getRegistry(null, null));
mbeans=mbeansMB.getMBeans();

} catch( Throwable t ) {
log.error( "Error loading " + mbeansFile, t );
}
}
}


可以通过如下方法来进行注册组件方法的调用。这个方法主要有两个功能,其一就是确保其父引用不为空,如为空,就调用注册组件的addChild()方法来设置父引用;其二就是注册自己。
public class StandardHost extends ContainerBase
implements Deployer, Host{
public void init() {
if( initialized ) return;
initialized=true;

// already registered.
if( getParent() == null ) {
try {
// Register with the Engine
ObjectName serviceName=new ObjectName(domain +
":type=Engine");

if( mserver.isRegistered( serviceName )) {
log.debug("Registering with the Engine");
mserver.invoke( serviceName, "addChild",
new Object[] { this },
new String[] {"org.apache.catalina.Container" } );
}
} catch( Exception ex ) {
ex.printStackTrace();
}
}

if( oname==null ) {
// not registered in JMX yet - standalone mode
try {
StandardEngine engine=(StandardEngine)parent;
domain=engine.getName();
log.debug( "Register " + domain );
oname=new ObjectName(domain + ":type=Host,host=" +
this.getName());
Registry.getRegistry(null, null)
.registerComponent(this, oname, null);
} catch( Throwable t ) {
log.info("Error registering ", t );
}
}
}
}


[size=18][color=blue]2、Listener的应用。[/color][/size] 主要为java中的事件处理,在java中事件处理从java1.1开始就用的是这种方式,Swing、AWT,SWT都是应用的这种事件模型。这里我举一些事例来说明tomcat中Listener的应用。
LifecycleListener接口处理:Lifecycle、LifecycleListener、LifecycleSupport、LifecycleEvent。
ContainerListener接口处理:Container,ContainerListener、ContainerEvent。
PropertyChangeListener接口处理:PropertyChangeListener、PropertyChangeSupport、PropertyChangeEvent、PropertyChangeListenerProxy。
这里以LifecycleListener接口处理为例:
public interface Lifecycle {
public static final String START_EVENT = "start";
public static final String BEFORE_START_EVENT = "before_start";
public static final String AFTER_START_EVENT = "after_start";
public static final String STOP_EVENT = "stop";
public static final String BEFORE_STOP_EVENT = "before_stop";
public static final String AFTER_STOP_EVENT = "after_stop";
public void addLifecycleListener(LifecycleListener listener);
public LifecycleListener[] findLifecycleListeners();
public void removeLifecycleListener(LifecycleListener listener);
public void start() throws LifecycleException;
public void stop() throws LifecycleException;
}

public final class LifecycleSupport{
public LifecycleSupport(Lifecycle lifecycle) ;
private Lifecycle lifecycle = null;
private LifecycleListener listeners[] = new LifecycleListener[0];
public void addLifecycleListener(LifecycleListener listener) ;
public LifecycleListener[] findLifecycleListeners() ;
public void fireLifecycleEvent(String type, Object data) ;
public void removeLifecycleListener(LifecycleListener listener);
}


public interface LifecycleListener {
public void lifecycleEvent(LifecycleEvent event);
}


public final class LifecycleEvent extends EventObject {
public LifecycleEvent(Lifecycle lifecycle, String type) ;
public LifecycleEvent(Lifecycle lifecycle, String type, Object data) ;
private Object data = null;
private Lifecycle lifecycle = null;
private String type = null;
public Object getData() ;
public Lifecycle getLifecycle() ;
public String getType();
}


Lifecycle为事件源,即事件发生时将触发具体的事件。其中的addLifecycleListener(),和removeLifecycleListener(),负责对监听器进行注册和取消注册。start()和stop()为具体事件的触发源,当然也可以在其它地方触发事件,但这个地方为Lifecycle的接口,这地方最好。当调用start()后,将触发BEFORE_START_EVENT,START_EVENT,AFTER_START_EVENT事件。而stop()将调用BEFORE_STOP_EVENT,STOP_EVENT,AFTER_STOP_EVENT事件。

LifecycleListener为事件监听器,主要负责对事件源进行注册监听器,并监听事件源的触发事件。

LifecycleSupport为监听器LifecycleListener的保持者,也是具体的事件的最终触发者。其中包含一个LifecycleListener列表,当事件触发时,LifecycleSupport.fireLifecycleEvent()负责对LifecycleListener[]进行遍历,找出对应的监听器来触发具体的事件。

LifecycleEvent为具体的事件对象,也是事件触发后生成的事件对象,包含有事件源、事件类型、事件数据等信息。LifecycleListener.lifecycleEvent()运行时就是依靠LifecycleEvent来进行工作的。

[size=18][color=blue]3、Wrapper的应用。[/color][/size]
tomcat中使用Wrapper对我们的servlet进行包装,使容器能够对我们自己写的servlet进行控制,也就是说用Wrapper来进行容器和我们的应用进行通信。
这个模式我还没有搞得清楚,具体情况见Wrapper接口和其具体实现StandardWrapper。


[size=18][color=blue]4、Facade的应用。[/color][/size]
这里要谈的主要是servlet中消息的载体Request和Response中用Facade模式来处理sun规范中javax.servlet.Request和org.apache.catalina.Request之间的区别、javax.servlet.Response和org.apache.cataina.Response之间的区别。RequestFacade和ResponseFacde在这里起到了桥梁的作用。他既实现了javax.servlet.*的接口,又对org.apache.cataina.*进行包装,使*Facade对外就像javax.servlet.*一样。而其内部的实现又是通过org.apache.catanila.*来进行具体实现的,其对*Facade的任何请求都实际交给java.apahce.cataina.*来处理的。

public class ResponseFacade implements ServletResponse {
public ResponseFacade(Response response) {
this.resp = response;
this.response = (ServletResponse) response;
}
protected ServletResponse response = null;
protected Response resp = null;
public String getCharacterEncoding() {
return response.getCharacterEncoding();
}
......
}
public final class HttpResponseFacade
extends ResponseFacade
implements HttpServletResponse {
public HttpResponseFacade(HttpResponse response) {
super(response);
}
public void addCookie(Cookie cookie) {
if (isCommitted())
return;
((HttpServletResponse) response).addCookie(cookie);
}
......
}


从这上面可以看出,在tomcat中数据流都是以http协议来进行传输的,不管是ResponseFacade还是HttpResponseFacade中每个方法的实际执行者都是HttpServletResponse。


[size=18][color=blue]5、StringManager管理信息,处理国际化问题。[/color][/size]
在tomcat中提示消息和输出错误消息都是通过StringManager来管理的,而且还实现了模式的匹配问题,具体如下:
public class StringManager {
private ResourceBundle bundle;
private StringManager(String packageName) ;
public String getString(String key);
protected String getStringInternal(String key) ;
public String getString(String key, Object[] args);
public String getString(String key, Object arg) ;
public String getString(String key, Object arg1, Object arg2);
public String getString(String key, Object arg1, Object arg2,
Object arg3);
public String getString(String key, Object arg1, Object arg2,
Object arg3, Object arg4) ;
private static Hashtable managers = new Hashtable();
public synchronized static StringManager getManager(String packageName);
}


[size=18][color=blue]6、Jndi的应用,处理资源问题。[/color][/size]
这部分我还没有搞的清楚。

[size=18][color=blue]7、tomcat的启动框架。[/color][/size]
这部分我只能说个大概,主要参考tomcat文档。
<Server>
<Listener/>
<GlobalNamingResources/>
<Service>
<Connector/>
<Engine/>
<Logger/>
<Realm/>
<Host>
<Logger/>
<Context>
<Logger/>
</Context>
</Host>
</Service>
</Server>


[size=18][color=blue]8、Notification模式[/color][/size]
这个模式主要是在import javax.management.*中实现的,其具体的实现在mx4j中实现他的具体实现应该和上面的Listener差不多。
其中主要用到的类为:import javax.management.NotificationBroadcasterSupport和import javax.management.Notification。
NotificationBroadcasterSupport是支持类,Notification为封装了具体信息的事件类。[size=12][/size][size=12][/size][size=12][/size][size=12][/size][size=12][/size][size=12][/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值