`

3、tomcat中的设计模式。

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

1、Jmx的应用。
也即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 );
            }
        }
    }
}


2、Listener的应用。 主要为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来进行工作的。

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


4、Facade的应用。
这里要谈的主要是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。


5、StringManager管理信息,处理国际化问题。
在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);
}


6、Jndi的应用,处理资源问题。
这部分我还没有搞的清楚。

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


8、Notification模式
这个模式主要是在import javax.management.*中实现的,其具体的实现在mx4j中实现他的具体实现应该和上面的Listener差不多。
其中主要用到的类为:import javax.management.NotificationBroadcasterSupport和import javax.management.Notification。
NotificationBroadcasterSupport是支持类,Notification为封装了具体信息的事件类。[/size][size=12]
分享到:
评论
1 楼 xiebiao110 2009-10-02  
嗯不错,我也在看tomcat6,tomcat4,分模块来分析,确实不错!

相关推荐

    Tomcat 系统架构与设计模式

    Tomcat 系统架构与设计模式,第 1 部分 工作原理

    Tomcat系统架构与设计模式[整理].pdf

    Tomcat 系统架构与设计模式 Tomcat 系统架构是 Apache 软件基金会的一款开源的 Java Web 服务器,它的架构设计非常复杂,具有很强的模块化特点。本文将从 Tomcat 的工作原理、设计模式两个方面来分析 Tomcat 的...

    Tomcat 系统架构与设计模式,第 1 部分: 工作原理1

    2. 设计模式在 Tomcat 中的应用 在 Tomcat 的架构中,设计模式扮演着至关重要的角色。其中,工厂模式、观察者模式、 Singleton 模式等都得到了广泛的应用。 * 工厂模式:在 Tomcat 中,工厂模式被用于创建和管理...

    Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析1

    3. 面向对象:Tomcat 中的设计模式也体现了面向对象的原则,例如在 Server.xml 文件中,我们可以看到许多对象的实现,例如 Server 对象、Service 对象等,这些对象都有其特定的职责和行为。 Tomcat 的系统架构与...

    Tomcat 系统架构与设计模式1

    介绍tomcat系统架构与设计模式的书籍,希望对大家有帮助

    Java详解Tomcat 的设计模式分析.doc

    Java中的Tomcat是一个广泛应用的开源Web服务器和Servlet容器,其设计模式的巧妙运用对于理解和优化软件架构至关重要。本文主要分析了Tomcat中两种主要的设计模式:门面模式和观察者模式。 1. 门面(Facade)设计...

    tomcat的运行模式

    APR是专门为提高Tomcat性能而设计的一种运行模式。APR利用了本地库的性能优势,可以显著提升Tomcat的性能,特别是在处理大量并发连接的情况下。为了启用APR模式,首先需要在系统中安装APR库,然后在编译或部署Tomcat...

    Java面试专题-面试人员必看-微服务架构面试专题系列:Tomcat+Mysql+设计模式+并发+Netty+JVM.rar

    本面试专题涵盖了微服务架构中的关键组件,包括Tomcat、Mysql、设计模式、并发处理、Netty以及JVM。以下是这些主题的详细说明: 1. **Tomcat**:作为Java Servlet容器,Tomcat是Web应用程序的基础。了解其工作原理...

    java筑基(基础)面试专题系列(一):Tomcat+Mysql+设计模式.rar

    在这个面试专题系列中,我们将聚焦于Tomcat、MySQL和设计模式这三个核心领域,这些都是Java开发者在面试中常常被问及的话题。 首先,让我们深入探讨Tomcat。Tomcat是一款开源的Servlet容器,它是Apache软件基金会...

    java筑基(基础)面试专题系列(一):Tomcat+Mysql+设计模式.zip

    3. 设计模式的分类、原理及在实际项目中的应用案例。 4. Java与数据库交互的API,如JDBC,以及连接池的使用,如C3P0和Druid。 5. 对于并发和多线程的理解,如何在Tomcat环境中处理高并发请求。 6. Web应用的安全性,...

    Tomcat 系统架构与设计模式-来自IBM

    本文以 Tomcat 5 为基础,也...Tomcat 的基本设计思路和架构是具有一定连续性的。 Tomcat 总体结构 Tomcat 的结构很复杂,但是 Tomcat 也非常的模块化,找到了 Tomcat 最核心的模块,您就抓住了 Tomcat 的“七寸”。

    Tomcat的系统架构与模式设计分析

    从标题看上去很大,Tomcat很复杂,不是一篇文章就能说清楚的,就算我想说恐怕我也说不清楚,我主要是想知道Tomcat如何分发请求的,如何处理多用户同时请求的,还有他的容器是如何工作的。这也是一个Web服务器要解决...

    Tomcat中文手册.doc

    3. **Tomcat与JServ的区别**:Tomcat不是JServ,尽管它们都是Servlet容器。JServ是Servlet API 2.0兼容的,而Tomcat是一个重新编写过的容器,兼容Servlet API 2.2和JSP 1.1。Tomcat使用了JServ的一些代码,特别是...

    最新设计模式超级详解+Tomcat架构源码分析+Spring源码分析 资深级设计模型课程

    Spring源码分析,web源码分析,Tomcat架构源码分析都是非常深入的源码级课程,期待研究设计模式和深入学习源码内功的朋友们,一定要仔细的学习研究。 (0);目录中文件数:1个 ├─3.代码.zip (1)\1.笔记;目录中文...

Global site tag (gtag.js) - Google Analytics