更多信息:
本篇算是学习笔记
视频
尚硅谷
配置文件的信息
Spring Boot文档
狂神老师的bilibli账号:如果想学相关的知识可以关注一下
编辑器:IntelliJ IDEA 2020.1
使用外部Servlet容器
嵌入式Servlet容器
优点:简单、便捷
缺点:不支持JSP、优化定制比较复杂、自己编写嵌入式Servlet容器的创建工厂
解决方法:如果想要支持JSP,我们可以使用外部Servlet容器
外置的Servlet容器:外面安装Tomcat—应用war包的方式打包;
创建项目
启动方式:打成war包的方式放在服务器,或是把服务器整合到IntelliJ IDEA
将服务器整合到IntelliJ IDEA
将嵌入式的Tomcat指定为provide
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
为了使用这个实现类的configure方法
package com.atguigu.springboot;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* SpringApplicationBuilder: Spring应用构建器调用sources方法
* 传入SpringBoot04WebJspApplication.class的主程序
*/
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
//传入主程序
return application.sources(SpringBoot04WebJspApplication.class);
}
}
注意:当我们直接启动项目的主程序是无法启动成功的
原理
jar包,我们直接启动项目的主程序是可以启动成功的启动ioc容器,创建嵌入式的Servlet容器;
war包:我们不能直接运行主方法,启动服务器,服务器帮我们启动SpringBoot应用(SpringBootServletInitializer支持),启动ioc容器;
文件内容就是ServletContainerInitializer的实现类的全类名
流程
启动Servlet容器,再启动SpringBoot应用
-
启动Tomcat
-
jrepository\org\springframework\spring-web\5.3.2\spring-web-5.3.2.jar!\META-INF\services\javax.servlet.ServletContainerInitializer
Spring的web模块里面有这个文件:org.springframework.web.SpringServletContainerInitializer
当项目启动时,我们要创建它的实例对象
SpringServletContainerInitializer
WebApplicationInitializer
ServletInitializer
SpringBootServletInitializer实例执行onStartup的时候会createRootApplicationContext;创建容器
createRootApplicationContext方法
protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
//创建SpringApplicationBuilder
SpringApplicationBuilder builder = this.createSpringApplicationBuilder();
//设置主类
builder.main(this.getClass());
ApplicationContext parent = this.getExistingRootWebApplicationContext(servletContext);
if (parent != null) {
this.logger.info("Root context already created (using as parent).");
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, (Object)null);
builder.initializers(new ApplicationContextInitializer[]{new ParentContextApplicationContextInitializer(parent)});
}
builder.initializers(new ApplicationContextInitializer[]{new ServletContextApplicationContextInitializer(servletContext)});
builder.contextFactory((webApplicationType) -> {
return new AnnotationConfigServletWebServerApplicationContext();
});
//调用configure方法,返回SpringApplicationBuilder
//子类会重写将我们的主程序类导入
builder = this.configure(builder);
builder.listeners(new ApplicationListener[]{new SpringBootServletInitializer.WebEnvironmentPropertySourceInitializer(servletContext)});
//使用builder创建Spring应用
SpringApplication application = builder.build();
if (application.getAllSources().isEmpty() && MergedAnnotations.from(this.getClass(), SearchStrategy.TYPE_HIERARCHY).isPresent(Configuration.class)) {
application.addPrimarySources(Collections.singleton(this.getClass()));
}
Assert.state(!application.getAllSources().isEmpty(), "No SpringApplication sources have been defined. Either override the configure method or add an @Configuration annotation");
if (this.registerErrorPageFilter) {
application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class));
}
application.setRegisterShutdownHook(false);
//启动spring应用
return this.run(application);
}
run方法