




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
新版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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 薯类批发商市场供需分析考核试卷
- 贸易代理国际市场进入与扩张策略考核试卷
- 集成服务在智能电网分布式能源管理的实现考核试卷
- 拍卖行拍卖业务智能化发展路径考核试卷
- 热扎带刚车间设计
- 麻醉科无痛技术临床应用与发展
- 寓言故事汇报展示
- 服装设计产品开发全流程
- Siphonaxanthin-生命科学试剂-MCE
- Anticonvulsant-agent-10-生命科学试剂-MCE
- GB/T 14536.12-2024电自动控制器第12部分:能量调节器的特殊要求
- 门诊部医疗纠纷预防与处理
- 六年级语文下册 期末复习非连续性文本阅读专项训练(一)(含答案)(部编版)
- 美学原理学习通超星期末考试答案章节答案2024年
- 《实践论》(原文)毛泽东
- 电力分包项目合同范本
- 贵州省遵义市道德与法治中考试卷及答案指导(2025年)
- 2023-2024学年内蒙古呼和浩特市回民区高二下学期期中考试生物试题(解析版)
- 历史人教部编版八年级(上册)第13课五四运动课件(23张)2024版新教材
- 文化在社会发展中的作用
- DB15-T 3651-2024 光伏项目防沙治沙技术规程
评论
0/150
提交评论