竹笋

首页 » 问答 » 灌水 » 是如何加载Spring和Sprin
TUhjnbcbe - 2023/1/25 17:18:00

概述

大家是否清楚,Tomcat是如何加载Spring和SpringMVC,今天我们就弄清下这个过程(记录最关键的东西)

其中会涉及到大大小小的知识,包括加载时候的设计模式,Servlet知识等,看了你肯定有所收获~

Tomcat

tomcat是一种Java写的Web应用服务器,也被称为Web容器,专门运行Web程序

tomcat启动

tomcat启动了之后会在操作系统中生成一个Jvm(Java虚拟机)的进程,从配置监听端口(默认)监听发来的HTTP/1.1协议的消息

默认配置文件这样

当Tomcat启动完成后,它就会加载其安装目录下webapps里的项目(放war包会自动解压成项目)

小提问:webapps里多个项目,是运行在同一个JVM上吗

是运行在同一个JVM上的(Tomcat启动时创建的那个),多个项目就是多个线程,之所以项目间数据不共享,是因为类加载器不一样的缘故

加载Web程序(Spring+SpringMVC框架)

tomcat启动完毕后,最关键的是生成了ServletContext(Tomcat的上下文),然后会根据webapps项目里的web.xml进行加载项目

下面是一个SpringMVC+Spring项目的部分web.xml

初始化Spring

tomcat首先会加载进ContextLoaderListener,然后将applicationContext.xml里写的参数注入进去,来完成一系列的Spring初始化(如各种bean,数据库资源等等)

这里就是经常听到的Ioc容器的初始化了,我们搜索这个类发现以下代码

这里最重要的是通过ServletContext,初始化属于Spring的上下文WebApplicationContext,并将其存放在ServletContext

WebApplicationContext多重要老铁们都懂得,我们经常用webApplicationContext.getBean()来获取被Spring管理的类,所以这也是IOC容器的核心

Spring采用这种监听器来启动自身的方法,也是一种设计模式,叫观察者模式:

整个过程是这样的,Tomcat加载webapps项目时,先通过反射加载在web.xml标明的类(通通放入一个数组)

到某个时刻,我tomcat(事件源,事件的起源)会发起一个叫ServletContextEvent的事件(里面带着各种参数)

凡是实现了ServletContextListener接口的类,我都会调用里面的contextInitialized方法,并把这个事件参数传进去

咳咳,现在我看看这个数组里有没符合条件的(遍历),发现真有实现这个接口的(类instanceof接口),就调用contextInitialized方法

于是Spring就被动态加载进来了~~

题外话:

加载一个类,可以用用完整的类名,通过java反射加载,Class.forName(类名)

也能直接new一个类来加载

初始化SpringMVC

看配置文件,标签是servlet,我们得首先了解下servlet是什么东东

Servlet简介

Servlet是一个接口,为web通信而生

tomcat有一套定义好的程序(其实不只是tomcat,能跑java写的web应用服务器如Jetty等,都有这固定程序)

1.当tomcat加载进来一个类时,如果它实现了Servlet接口,那么会记载到一个Map里,然后执行一次init()方法进行Servlet初始化

2.当tomcat收到浏览器的请求后,就会在Map里找对应路径的Servlet处理,路径就是写在url-pattern标签里的参数,调用service()这个方法

3.当Servlet要被销毁了,就调用一次destroy()方法

各位看到这是不是感觉相识,跟Spring加载差不多嘛,都是实现了一个接口后就被命运(tomcat)安排~~

当然,我们自己实现Servlet接口太麻烦了,于是有HttpServlet(一个抽象类)帮我们实现了大部分方法(包含

1
查看完整版本: 是如何加载Spring和Sprin