Tomcat源码阅读之StandarWrapper源码分析

本文详细分析了Tomcat中的StandarWrapper类,它是Servlet的包装器,负责创建和初始化Servlet对象。讲解了StandarWrapper的继承结构、接口实现、重要方法如load和initServlet,以及在请求处理中的关键角色,特别是StandardWrapperValve的invoke方法,揭示了过滤器和Servlet的执行流程。文章最后讨论了StandarWrapper在创建ApplicationFilterChain时未做缓存的问题,对比了Jetty的优化策略。
摘要由CSDN通过智能技术生成

这几天有点杂事,没有怎么看代码了,今天来把最下层的Container对象看了吧,这里之所以说它是最下层的container对象,是因为它不能在调用addChild方法来添加其他的子container对象了。。。

StandarWrapper,嗯,其实可以将其理解为对servlet对象的包装。。。先来看看简单的继承结构吧:



这里的继承体系还算是比较简单吧,首先是继承了ContainerBase,让StandarWrapper有了基本的对Container的管理能力,其实是先了ServletConfig接口,这个接口应该比较熟悉吧,在servlet的初始化的时候,传进去的就是这个参数,另外就是还有实现了Wrapper接口和NotificationEmitter。。。

从前面可以知道,Wrapper对象是在ContextConfig对象中解析web应用程序的配置的时候创建的,它会读取配置文件里面申明的class属性,name,以及一些参数等。。。

这里先来看看Wrapper接口的定义吧:

//wrapper接口的定义,这里可以理解为对servlet的包装
public interface Wrapper extends Container {
	//一些事件的定义,主要是添加和移除map的信息
    public static final String ADD_MAPPING_EVENT = "addMapping";  
    public static final String REMOVE_MAPPING_EVENT = "removeMapping";


    // 返回这个servlet还需要多长时间可以用
    public long getAvailable();


    // 
    public void setAvailable(long available);

    //是否要在加载的时候启动,如果是负的话,那么表示在第一次调用的时候启动
    public int getLoadOnStartup();

    public void setLoadOnStartup(int value);
    public String getRunAs();

    public void setRunAs(String runAs);

    //servlet的class
    public String getServletClass();


    // 设置servlet的class
    public void setServletClass(String servletClass);

    //servlet支持的所有方法
    public String[] getServletMethods() throws ServletException;

    //现在是否不能用
    public boolean isUnavailable();

    //返回servlet对象
    public Servlet getServlet();

    //设置关联的servlet对象
    public void setServlet(Servlet servlet);

    //添加servlet的初始化参数
    public void addInitParameter(String name, String value);

    //添加监听
    public void addInstanceListener(InstanceListener listener);

    //为当前servlet添加map信息
    public void addMapping(String mapping);

    public void addSecurityReference(String name, String link);

    //这里表示分配一个servlet对象,这里会区分当前servlet的环境,如果不是单线程模式的吧,那么所有的都返回同一个对象
    public Servlet allocate() throws ServletException;


    //表示返回一个servlet到pool里面,只有在servlet配置为单线程模式的时候才有用
    public void deallocate(Servlet servlet) throws ServletException;

    //获取一个初始化的参数的值
    public String findInitParameter(String name);


    //返回所有的初始化参数的名字
    public String[] findInitParameters();


    //返回这个servlet所有的map信息
    public String[] findMappings();

    public String findSecurityReference(String name);

    public String[] findSecurityReferences();

    //增加错误计数
    public void incrementErrorCount();

    //加载并初始化servlet对象
    public void load() throws ServletException;

    //移除一个初始化的参数
    public void removeInitParameter(String name);

    //移除listener
    public void removeInstanceListener(InstanceListener listener);

    //移除一个mapping信息
    public void removeMapping(String mapping);

    public void removeSecurityReference(String name);

    public void unavailable(UnavailableException unavailable);

    //这里表示卸载所有的servlet实例
    public void unload() throws ServletException;

    public MultipartConfigElement getMultipartConfigElement();


    public void setMultipartConfigElement(
            MultipartConfigElement multipartConfig);

    //该servlet是否支持异步
    public boolean isAsyncSupported();

    public void setAsyncSupported(boolean asyncSupport);

    //当前关联的servlet是否可用
    public boolean isEnabled();

    public void setEnabled(boolean enabled);

    public void setServletSecurityAnnotationScanRequired(boolean b);

    public void servletSecurityAnnotationScan() throws ServletException;

    public boolean isOverridable();

    public void setOverridable(boolean overridable);
}

嗯,方法的定义虽然还比较的多,但其实都还算是比较简答的,首先是两个事件的定义,分别是添加和移除map的信息,然后就还有一些属性的设置和获取的方法,最后还有比较重要的就是load方法,用于加载servlet对象。。


这里先来看看构造方法和一些重要的属性申明吧:

    protected static final String[] DEFAULT_SERVLET_METHODS = new String[] {
                                                    "GET", "HEAD", "POST" };
    public StandardWrapper() {

        super();
        swValve=new StandardWrapperValve();  //创建pipeline上的basic的valve对象
        pipeline.setBasic(swValve);
        broadcaster = new NotificationBroadcasterSupport();

    }

    protected long available = 0L;  //还需要多少事件当前servlet可以用,如果是0的话,那么表示servlet现在就可以用了


    protected final NotificationBroadcasterSupport broadcaster;


    protected final AtomicInteger countAllocated = new AtomicInteger(0);  //已经分配了servlet对象的数目,单线程模式下


    protected final StandardWrapperFacade facade = new StandardWrapperFacade(this);  //servletConfig对象,用于维护servlet的初始化参数什么的,其实是对standerWrapper进行了包装



    protected volatile Servlet instance = null;  //共享模式下的对象

    protected volatile boolean instanceInitialized = false;  //用于标记servlet对象是否初始化

    protected final InstanceSupport instanceSupport = new InstanceSupport(this);   //用于处理一些实例的事件

    protected int loadOnStartup = -1;  //是否在加载的时候启动servlet,默认不是

    protected final ArrayList&
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值