https://www.cnblogs.com/developerxiaofeng/p/9081689.html
jar包和war包启动区别:
正常springboot项目在创建的时候是会生成启动类的,这个类启动的是内置的tomcat容器,但是我们也是可以用外部的容器,这个时候我们发现有一个问题就是,我们配置的时候好像少了一个web.xml文件,这个是在spring+springmvc时代的配置文件,但是在springboot中是没有这个文件的,但是功能上来说我们不能丢弃这,所以才需要继承SpringBootServletInitializer这个类来替代web.xml的功能。(原文链接:https://blog.csdn.net/hy_coming/article/details/103307000、https://blog.csdn.net/wey1234567/article/details/95045388)
Spring Boot项目有两种部署方式,1、Spring Boot 内置Tomcat启动(jar包);2、Spring Boot外置Tomcat启动(war包)
Servlet 3.0+规定:
外部Tomcat流程以及原理
① 启动Tomcat
② 根据上述描述的Servlet3.0+规则,可以在Spring的web模块里面找到有个文件名为javax.servlet.ServletContainerInitializer的文件,而文件的内容为org.springframework.web.SpringServletContainerInitializer,用于加载SpringServletContainerInitializer类。
③看看SpringServletContainerInitializer定义。SpringServletContainerInitializer将@HandlesTypes(WebApplicationInitializer.class)标注的所有WebApplicationInitializer这个类型的类都传入到onStartup方法的Set参数中,并通过反射为这些WebApplicationInitializer类型的类创建实例;
④ 方法最后,每一个WebApplicationInitilizer实现调用自己onstartup方法
⑤ 而WebApplicationInitializer有个抽象实现类SpringBootServletInitializer(记住我们继承了该抽象类),则会调用每一个WebApplicationInitializer实例(包括SpringBootServletInitializer)的onStartup方法:
SpringBootServletInitializer实例执行onStartup方法的时候会通过createRootApplicationContext方法来执行run方法,接下来的过程就同以jar包形式启动的应用的run过程一样了,在内部会创建IOC容器并返回,只是以war包形式的应用在创建IOC容器过程中不再创建Servlet容器了。
----------------------------------------
在web容器(例如Tomcat)启动时为提供给第三方组件做一些初始化工作的机会,例如注册servlet或者filters等,servlet规范中通过ServletContainerInitializer实现此功能。
每个框架要使用ServletContainerInitializer,就必须在对应的jar包的META-INF/services目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。
一般伴随着ServletContainerInitializer一起使用的还有HandlesTypes注解,通过HandlesTypes可以将感兴趣的一些类注入到ServletContainerInitializerde的onStartup()方法作为参数传入。
Tomcat容器的ServletContainerInitializer机制的实现,主要交由Context容器和ContextConfig监听器共同实现:首先通过ContextConfig监听器遍历每个jar包或web根目录的META-INF/services/javax.servlet.ServletContainerInitializer文件,根据读到的类路径通过反射完成这些ServletContainerInitializer的实例化;然后再分别将实例化好的ServletContainerInitializer设置进Context容器中;最后Context容器启动时分别调用所有ServletContainerInitializer对象的onStartup方法,并将感兴趣的类作为参数传入。
/org/springframework/spring-web/5.1.10.RELEASE/spring-web-5.1.10.RELEASE.jar!/META-INF/services/javax.servlet.ServletContainerInitializer中指定了org.springframework.web.SpringServletContainerInitializer这个类,即在Tomcat的Context容器启动的时候会调用SpringServletContainerInitializer这个类的onStartup()方法,并将WebApplicationInitializer这个类的实现类作为参数传入。
在onStartup(@Nullable Set
WebApplicationInitializer.class的几个实现类:(这几个好像都是抽象类啊,怎么理解呢?是这样的,比如SpringBoot项目选择外置Tomcat启动,则需要继承SpringBootServletInitializer,tomcat根据上述Servlet3.0+规则来启动这个应用)
————————————————
版权声明:本文为CSDN博主「yangliuhbhd」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yangliuhbhd/article/details/80803464
在 Spring MVC 中存在两种应用上下文:DispatcherServlet 创建的上下文和拦截器 ContextLoaderListener 创建的上下文:
https://docs.spring.io/spring-framework/docs/5.0.2.RELEASE/spring-framework-reference/web.html#mvc-servlet-context-hierarchy
在 AbstractAnnotationConfigDispatcherServletInitializer 中 DispatcherServlet 和 ContextLoaderListener 都会被创建,而基类中的方法就可用来创建不同的应用上下文:
getServletConfigClasses():定义 DispatcherServlet 应用上下文中的 beans
getRootConfigClasses():定义拦截器 ContextLoaderListener 应用上下文中的 beans
Note:为了使用 AbstractAnnotationConfigDispatcherServletInitializer 必须保证 web 服务器支持 Servlet 3.0 标准(如 tomcat 7 或更高版本) 。
————————————————
版权声明:本文为CSDN博主「yangliuhbhd」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yangliuhbhd/article/details/80803464
Spring只是一个框架,用来简化开发。
如果是web应用,则涉及到servlet、servlet容器等等,可以使用Spring MVC框架快速开发,需要将web应用部署到Tomcat中进而提供服务(当然Tomcat也是跑在JVM上的)。
如果不是是web应用,肯定不涉及Tomcat和Spring MVC等web框架,但是可以有Spring框架来处理bean之间的依赖关系等等,应用应该是直接跑在JVM上的。
----------------------------------------
--------------------------------