上篇文章:
Tomcat与Servlethttps://blog.csdn.net/sniper_fandc/article/details/147278469?fromshare=blogdetail&sharetype=blogdetail&sharerId=147278469&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link 上篇文章介绍了Tomcat服务器的启动和基本程序的部署,但是在开发环境下,如果修改代码,就需要重复打包部署的步骤,有点繁琐,因此在开发阶段,我们有更简洁的流程(这个流程还比不上使用SpringBoot框架,属于折中方案):
目录
1 简化流程
1.1 安装Smart Tomcat
1.2 配置Smart Tomcat
1.3 Tomcat底层原理
1 简化流程
1.1 安装Smart Tomcat
上述操作如果开发人员每修改一次代码,就需要重新打包部署一次,非常麻烦,这里可以使用插件Smart Tomcat来简化打包部署的流程。
在Setting界面找到插件安装,搜索Smart Tomcat插件安装即可。
注意:Smart Tomcat不等于Tomcat,即它只是一个插件,不是HTTP服务器。Smart Tomcat在背后所做的工作就是让我们不用再打开Tomcat目录使用命令启动,可以在IDEA中点击自动启动Tomcat,并且自动部署运行我们的web程序。
1.2 配置Smart Tomcat
打开Configurations(在右上角运行左侧),点击加号添加Smart Tomcat。
Name表示为当前服务起名。
Tomcat server表示Tomcat的安装路径,首次使用时需要设置。
Deployment directory对应项目中的webapp的路径。
Use classpath of module和Context path表示浏览器输入的一级URL(在IP和端口后申请访问的资源)。
Server port表示Tomcat服务器的端口。
Admin port表示Tomcat的管理端口(比如控制重启等)。
配置完成后,点击运行,即可自动编译、打包、部署、运行。
见到如上信息,就说明成功启动了,也可以访问我们的程序了。如果修改了代码,重新运行程序即可。
注意:Smart Tomcat并没有把war包部署到Tomcat的webapps目录下,而是直接通过让Tomcat读取项目中target目录下编译好的文件,运行.class文件来运行项目。
1.3 Tomcat底层原理
这里给出伪代码:
class Tomcat {// 用来存储所有的 Servlet 对象private List<Servlet> instanceList = new ArrayList<>();public void start() {// 根据约定,读取 WEB-INF/web.xml 配置文件;// 并解析被 @WebServlet 注解修饰的类// 假定这个数组里就包含了我们解析到的所有被 @WebServlet 注解修饰的类.Class<Servlet>[] allServletClasses = ...;// 实例化出所有的 Servlet 对象出来;for (Class<Servlet> cls : allServletClasses) {// 利用 java 中的反射特性// 实际上涉及一个类的加载问题,因为类字节码文件是按照约定// 方式(全部在WEB-INF/classes文件夹下)存放的,所以tomcat内部// 实现了一个自定义的类加载器(ClassLoader)用来负责这部分工作。Servlet ins = cls.newInstance();instanceList.add(ins);}// 调用每个 Servlet 对象的init()方法,这个方法在对象的生命中只会被调用这一次;for (Servlet ins : instanceList) {ins.init();}// 启动一个 HTTP 服务器// 并用线程池的方式分别处理每一个RequestServerSocket serverSocket = new ServerSocket(8080);// 实际上 tomcat 不是用的固定线程池,这里只是为了说明情况ExecuteService pool = Executors.newFixedThreadPool(100);while (true) {Socket socket = ServerSocket.accept();// 每个请求都是用一个线程独立支持,这里体现了Servlet是运行在多线程环境下的pool.execute(new Runnable() {doHttpRequest(socket);});}// 调用每个 Servlet 对象的 destroy() 方法,这个方法在对象的生命中只会被调用这一次;for (Servlet ins : instanceList) {ins.destroy();}}// 内置main方法public static void main(String[] args) {new Tomcat().start();}}
这里的doHttpRequest(Socket socket)方法根据请求构造出HttpServletRequest对象,根据URL判断寻找的资源是静态资源还是动态资源,如果是静态资源直接返回对应的资源即可;如果是动态资源就找到Servlet对象,调用其中的service()方法,service()方法就会判断这次请求方法是GET还是POST或者其他,指定对应的doXXX方法。
注意:doXXX方法是多态的体现,我们开发人员写的类继承HttpServlet类(有doXXX系列的方法,需要我们的自定义类重写),而HttpServlet类继承Servlet类,而在动态资源的访问中引用对象的类型是Servlet,因此相当于我们通过父类引用Servlet来调用子类的doXXX方法(父类引用指向子类对象)。
下篇文章:
Servlethttps://blog.csdn.net/sniper_fandc/article/details/147279226?fromshare=blogdetail&sharetype=blogdetail&sharerId=147279226&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link