jetty的start.jar

本文主要分析下jetty的start.jar中的jar包加载顺序和一些简单逻辑,由于没有下到start.jar包的源码,用反编译的方式搞的,代码可能有些地方不一定准确。

 

1.main方法

main方法非常简单,基本就这一句:

[java]  view plain copy
  1. Main main = new Main().parseCommandLine(args);  

2.   public void parseCommandLine(String[] args)

该函数主要完成解析命令行参数的功能:

 

1.首先遍历所有的传入参数,并把他们加入到arguments这个ArrayList<String>中。如果指定了--ini=,则吧ini指定文件中的所有参数也加入到
arguments,如果是--config=,则设置 this._startConfig,最后如果传入参数中没有 --ini=或者--ini,就是用默认的ini,并把参数加入到arguments。

[java]  view plain copy
  1. List arguments = new ArrayList();  
  2. for (String arg1 : args)  
  3. {  
  4.   if ((arg1.startsWith("--ini=")) || (arg1.equals("--ini")))  
  5.   {  
  6.       arguments.addAll(loadStartIni(arg1.substring(6)));  
  7.   }  
  8.   else if (arg1.startsWith("--config="))  
  9.   {  
  10.     this._startConfig = arg1.substring(9);  
  11.   }  
  12.   else  
  13.   {  
  14.     arguments.add(arg1);  
  15.   }  
  16. }  
  17. if (!(ini)){ arguments.addAll(0, loadStartIni(null));}  


 

2.遍历arguments并一一解析处理,主要处理的参数有这些:

  • 一些常见参数,类似--help,--stop等的处理
  • --daemon的处理,控制启动日志打印
  • -D...的参数,设置到System.properties中
  • -  的参数,设置为jvm参数
  • 类似a=b的参数,设置到this._config中

3.调用start(xmls);

 

3.   public void start(List<String> xmls)

主要完成这几件事情:


1.startMonitor();
2.List configuredXmls = loadConfig(xmls);
3.configuredXmls = resolveXmlConfigs(configuredXmls);//主要是确定所有xml的位置,包括文件夹转化为一个个的xml路径
4.mainClass = System.getProperty("main.class");invokeMain(cl, classname, configuredXmls);

 

其中loadConfig(xmls);和invokeMain(cl, classname, configuredXmls);是主要逻辑,loadConfig(xmls);主要是处理定义好的classpath和xml文件的处理顺序等,逻辑委托给org.eclipse.jetty.start.Config类来实现,部分代码如下:

[java]  view plain copy
  1. private InputStream getConfigStream() throws FileNotFoundException  
  2.   {  
  3.     String config = this._startConfig;  
  4.     if ((config == null) || (config.length() == 0))  
  5.     {  
  6.       config = System.getProperty("START""org/eclipse/jetty/start/start.config");  
  7.     }  
  8.   
  9.     Config.debug("config=" + config);  
  10.   
  11.     InputStream cfgstream = super.getClass().getClassLoader().getResourceAsStream(config);  
  12.   
  13.     if (cfgstream == null)  
  14.     {  
  15.       cfgstream = new FileInputStream(config);  
  16.     }  
  17.   
  18.     return cfgstream;  
  19.   }  


可以看到,如果我们自定义了start文件,就使用自定义的,否则使用start.jar中自带的,这个文件的主要功能是什么的,文档说:This file controls what file are to be put on classpath or command line.截取一小段示例一下:

[plain]  view plain copy
  1. # add a property defined classpath  
  2. ${path}.path                                     property path  
  3.   
  4. # add a property defined library directory  
  5. ${lib}/**                                        exists ${lib}  
  6.   
  7. # Try different settings of jetty.home until the start.jar is found.  
  8. jetty.home=.                                     ! exists $(jetty.home)/start.jar   
  9. jetty.home=..                                    ! exists $(jetty.home)/start.jar   
  10. jetty.home=jetty-distribution/src/main/resources     ! exists $(jetty.home)/start.jar   
  11. jetty.home=../jetty-distribution/src/main/resources  ! exists $(jetty.home)/start.jar   
  12. jetty.home=.                                     ! exists $(jetty.home)/start.jar  
  13. jetty.home/=$(jetty.home)                        exists $(jetty.home)/start.jar  
  14.   
  15. # The main class to run  
  16. org.eclipse.jetty.xml.XmlConfiguration.class  
  17. ${start.class}.class                             property start.class  
  18.   
  19. # The default configuration files  
  20. $(jetty.home)/etc/jetty.xml                      nargs == 0  
  21. ./jetty-server/src/main/config/etc/jetty.xml     nargs == 0 AND ! exists $(jetty.home)/etc/jetty.xml  
  22.   
  23. # Default OPTIONS if not specified on the command line  
  24. OPTIONS~=default,*                               ! property OPTIONS  
  25.   
  26. # Add a resources directory if it is there  
  27. [All,resources,default]  
  28. $(jetty.home)/resources/  
  29.              
  30. # Add jetty modules  
  31. [*]  
  32. $(jetty.home)/lib/jetty-util-$(version).jar                                             ! available org.eclipse.jetty.util.StringUtil  
  33. $(jetty.home)/lib/jetty-io-$(version).jar     


可以看到它主要定义了一些classpath的路径等信息,解析过程比较复杂,在此不详述,有兴趣可以自己了解。这里举一个例子,比如我们在启动参数中定义了-lib=D:/mylib/

这个classpath就会被加入到java.class.path中,甚至比jetty的server等类还靠前,这样我们就可以覆盖或者替换jetty的类,达到一些特殊的目的。

 

完成一系列的预处理之后,就该真正的启动server了

[java]  view plain copy
  1. String mainClass = System.getProperty("jetty.server");  
  2.    if (mainClass != null)  
  3.    {  
  4.      classname = mainClass;  
  5.    }  
  6.   
  7.    mainClass = System.getProperty("main.class");  
  8.    if (mainClass != null)  
  9.    {  
  10.      classname = mainClass;  
  11.    }  
  12.   
  13.    Config.debug("main.class=" + classname);  
  14.   
  15.    invokeMain(cl, classname, configuredXmls);  

 

invokeMain(cl, classname, configuredXmls);这个方法就是关键的启动方法了,这里默认的main.class=org.eclipse.jetty.xml.XmlConfiguration,其主要逻辑如是:

先初始化properties文件或者解析xml文件,在解析的过程中可能会通过反射机制初始化一些类。包括server类等;然后对于生成的类,如果是继承了lifecycle的,全部启动,从而完成容器的启动,主要代码如下:

[java]  view plain copy
  1. // For all arguments, load properties or parse XMLs   
  2. XmlConfiguration last = null;  
  3. Object[] obj = new Object[args.length];  
  4. for ( int i = 0; i < args.length; i++ )  
  5. {  
  6.     if ( args[i].toLowerCase().endsWith( ".properties" ) )  
  7.     {  
  8.         properties.load( Resource.newResource( args[i] ).getInputStream() );  
  9.     }  
  10.     else  
  11.     {  
  12.         XmlConfiguration configuration =  
  13.             new XmlConfiguration( Resource.newResource( args[i] ).getURL() );  
  14.         if ( last != null )  
  15.             configuration.getIdMap().putAll( last.getIdMap() );  
  16.         if ( properties.size() > 0 )  
  17.             configuration.setProperties( properties );  
  18.         obj[i] = configuration.configure();  
  19.         last = configuration;  
  20.     }  
  21. }  
  22.   
  23. // For all objects created by XmlConfigurations, start them if they are lifecycles.  
  24. for ( int i = 0; i < args.length; i++ )  
  25. {  
  26.     if ( obj[i] instanceof LifeCycle )  
  27.     {  
  28.         LifeCycle lc = (LifeCycle) obj[i];  
  29.         if ( !lc.isRunning() )  
  30.             lc.start();  
  31.     }  
  32. }  

 

通过debug级别的log可以看到,最先解析的是parsing: sid=file:/D:/learn/jetty7/etc/jetty.xml,其实现的逻辑和以下这段代码类似:

[java]  view plain copy
  1. Server server = new Server(8080);  
  2. WebAppContext webapp = new WebAppContext();  
  3. webapp.setContextPath("/");  
  4. server.setHandler(webapp);  
  5. server.start();  

然后还有自定义的一些,比如jetty-deploy.xml等,整个初始化的过程就完成了。其实这里jetty也实现了一个简单的依赖注入的功能。


 

4. 总结:

start.jar 主要干了这几件事情:
1.解析命令行参数。
2.定位资源,根据参数和配置文件决定classpath和xmls的位置等。
3.反射调用启动server,并根据xml配置实现相关的依赖注入的功能

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值