本博客是原创:主要目的是为了自己总结学习的,不喜勿喷,当然里面有错误欢迎指出。
寒暄部分:
BootStrap类是tomcat的入口 自然有一个main方法不要问我为什么 我也不知道是咋回事,百度搜到的或者说是慢慢磨出来的。现在联想到的问题就是我们平时用的tomcat是tomcat产品只需要执行脚本然后就可运行这个是tomcat源码编译过后的样子,然后在上面发布项目,那tomcat本身是怎么一回事呢,源码是怎么设计的呢,它又是怎么工作的,对于小白的我陷入了沉思。
//tomcat源码BootStrap.main()
public static void main(String args[]) {
if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.init();
} catch (Throwable t) {
handleThrowable(t);
t.printStackTrace();
return;
}
daemon = bootstrap;
} else {
// When running as a service the call to stop will be on a new
// thread so make sure the correct class loader is used to prevent
// a range of class not found exceptions.
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
}
try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("startd")) {
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[args.length - 1] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else if (command.equals("configtest")) {
daemon.load(args);
if (null==daemon.getServer()) {
System.exit(1);
}
System.exit(0);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
// Unwrap the Exception for clearer error reporting
if (t instanceof InvocationTargetException &&
t.getCause() != null) {
t = t.getCause();
}
handleThrowable(t);
t.printStackTrace();
System.exit(1);
}
}
注意代码不是很多但也不少要是挨个点进去那理一上午估计也是一头雾水,看源码要走主流程,那些if else 一带而过基本上都是业务代码,try catch (今天发现这个家伙有个新的写法了)一般就是核心的部分。抓住这一点会节约很多时间。
init()
load()
start()
先看load()
其实最一开始看这里我是懵逼为什么反射忘记了,不仅忘记了而且被蒙住了眼,一直纠结这里怎么就调了catalina的load方法呢,也是慢慢的磨慢慢的磨,哦不是反射的问题,妈蛋catalinaDaemon是个全局变量 并且还是个引用类型的在load()方法之前还有一个init()方法说不定是这个方法改变了load()里面的catalinaDaemon的值,果然是这样如下图:。同时弄个了小窗口复习了一下反射的小知识,
方式一:
Object per = Class.forName("test.test.Person").newInstance();//哪个类 哪个方法 方法可能多个 所以加了个参数
Method method = Class.forName("test.test.Person").getMethod("getSomething", String.class);
String ret = (String)method.invoke(per, "hah");// param1 实例 param2 参数
方式二:
per.getClass().getMethod("getSomething", String.class).invoke(per, "heheheheh").toString();
System.out.println("hahadfadfafaf" + per.getClass().getMethod("getSomething", String.class).invoke(per,"heheheheh").toString());
其实看到上图可以发现 catalinaDaemon是个Object类型的,后面怎么知道用的是哪一个类那个一个方法,其实方式二已经说明了这一点了,这个调什么类在上图创建实例的部分完成了,其实这都是java基础的问题,但是往往基础的也都是最蛋疼的问题。
小结:
最后总结一下按照下面这个图基本上可以把大致的初始化流程走一遍,这样对整个的流程有个大概的了解,在了解的基础上你就可以去熟悉里面的设计模式,就可以深究里面的各种实现,最一开始如果每个方法都点进去那其实是不好的,各种api 其实并不是很熟悉的。
其实这就设计到了看源码的三条线 一种是:代码运行的线路 (一般就是这种思路)
第二种就是产品设计的线tomcat 肯定是java产品 设计到 bs cs java网络变程 ,慢慢的发现各种东西建立起模型起来了。这个模型就是常见的java网络编程了,肯定有服务端,有客户端 自然就会想到服务端监听端口,客户端发送请求然后就是服务监听的的几个最底层的api带着这种思路一步步的去验证也事很好。
第三种方式就是:用户体验的方式,我怎么去操作的 我这样操作会是什么效果,为什么会是这种效果,相当于站在白盒测试的角度和第一种第二种开发正好反过来。
参考的资料:
最新的try catch的写法
https://blog.csdn.net/llkoio/article/details/78939148
https://www.cnblogs.com/jiaan-geng/p/4866009.html(TOMCAT源码分析——SERVER.XML文件的加载与解析)
java创建对象的几种方式通俗易懂
https://www.cnblogs.com/baizhanshi/p/5896092.html
System.getProperties()的用法 还是就是文件
https://www.cnblogs.com/chengxuzhijia/p/9635251.html
File的用法可以查看jdk帮助文档
https://zhidao.baidu.com/question/311796975.html
https://www.yiibai.com/java/io/file_isabsolute.html
绘图工具;