设为首页 收藏本站
查看: 961|回复: 0

[经验分享] jetty_webappcontext

[复制链接]

尚未签到

发表于 2017-2-25 12:06:19 | 显示全部楼层 |阅读模式
1.概述
  jetty的web工程主要完成servlet中context的管理,war包中web.xml中文件等的解析和加载,类加载器等一些功能。

2. 类图和解释

  webAppContext是中心,其中包括classloader,configuration和metadata三个主要的内容,classloadee后面再说,configuration主要是对一些配置的应用,比如调用加载器加载jar包,根据web.xml中的配置初始化servlet等等。metadata主要是元数据的定义和处理,展开类图如下:

  其中descriptor主要完成xml文件的解析,这里包括web.xml,webdefault.xml,web-fragment.xml等,然后DescriptorProcessor主要是将解析好的文件转换为需要使用的数据结构,或者设置context等的一些相应的值。

3.启动过程

  server,connector,handler等都继承了abstractLifeCycle(实现LifeCycle接口)。


  • server的dostart过程包括:启动threadPool,启动handler,启动connector(分别调用它们的doStart方法)
  • hanlder(webappContext)的doStart方法又包括如下步骤:

    1
    2
    3


                preConfigure();
    super.doStart();
    postConfigure();

  • preConfigure()完成的主要工作包括:初始化所有的Configuration,定义systemClass和serverClass,创建webappClassLoader,调用configuration的preconfigure方法。其中WebInfConfiguration主要完成将war包解压的临时文件夹,根据定义加载一些控制扫描jar包的顺序(比如扫描jar包中的web-fragment.xml), webxmlConfiguration主要完成webdefault.xml,web.xml和web-fragment.xml文件的resource定位和加载。还有几个在此就不详述了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32


             loadConfigurations();
     
    // Setup system classes
    loadSystemClasses();
     
    // Setup server classes
    loadServerClasses();
     
    // Configure classloader
    _ownClassLoader=false;
    if (getClassLoader()==null)
    {
    WebAppClassLoader classLoader = new WebAppClassLoader(this);
    setClassLoader(classLoader);
    _ownClassLoader=true;
    }
     
    if (Log.isDebugEnabled())
    {
    ClassLoader loader = getClassLoader();
    Log.debug("Thread Context class loader is: " + loader);
    loader=loader.getParent();
    while(loader!=null)
    {
    Log.debug("Parent class loader is: " + loader);
    loader=loader.getParent();
    }
    }
     
    // Prepare for configuration
    for (int i=0;i<_configurations.length;i++)
    _configurations[i].preConfigure(this);

  • start方法先将classloader设置到线程上下文加载器,然后调用startContext,分为以下3个步骤


1
2
3
4
5
6
7
8
9
10


protected void startContext()
throws Exception
{
configure();
 
//resolve the metadata
_metadata.resolve(this);
 
super.startContext();
}




  • configure步骤主要调用各个configuration的configure方法,其中webinfconfiguration主要完成两件事情,吧WEB-INF的class文件夹和lib文件夹下得jar加入到webappClassloader的classpath中,然后读取RESOURCE_URLS,设置BaseResource。webxmlconfiguration主要addDescriptorProcessor。
  • metadata.resolve主要完成web.xml(包括servlet注解)中定义的filter,servlet等得解析和初始化化(比如解析到servelet,就会load这个class等),这里一个stranderProcess可以处理webDefaultDescriptor,WebDescriptor等多个文件,处理过程一样,只是处理内容不同。这里以后再扩展一下。
  • 通知所有的contextlistener发生了contextInitialized(event)事件。初始化servletHandler,securityhandler和sessionHandler,并把他们链接起来,最后调用_servletHandler.initialize();,从而调用各个servletHolder的dostart。

4.ClassLoad机制
  jetty的classload机制很简单,对于system(系统类)的class,使用jdk的方式(双亲委派)加载,对于server(服务器类,app不可见)的class, ,对于app的class,使用WebAppClassloader来加载,核心代码如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56


@Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
Class<?> c= findLoadedClass(name);
ClassNotFoundException ex= null;
boolean tried_parent= false;
 
boolean system_class=_context.isSystemClass(name);
boolean server_class=_context.isServerClass(name);
 
if (system_class && server_class)
{
return null;
}
 
if (c == null && _parent!=null && (_context.isParentLoaderPriority() || system_class) && !server_class)
{
tried_parent= true;
try
{
c= _parent.loadClass(name);
if (Log.isDebugEnabled())
Log.debug("loaded " + c);
}
catch (ClassNotFoundException e)
{
ex= e;
}
}
 
if (c == null)
{
try
{
c= this.findClass(name);
}
catch (ClassNotFoundException e)
{
ex= e;
}
}
 
if (c == null && _parent!=null && !tried_parent && !server_class )
c= _parent.loadClass(name);
 
if (c == null)
throw ex;
 
if (resolve)
resolveClass(c);
 
if (Log.isDebugEnabled())
Log.debug("loaded " + c+ " from "+c.getClassLoader());
 
return c;
}


  其中=_context.isSystemClass(name)方法是查看是否为systemclass,systemclass都通过正则的方式定义在context中了(通过解析配置systemclass名称的字符串得到)


1
2
3
4
5
6
7


    public boolean isSystemClass(String name)
{
if (_systemClasses == null)
loadSystemClasses();
 
return _systemClasses.match(name);
}


  这里它没有使用tomcat那样多重的继承关系,哪些class是system的,哪些是server的,都是可以自己定义的


1


public void addSystemClass(String classname)


  也可以通过配置文件来定义。
  通过上面的代码可以看到,一个类被判断为systemclass时,就会委托给系统类加载器,如果是serverclass,就一定会勇webxppClassLoader加载,由于WEB-INF/lib中并没有org.jetty.类,而且由于以下的代码,保证server类不会委托给系统类加载器,所以如果WEB-INF/lib没有,就会报ClassnotFound,从而达到了容器类对于应用不可见的目的。
  (测试时,可以在pom中引入jetty的容器类,但定义为provided,或者直接用class.forname之类的方式来测)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-347046-1-1.html 上篇帖子: Jetty--Quick Start 下篇帖子: jetty_classloader
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表