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之类的方式来测)
相关推荐
jetty_8.1.17_API.chm ,从jetty-distribution-8.1.17.v20150415.zip编译
jetty_7.6.17_API.chm ,从jetty-distribution-7.6.17.v20150415.zip中编译
eclipse插件,jetty_svn。使用links方式安装,直接解压在eclipse 根目录下就行。
maven jetty插件配置指南。 看看就知道。
jetty socket java c# 互相调用 jetty socket java c# 互相调用 jetty socket java c# 互相调用
jetty开通jmx的方式,亲测有效。
支持web接口的批处理框架 在eclipse中导出为可执行的jar,无需部署到任何web容器中。直接通过bat或shell启动即可。...mybatis3.4.1 druid1.0.17 smg3(决策引擎) jetty8.1.5 fastjson1.2.7 springjdbc3.2.14
通过android studio倒入i-jetty-ui工程,会发现无法运行,问题的原因一个是没有引入jetty相关的jar,另一个就是没有合并i-jetty-server代码,当jetty相关jar引入成功,i-jetty-server代码合并完成以后就可以运行了
jetty-distribution-7.6.16.v20140903.zip中的doc编译的chm
eclipse 插件,包括 SVN中文,jetty 和 mybatipse 以及打开文件夹位置的插件。 直接解压到eclipse的根目录就行
利用该资源能有效的搭建起web项目开发平台,能顺利有效地进行资源开发。
Jetty6_指南书 Jetty6_指南书 Jetty6_指南书Jetty6_指南书 Jetty6_指南书 Jetty6_指南书
正在维护项目中的一个中间件之一,使得在嵌入式程序中快速搭建WEB服务,或使用HTTP Client服务抑或Apache MINA的推送服务变得容易。
把${jetty_home}/lib/jsp-2.1目录复制到${project_home}/jetty/lib目录下(如果不复制jsp-2.1或jsp-2.0也可以正常启动,只是不能解析jsp,打开主页时提示 JSP not support)。 同样把jetty-6.1.14.jar、jetty-util-...
runjettyrun.jetty8_1.3.2.jar
角色变量jetty_version 将要安装的 Jetty 版本。 (默认为9.2.3.v20140905 。) jetty_host 听什么主持人。 默认情况下,它侦听所有接口。 jetty_port 要侦听的 HTTP 端口。 默认情况下,它侦听端口8080 。 jetty_...
java运行依赖jar包
jsf_primefaces_app_with_embedded_jetty_9_container 真是一件很酷的事情。 我设法使用嵌入式 Jetty9 容器运行带有 primefaces 框架的 JSF 应用程序。
最新官网下载的runjettyrun.jetty9_1.3.4.jar,里面包含runjettyrun.jetty7_1.3.4.jar,runjettyrun.jetty8_1.3.4.jar,runjettyrun.jetty9_1.3.4.jar,runjettyrun_1.3.4.jar四个文件,解压后放在eclipse目录下的...
需要安装runjettyrun.jetty9_1.3.5的, runjettyrun.jetty9_1.3.5.201802101211.jar