JETTY源码剖析及总结_第1页
JETTY源码剖析及总结_第2页
JETTY源码剖析及总结_第3页
JETTY源码剖析及总结_第4页
JETTY源码剖析及总结_第5页
已阅读5页,还剩211页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

新版JETTY源码剖析及总结

目录

第一章JETTY源码剖析1

第一节启动篇1

第二节组件启动篇44

第三节应用加载篇48

第四节请求处理上篇93

第五节请求处理下篇119

第六节其余功能篇200

第一章JETTY源码剖析

Jetty资料:

文档都在这里

第一节启动篇

1、启动的方式、选项

•HowtoRunJetty

标准的启动方式就是

Ja-jarstart.jar

我们通过ja-jarstart.jar-helpok.txt命令看看启动参数都有哪些

J

oktxt

生成的文件如下•

下面是所有的文本

Usage:ja-jarstart.jar[options...][properties...][configs...]

Thestart.jarbuildsaclasspathandexecutesamainjaclasswith

aclassloaderbuiltfromthatclasspath.Bydefaultthestart.jar

mechaniisconfiguredtostartthejettyserver,butitcanbe

configuredtostartanyjamainclass.

mandLineOptions:

-helpThishelp/usageinformation.

-versionPrinttheversioninformationforJettyand

dependentjars,thenexit.

-list-optionsListthedetailsofeachclasspathOPTION

该选项列出jettyprojecthome以及分类的jar

[@zw-76-14jetty]#java-jarstart.jar-11st-options|more

Thereare33OPTIONSavailabletouse.

Eachoptionislistedalongwithassociatedaval1ableclasspathentries,intheorderthat

Note::Ifusingmultipleoptions(eg:'server.servlet.webapp,jms,jmx')thenoverlappingentriei

classpath.

${jetty,home)=/opt/whf/soft/jetty

GLOBALoption(PrependedEntries)

Emptyoption,noclasspathentriesactive.

GLOBALoption(AppendedEntries)(*)

0:8.1.7.V2O12O91O|${jetty.home}/lib/jetty-util-8.1.7.V2O12O91O.jar

1:8.1.7.V20120910|home}/lib/jerty-io-8.1.7.V20120910.jar

Option[ajp]

0:8.1.7.V20120910|${jetty.home}/lib/jetty-ajp-8.1.7.V20120910.jar

option[All](Aggregate)

0

1(dir)Stjetty.nomej/resources

28.1.7.V20120910home}/lib/jetty-xml-8.1.7.V2O12O91O.jar

33.0.0.V201112011016Stletty.homej/1ib/servIet-api-3.0.jar

48.1.7.V20120910${jetty.home}/lib/1etty-http-8.1.7.v20120910.jar

58.1.7.V20120910jetty.home)/lib/ietty-continuation-8.1.7.V20120910.jar

68.1.7.V20120910Shetty,homej/lib/ietty-server-8.1.-V--2--0--1--20--9--1-‘0一.jar

78.1.7.V20120910home}/lib/qetty-security-8.7.V20120910.jar

88.1.7.V20120910S{qetty.homej/lib/^etry-servlet-8.1.V20120910.jar

98.1.7.V20120910home}/lib/^etty-webapp-8.1.V20120910.jar

8.1.7.V20120910home}/lib/ietty-deploy-8.1.V20120910.jar

8.1.7.V20120910${ietty.home}/lib/ietty-servlets-8.1.7.V20120910.jar

8.1.7.V20120910${ietty.home}/lib/ietty-rewrite-8.1.7.V20120910.jar

8.1.7.V20120910${ietty.home}/lib/ietty-jmx-8.1.7.V20120910.jar

8.1.7.V20120910${jetty.home}/lib/ietty-ajp-8.1.7.V20120910.jar

8.1.7.V2O12O91O${ietty.home}/lib/ietty-jndi-8.1.7.V20120910.jar

8.1.7.V20120910${ietty.home}/lib/ietty-plus-8.1.7.V20120910.jar

1.1.0.V2O11O5O71233${Jetty.homej/lib/indi/iavax.activation-1.1.0.V2O11O5O71233.

1.4.1.v201005082020${ietty.home}/lib/indi/javax.mail.glassfish-1.4.1.V2O1OO5O82jar

-list-configListthestart.configfile.

该选项没有特别的,就将start.jar里面的start.config文件文本输出

-dry-runPrintthemandlinethatthestart.jargenerates,

thenexit.Thismaybeusedtogeneratemandlines

whenthestart.iniincludes-Xor-Darguments.

所以为了不让它启动,在敲命令时可以这样

ja-jarstart.jar-dry-run-list-config

或者

ja-jarstart.jar-dry-run-list-options

将最后启动后所有的参数列出来,但是实际应用不启动

--execRunthegeneratedmandline(see-dry-run)in

asubprocess.Thiscanbeusedwhenstart.ini

contains-Xor-Darguments,butcreatesanextra

JVMinstance.

该选项是创建一个子进程,并使用start.ini里面的-X,-D参数,因为ja里面一旦进程启动就不能增加・X,-D

参数了,所有创建子进程可以解决这个问题,父进程在子进程结束后退出

手输命令行里也可以不添加一exec,可以改成在start.ini中开启一exec命令,实现一样的效果

-stopStoptherunningJettyinstance.

-daemonStartindaemonmodewithstderrandstdout

redirectedto${jetty.log}/start.log

-config=fileSpecifyanalternatestart.configfile.

Thedefaultisthestart.configfileinside

thestart.jar.Thedefaultcanalsobespecified

withtheSTARTsystemproperty.

-ini=fileLoadmandlineargumentsfromafile.If

no-inioptionsarespecified,thenthe

start.inifilewillbereadifitexistsin

jetty.home.Ifspecifiedjetty.home/start.ini

andadditional.inifilesinjetty.home/start.d/

willNOTberead.A-inioptionwithnofileindicatesthat

start.inishouldnotberead.

可以通过它指定ini,这样默认的就不读了,如果空,就不读ini了

-pre=fileSpecifyaconfigurationfilethatistobeprocessed

beforeanyconfigurationfileslistedinstart.ini

SystemProperties:

Thesearesetwithamandlinelike"ja-Dname=value..."andare

accessibleviatheja.lang.System#getProperty(String)API.

Somekeysystempropertiesare:

org.eclipse.jetty.util.log.class=[class]

ALowLevelJettyLoggerImplementationtouse

(default:org.eclipse.jetty.util.log.Slf4jLog)

org.eclipse.jetty.util.log.DEBUG=[boolean]

DebugloggingforthestderrandjautilLoggers.Slf4j

andotherloggersmustbeseparatelyconfiguredfordebug.

(default:false)

org.eclipse.jetty.util.log.IGNORED=[boolean]

Ignoredexceptionsarelogged,independentofDEBUGsettings

(default:false)

org.eclipse.jetty.util.log.SOURCE=[boolean]

ThesourcelocationoflogsisloggedinthestderrLogger.

(default:false)

.sun.management.jmxremote

EnableremoteJMXmanagementinSunJVMS.

Properties:

Thesearesetwithamandlinelike"ja-jarstart.jarname=value"

andonlyaffectthestartmechani.Someofthesearedefinedinthe

defaultstart.configandwillnotbeailableifanotherconfiguration

fileisused.NOTE:Notallpropertiesarelistedhere:

会覆盖start.config里面相同名字的

注意以下变量在start.config中的配置

path=[directory]

Anadditionalclasspathelementtoaddtothestartedclasspath.Typically

thisisusedtoadddirectoriesofclassesand/orresources

额外的classpath路径

lib=[directory]

Anadditionallibrarydirectorytoaddtothestartedclasspath.Thismust

bea(deep)directoryofjars

STOP.PORT=[number]

TheporttousetostoptherunningJettyserver.

RequiredalongwithSTOP.KEYifyouwanttousethe-stopoptionabove.

STOP.KEY=[alphanumeric]

Thepassphrasedefinedtostoptheserver.

RequriedalongwithSTOP.PORTifyouwanttousethe-stopoptionabove.

DEBUG=true

Enabledebugonthestartmechaniandsetsthe

org.eclipse.jetty.util.log.stderr.DEBUGsystempropertytotrue.

(default:false)

OPTIONS=[option,option,...]

EnableclasspathOPTIONS.Eachoptionsrepresentsoneormorejars

tobeaddedtotheclasspath.Theoptionsaredefinedin

thestart.configfileandcanbelistedwith-helpor-list-options.

Byconvention,optionsstartingwithacapitalletter(egServer)

areaggregationsofotherailableoptions.ailableOPTIONS:

All

Client

Server

ajp

annotations

client

default

deploy

jdbc

jmx

jndi

jsp

jta

monitor

overlay

overlays

plus

policy

resources

rewrite

security

server

servlet

servlets

setuid

spdy

spring

webapp

websocket

xml

ailableConfigurations:

Byconvention,configurationfilesarekeptin$JETTY_HOME/etc.

Theknownconfigurationfilesare:

etc/jetty-ajp.xml

etc/jetty-annotations.xml

etc/jetty-bio-ssl.xml

etc/jetty-bio.xml

etc/jetty-contexts.xml

etc/jetty-debug.xml

etc/jetty-deploy.xml

etc/jetty-fileserver.xml

etc/jetty-hightide.xml

etc/jetty-ipaccess.xml

etc/jetty-jaas.xml

etc/jetty-jmx.xml

etc/jetty-logging.xml

etc/jetty-monitor.xml

etc/jetty-overlay.xml

etc/jetty-plus.xml

etc/jetty-policy.xml

etc/jetty-proxy.xml

etc/jetty-requestlog.xml

etc/jetty-rewrite.xml

etc/jetty-setuid.xml

etc/jetty-spdy-proxy.xmI

etc/jetty-spdy.xml

etc/jetty-ssl.xml

etc/jetty-stats.xml

etc/jetty-testrealm.xml

etc/jetty-webapps.xml

etc/jetty-xid.xml

etc/jetty.xml

Defaults:

Astart.inifilemaybeusedtospecifydefaultargumentstostart.jar,

whichareusedifnomandlineargumentsareprovidedandoverride

thedefaultsinthestart.configfile.Ifthedirectoryjetty.home/start.d

exists,thenmultiple*.inifileswillbereadfromthatdirectoryin

alphabeticalorder.If-inioptionsareprovidedonthemandline,

thenstart.iniandstart.dwillNOTberead.

Thecurrentstart.iniargumentsare:

OPTIONS=Server1jsp,jmx,resources,websocket,ext,plus,annotations,jtajdbc

etc/jetty-jmx.xml

etc/jetty.xml

etc/jetty-hightide.xml

etc/jetty-deploy.xml

etc/jetty-webapps.xml

etc/jetty-contexts.xml

etc/jetty-testrealm.xml

etc/jetty-jaas.xml

HowtoRunJettywithJConsole

•HowtoRunJettyfromasinglejar

可以通过jetty-runner.jar包,直接运行jetty,里面已经包含了所有的jar

示例如下:ja-jarjetty-runner.jarmy.war

ja-jarjetty-runner.jar-path/onemy1.war-path/twomy2

ja-jarjetty-runner.jarcontexts/my.xml

ja-jarjetty-runner.jar-port9090-logmy/request/log/goes/heremy.war

•HowtoRunJettyfromMen

Pom中加上这个plugin

groupldorg.eclipse.jetty/groupld

artifactldjetty-men-plugin/artifactld

/plugin

然后执行mvnjetty:run

HowtoRunJettyfromAnt

•HowtoEmbedJetty

wiki.eclipse/Jetty/Tutorial/EmbeddingJetty

经历以下步骤

1.Createtheserver

2.Add/ConfigureConnectors

3.Add/ConfigureHandlers

4.Add/ConfigureServlets/WebappstoHandlers

5.Starttheserver

6.Wait(jointheservertopreventmainexiting)

publicstaticvoidmain(String[]args)throwsException

(

Serverserver=newServer(8080);

server.setHandler(newHelloHandler());

server.start();

server.joinQ;

)

或者你可以通过xml来配置

Configureid="FileServer"class=Horg.eclipse.jetty.server.Server"

Callname=naddConnector"

Arg

Newclass="org.eclipse.jetty.server.nio.SelectChannelConnector”

Setname=nport"8080/Set

/New

/Arg

/Call

Setname="handler"

Newclass^'org.eclipse.jetty.server.handler.HandlerList"

Setname="handlers"

Arraytype^'org.eclipse.jetty.server.Handler*'

Item

Newclass^'org.eclipse.jetty.server.handler.ResourceHandler"

Setname="directoriesListed"true/Set

Setname="weleFiles"

Arraytype="String',ltemindex.html/ltem/Array

/Set

Setname="resourceBase"./Set

/New

/Item

Item

Newclass="org.eclipse.jetty.server.handler.DefaultHandler"

/New

/Item

/Array

/Set

/New

/Set

然后这样使用

publicclassFileServerXml

publicstaticvoidmain(String[]args)throwsException

Resourcefileserver_xml=Resource.newSystemResource("fileserver.xmr,);

XmlConfigurationconfiguration=newXmlConfiguration(fileserver_xml.getlnputStream());

Serverserver=(Server)configuration.configure();

server.start();

server.join();

)

)

•JettyHelloWorldTutorial

代码如下:

publicclassHelloWorldextendsAbstractHandler

(

publicvoidhandle(Stringtarget,

RequestbaseRequest,

HttpServletRequestrequest,

HttpServletResponseresponse)

throwslOException,ServletException

{

response.setContentType(,ztext/html;charset=utf-8,");

response,setStatus(HttpServletResponse.SCOK);

baseRequest.setHandled(true);

response.getWriter().printin(/zhlHelloWorld/hl^);

}

publicstaticvoidmain(String[]args)throwception

(

Serverserver=newServer(8080);

server.setHandler(newHeiloWorld());

server,start();

server,join();

)

}

然后就可以运行了

ja-cp.:servlet-api-2.5.jar:jetty-al1-$JETTYVERS1OX.jarHeiloWorld

JettyandMenHelloWorldTutorial

•GettingStartingwithJetty(6)(on.itiunqle)

•JettyStart.jar

见start.jar-help

2、启动源码剖析

•入口是start.jar的main方法

publicstaticvoidmain(String[]args)

{

try

(

Mainmain=newMain();

Liststringarguments=main.expandmandLine(args);

Liststringxmls=cessmandLine(arguments);

if(xmls!=null)

main.start(xmls);

)

catch(Throwablee)

{

usageExit(e,ERR_UNKNOWN);

)

)

1获取jettyversion,通过Package。类

if(ver==null){

Packagepkg=Config.class.getPackage();

if(pkg!=null&&

"Eclipse.org-Jettyrr.equals(pkg.getlmplementationVendor())&&

(pkg.getImplementationVersion()!=null))

(

ver=pkg.getImplementationVersion();|

)

)

这些信息是存放在jar的META-INF下面的,implementationversion是版本号

2获取jetty绝对路径

Main()throwslOException

n

_jettyHome=System.getProperty("jetty.home"z.;

_jettyHome=newFile(_jettyHome).getCanonicalPath();

I

3读取start.ini文件

staticListstringloadStartlni(Fileini)

(

if(!ini.exists())

(

System.err.printIn("Warning-can*tfindinifile:"+ini);

//Nostart.inifound,skipload.

returnCollections.emptyList();

)

Liststringargs=newArrayListString();

FileReaderreader=null;

BufferedReaderbuf=null;

try

(

reader=newFileReader(ini);

buf=newBufferedReader(reader);

Stringarg;

while((arg=buf.readLine())!=null)

|

arg=arg.trim();

if(arg.length()==0IIarg.startsWith("#"))

(

continue;

)

args.add(arg);

}

}

catch(lOExceptione)

(

usageExit(e,ERR_UNKNOWN);

)

finally

(

Main.close(buf);

Main.close(reader);

returnargs;

最后加载的默认配置是

[OPTIONS=Server,jsp,jmx,resources,websocket,ext,etc/jetty.xml,

etc/jetty-deploy.xml,etc/jetty-webapps.xml,etc/jetty-contexts.xml,

etc/jetty-testrealm.xml]

这个会加载start.d或者start.ini

如果你在start.ini文件中开启了-exec

那么最后的args是这样的

[-exec

-Dorg.apache.jasperpiler.disablejsrl99=true

-D.sun.management.jmxremote

-Dorg.eclipse.jetty.util.log.IGNORED=true

-Dorg.eclipse.jetty.LEVEL=DEBUG

-Dorg.eclipse.jetty.util.log.stderr.SOURCE=true

-Xmx512m

-Xmnl28m

-verbose:gc

-XX:+PrintateStamps

-XX:+PrintGCTimeStamps

-XX:+Printetails

-XX:+PrintTenuringDistribution

-XX:+PrintmandLineFlags

OPTIONS=Server

jsp

jmx

resources

websocket

ext

etc/jetty.xml

etc/jetty-deploy.xml

etc/jetty-webapps.xml

etc/jetty-contexts.xml

etc/jetty-testrealm.xml]

待会我们去执行-exec时再看看它是如何工作的

最后关闭流,看看它是如何吐到屏幕上去的

publicstaticvoidclose(Closeablec)

{

if(c==null)

{

return;

)

try

(

c.close();

)

catch(IOExceptione)

(

e.printStackTrace(System.err);

)

)

publicstaticvoidmain(String[]args)

(

try

{

Mainmain=newMain();

List<String>arguments=main,expandCommandLine(args);

List<String>xmls=cessCommandLine(arguments);

It(xmls!=null)

main.start(xmls);

)

catch(Throwablee)|

(

usag-eExit(ezERR_UNKNOWN);

)

Main该方将OPTIONS=Server,jsp,jmx,resources,websocket,ext,放至lj_config对象

switch(assign.length)

(

case2:

if(,rOPTIONSrr.equals(assign[O]))

(

Stringopts[]=assign[l].split;

for(Stringopt:opts)

_config.addActiveOption(opt.trim());|

)

else

(

this._config.setProperty(assign[0],assign[l]);

)

break;

case1:

this._config.setProperty(assign[0],null);

break;

default:

break;

)

对应刚才的这些配置文件etc/jetty.xml,

它会调用这个

//AnythingelseisconsideredanXMLfile,

if(xmls.contains(arg))

(

System,out.println(rrWARN:Argument',f+arg+specifiedmultipletj

System.out.println(,rUse\,rjava-jarstart,jar--help\rrformoreinfom

}

xmls.add(arg);

Xmls是一个xml配置数组,接下来就是解析启动这些xml了

我们先看选项一help,呆会我们再回到cesmanLine去看其它选项

publicstaticvoidmain(String[]args)

(

try

(

Hainmain=newMain();

List<String>arguments=main.expandComiaandLine(args);

List<String>xmls=cessCommandLine(arguments);

if(xmls!=null)

main,start(xmls);|

}

catch(Throvablee)

usag-eExit(e,ERRUNKNOWN);

}

privateList<String>loadConfig(List<String>xmls)

(

InputStrearncfgstream=null;

try

{

//Passinxmls.siz^intoConfigsothatconditionsbasedor

_config.setArgCount(xmls.size());

cfgstream=getConfigStream();

//parsetheconfig

_config.parse(cfgstream);

,r,r

_jettyHome=Config.getProperty(jetty,homez_jettyHome);

if(JettyHoiae!=null)

(

_jettyHome=newFile(_jettyHome).getCanonicalPath();

rr,r

Systen.setProperty(jetty.homez_jettyHome);

}

//Collecttheconfiguredxmlconfigurations.

List<String>ret=newArraYList<String>();

ret.addAll(xmls);//addcommandlineprovidedxmlsfirst.

for(Stringxmlconfig:_config.getXmlConfigs())

(

//addxmlconfigsarrivingviastart.config

if(!ret.contains(xmlconfig))

(

ret.add(xmlconfig);

)

}

returnret;

}

catch(Exceptione)

(

先看从一个xml文件解析,首先是得到文件流

privateInputstreamgetConfigStreaia()throvisFi1eNotFoundException

(

Stringconfig=_startConfig;

if(config==nullIIconfig.length()==0)

(

config=System.^etPropertyt^START^z^org/eclipse/jettY/start/start.config,r):

)

Config,(,rconfig=rr+config);

//Lookupconfigasresourcefirst.

InputStrearncfgstream=getClass().getClassLoader().getResourceAsStreaui(config);

//resourcenotfound,tryfilesystemnext

if(cfgstream==null)

(

cfgstream=newFilelnputStream(config);

)

returncfgstream;

)

然后就是解析了

publicvoidparse(InputStrearnstream)throvislOException

(

InputstreamReaderreader=null;

try

(

reader=nevrInputStreaiaReader(stream);

parse(reader);|

)

finally

(

close(reader);

)

)

Config文件的一部分,比如第一行是将config里面或者systemproperties里面的path赋值到${path}里

面,然后成为•个classpath

try

(

StringTokenizerst=newStringTokenizer(line);

Stringsubject=st.nextToken();

booleanexpression=true;

booleannot=false;

/x"line"="${path}.path

Stringcondition=null;

//EvaluateallconditionssTcount=62[0x3e][>]

vihile(st.hasMoreTokens())ahash=0[0x0][A@(NUL)]

(丁。仟set=0[0x0](NUL)]

condition=st.nextToken();

>ETvalue=(id=135)

if(condition.equalsIgnoreCase(,r!r,))

not=true;

continue;${path}.path

)<,______#[>

if(condition.equalsIgnoreCase(,r0R,r))

PressCtrl+Shift+It。Movet。ExpressionsView

if(expression)

break;

StringTokenizer的妙用

else

(

System.err.printin("ERROR:Unknowncondition:"+condition);

eval=false;

}

expression&=not?•eval:eval;

not=false;

按位与的妙用

•Config文件配置说明

Start.config是一个比较重要的配置文件!要好好看

先看一个链接,或者点开下面的txt文件去温习一下,然后看下面的例子

bloq.csdn/dagigi/article/details/6163540

startconfig用法解释.txt

比如第一个${path}.pathpropertypath

elseif(condition.equals("property"))

{

Stringproperty=getl^roperty(st.nextToken());

eval=property!=null&&property.length(>>0;

如果perty中有path则eval会变成true。贝(${path}.path也会加到classpath中

比如我刚刚在启动参数中添加了-Dpath=D:〃xx/classes

因为结尾是path

看它的处理

//Addrawclasspathentry

if(subject.toLowerCase(Locale.ENGLISH).endsWith(".path"))

(

//classpath口etty.class.path?)toaddtoruntimeclasspath

Stringcp=expand(subject,substrings,subject,length。)-5));

if(cn!

(

debv

addC

)

ccmtinue

)

//singleJA

Filef=new

nsole区'

它又将path去除了,最终添加我的属性中的值到classpath中

如下添加到classpath中

privatebooleanaddClasspathPath(List<String>sections,Stringpath)

{

for(Stringsection:sections)

{

Classpathcp=_cla33paths.get(section);

if(cp==null)

{

cp=newClasspath。;

}

if(!cp.addClasspath(path))

(

//Firstfailuremeansallfailed,

returnfalse;

}

_classpaths.put(section,cp);

returntrue;

}

通过debug代码,默认的启动主函数是org.eelipse.jetty.xml.XmlConfiguration.class

你也可以自己指定启动主函数

接下来我们再看一个例子

是如何判断一个class类ailable的

配置文件的一行是这么写的

意思是如果类之前没有加载进来,就将该jar放到classpath中

入口代码

elseif(condition.equals("available"))

(

Stringclass_to__check=st.nextloken();

eval=isAvailable(options,class_to_check);

}

进入detail代码里

privatebooleanisAvailable(List<String>options,Stringclassname)

(

//Trydefault/parentclassloaderfirst,

try

(

Class.forName(clasaname);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论