SpringBoot 是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件默认集成的是SpringMVC框架。
核心原理:
- 基于SpringMVC无配置文件(纯Java)完全注解化+内置tomcat-embed-core实现SpringBoot框架,Main函数启动。
- SpringBoot核心快速整合第三方框架原理:Maven继承依赖关系
- SpringBoot内嵌入tomcat-embed-core
- SpringBoot采用SpringMVC注解版本实现无配置效果
下面来讲解SpringBoot的实现原理,主要重“内置Tomcat容器”和“SpringMVC注解启动”这两块来分析。
注意:本文说的不是SpringBoot流程还是SpringBoot核心原理。
1.内置Tomcat容器
Java提供内置Tomcat容器框架,使用Java语言操作Tomcat容器。
案例: 使用Java语言创建一个Tomcat容器。
1.1添加maven依赖:
<dependencies> <!--Java语言操作tomcat --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>8.5.16</version> </dependency> <!-- spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.4.RELEASE</version> <scope>compile</scope> </dependency> <!-- spring-mvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.4.RELEASE</version> <scope>compile</scope> </dependency> <!-- tomcat对jsp支持 --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper</artifactId> <version>8.5.16</version> </dependency> </dependencies>
1.2 创建Servet类:
public class IndexServet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().print("springboot2.0"); } }
1.3 创建Tomcat运行:
public class Test001 { // 端口号 private static int PORT = 8080; // 项目名称 private static String CONTEXTPATH = "/ylw"; public static void main(String[] args) throws LifecycleException, InterruptedException { // 创建Tomcat服务器 Tomcat tomcatServer = new Tomcat(); // 设置Tomcat端口号 tomcatServer.setPort(PORT); tomcatServer.getHost().setAutoDeploy(false); // 创建Context上下文 StandardContext standardContext = new StandardContext(); standardContext.setPath(CONTEXTPATH); standardContext.addLifecycleListener(new FixContextListener()); // tomcat容器添加standardContext tomcatServer.getHost().addChild(standardContext); // 创建servlet tomcatServer.addServlet(CONTEXTPATH, "IndexServet", new IndexServlet()); // 添加servleturl映射 standardContext.addServletMappingDecoded("/index", "IndexServet"); tomcatServer.start(); System.out.println("tomcat启动..."); tomcatServer.getServer().await(); } }
1.4 运行结果:
浏览器访问http://localhost:8080/ylw/index:
2. SpringMVC注解启动方式
DispatcherServlet是Spring MVC的核心,每当应用接受一个HTTP请求,由DispatcherServlet负责将请求分发给应用的其他组件。
在旧版本中,DispatcherServlet之类的servlet一般在web.xml文件中配置,该文件一般会打包进最后的war包种;但是Spring 3引入了注解,下面来讲解如何基于注解配置Spring MVC?
2.1 添加Maven依赖:
<dependencies> <!--Java语言操作tomcat --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>8.5.16</version> </dependency> <!-- spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.4.RELEASE</version> <scope>compile</scope> </dependency> <!-- spring-mvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.4.RELEASE</version> <scope>compile</scope> </dependency> <!-- tomcat对jsp支持 --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper</artifactId> <version>8.5.16</version> </dependency> </dependencies>
2.2 加载SpringMVCDispatcherServlet
AbstractAnnotationConfigDispatcherServletInitializer这个类负责配置DispatcherServlet、初始化Spring MVC容器和Spring容器。getRootConfigClasses()方法用于获取Spring应用容器的配置文件,这里我们给定预先定义的RootConfig.class;getServletConfigClasses负责获取Spring MVC应用容器,这里传入预先定义好的WebConfig.class;getServletMappings()方法负责指定需要由DispatcherServlet映射的路径,这里给定的是"/",意思是由DispatcherServlet处理所有向该应用发起的请求。
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { // 加载根容器 protected Class<?>[] getRootConfigClasses() { // TODO Auto-generated method stub return new Class[] { RootConfig.class }; } // 加载SpringMVC容器 protected Class<?>[] getServletConfigClasses() { return new Class[] { WebConfig.class }; } // SpringMVCDispatcherServlet 拦截的请求 / protected String[] getServletMappings() { return new String[] { "/" }; } }
2.3 加载SpringMVC容器:
正如可以通过多种方式配置DispatcherServlet一样,也可以通过多种方式启动Spring MVC特性。原来我们一般在xml文件中使用<mvc:annotatio-driven>
元素启动注解驱动的Spring MVC特性。
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration @EnableWebMvc @ComponentScan("com.ylw.controller") public class WebConfig extends WebMvcConfigurerAdapter { }
2.4 RootConfig容器
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = "com.ylw") public class RootConfig { }
2.5 indexController
package com.ylw.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @RequestMapping(value = "/index", produces = "text/html;charset=UTF-8") public String index() { return "SpringBoot index ......"; } }
2.6 测试类:
import java.io.File; import javax.servlet.ServletException; import org.apache.catalina.LifecycleException; import org.apache.catalina.WebResourceRoot; import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.webresources.DirResourceSet; import org.apache.catalina.webresources.StandardRoot; public class AppTomcat { public static void main(String[] args) throws ServletException, LifecycleException { start(); } public static void start() throws ServletException, LifecycleException { // 创建Tomcat容器 Tomcat tomcatServer = new Tomcat(); // 端口号设置 tomcatServer.setPort(9090); // 读取项目路径 StandardContext ctx = (StandardContext) tomcatServer.addWebapp("/", new File("src/main").getAbsolutePath()); // 禁止重新载入 ctx.setReloadable(false); // class文件读取地址 File additionWebInfClasses = new File("target/classes"); // 创建WebRoot WebResourceRoot resources = new StandardRoot(ctx); // tomcat内部读取Class执行 resources.addPreResources( new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/")); tomcatServer.start(); // 异步等待请求执行 tomcatServer.getServer().await(); } }
2.7运行
浏览器输入:http://localhost:9090/index
2.8 其它(对JSP页面的支持)
1.修改WebConfig创建视图解析器
// 创建SpringMVC视图解析器 @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); //可以在JSP页面中通过${}访问beans viewResolver.setExposeContextBeansAsAttributes(true); return viewResolver; }
2.新增控制器层
@Controller public class IndexController { @RequestMapping("/pageIndex") public String pageIndex() { return "pageIndex"; } }
总结