SpringBoot 是一个快速开整合第三方框架的框架,全部采用注解形式替代原来的XML形式,内置Tomcat容器。
换句话来说,SpringBoot并不是一个严格的开发框架,而是快速整合框架的框架。例如SpringBoot整合Spring、SpringMVC、MyBatis后,此项目的使用方式和使用maven的SSM框架几乎完全一致,最大的改变是,没了那一堆Spring的配置,以及web.xml配置。
如果我们现在来手写一套SpringBoot,我们需要做什么工作?
这个比较简单,maven依赖就能实现了。所以创建一个maven项目就gameover了。
之前的文章已经着重讲述了构建一个tomcat服务,这里不在重复。
之前的文章中,我们讲了SpringBoot怎么启动的,在这篇文章中,我们介绍了@SpringBootApplication的核心组建之一有@SpringBootConfiguration。
这个注解干嘛用的, 如果没有看过这篇文章,或者忘记了,我们先回顾下
SpringBoot中的@SpringBootConfiguration和Spring3.0版本中发布的Configuration作用完全一致。
@Configuration作用:配置Spring容器,使用 Java代码形式来配置Spring上下文中的bean。当我们把@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的,作用为:配置spring容器(应用上下文)
例如如下配置中的bean可以用java类来配置。
现在,有了上述三个知识点的支撑,离我们手写SpringBoot框架就不远了。
<dependency>
<groupId>org.apache.tomcat.embedgroupId>
<artifactId>tomcat-embed-coreartifactId>
<version>8.5.16version>
dependency>
<dependency>
<groupId>org.apache.tomcatgroupId>
<artifactId>tomcat-jasperartifactId>
<version>8.5.16version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.0.4.RELEASEversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.0.4.RELEASEversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.1version>
dependency>
这里跟我们之前的文章:教你用Java的方式创建一个自己的Tomcat容器,功能几乎一致,唯一区别,就是这里我们不是配置servlet,而是将提供的web应用资源添加到此Web应用程序,这种方式比较灵活,毕竟应该是资源文件有什么,我们加什么,总不能一个一个资源用手动的方式去加载吧。
/**
* @Description:内置tomcat
* @author hutao
* @mail:[email protected]
* @date 2020年8月10日
*/
public class AppTomcat {
private static int PORT = 8081;
private static String WEB_APP_PATH = "src/main";
private static String WEB_INF_CLASSES_PATH = "target/classes";
private static String RESOURCES_PATH = "/WEB-INF/classes";
public static void main(String[] args) throws ServletException, LifecycleException {
start();
}
public static void start() throws ServletException, LifecycleException {
System.out.println("开始启动tomcat");
//创建tomcat服务
Tomcat tomcat = new Tomcat();
//指定端口
tomcat.setPort(PORT);
//添加webapp
Context webapp = tomcat.addWebapp("", new File(WEB_APP_PATH).getAbsolutePath());
//webapp禁止重载入
webapp.setReloadable(false);
//加载静态资源文件
File additionWebInfClasses = new File(WEB_INF_CLASSES_PATH);
//创建web应用资源
WebResourceRoot resources = new StandardRoot(webapp);
//tomcat将提供的web应用资源添加到此Web应用程序。
resources.addPreResources(new DirResourceSet(resources,RESOURCES_PATH, additionWebInfClasses.getAbsolutePath(), "/"));
//启动tomcat
tomcat.start();
System.out.println("启动tomcat完毕");
//开启异步接收http请求接入
tomcat.getServer().await();
}
}
@Configuration注解声明它是配置类,@ComponentScan指定扫包的范围。
/**
* @Description:Spring上下文注解配置
* @author hutao
* @mail:[email protected]
* @date 2020年8月11日
*/
@Configuration
@ComponentScan("com.hutao.springboot.write")
public class SpringApplicationConfig {
}
/**
* @Description:SpringMVC注解配置,视图解析器
* @author hutao
* @mail:[email protected]
* @date 2020年8月11日
*/
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.hutao.springboot.write.controller" })
public class SpringMvcConfig extends WebMvcConfigurationSupport {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/page/");
viewResolver.setSuffix(".jsp");
viewResolver.setExposeContextBeansAsAttributes(true);
return viewResolver;
}
}
通过实现org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer这个接口,来完成托管和注册
/**
* @Description:注册DispatcherServlet,以及Spring托管
* @author hutao
* @mail:[email protected]
* @date 2020年8月10日
*/
public class AnnotationConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* @Description:Spring上下文配置:从跟目录去获取上下文应用
* @author hutao
* @mail:[email protected]
* @date 2020年8月10日
*/
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SpringApplicationConfig.class };
}
/**
* @Description:SpringMVC配置,本质就是Servlet应用程序上下文的配置
* @author hutao
* @mail:[email protected]
* @date 2020年8月10日
*/
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringMvcConfig.class };
}
/**
* @Description:Servlet映射
* @author hutao
* @mail:[email protected]
* @date 2020年8月10日
*/
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
/**
* @Description:格式化返回JSON
* @author hutao
* @mail:[email protected]
* @date 2020年8月12日
*/
public class ResultData implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int resultCode;
private String resultInfo;
public Object data;
//省略get set
}
@Configuration
public class ResultConfig {
@Bean
public ResultData getResultData() {
return new ResultData();
}
}
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
private HelloService helloService;
@Autowired
private ResultData result;
@RequestMapping("/hello/{userName}")
public ResultData hello(@PathVariable String userName) {
result.setResultCode(200);
result.setResultInfo("SUCC");
result.setData(helloService.hello(userName));
return result;
}
}
public interface HelloService {
String hello(String userName);
}
@Service
public class HelloServiceImpl implements HelloService{
public String hello(String userName) {
return userName+"手写SpringBoot集成SpringMVC和Spring";
}
}
启动tomcat以后,我们看到我们的controller被扫描并且注册了
创建返回页面的controller
@Controller
@RequestMapping("/page")
public class PageController {
@RequestMapping("/pageIndex")
public String pageIndex() {
return "pageIndex";
}
}
<%@ page language="java" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>主页面</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap-table/1.17.1/bootstrap-table.min.js"></script>
</head>
<body>
<table class="table">
<thead>
<tr>
<th style="width:10%">序号</th>
<th style="width:90%">内容</th>
</tr>
</thead>
<tbody>
<tr class="active">
<td>1</td>
<td><a href="https://blog.csdn.net/m0_37892044/article/details/106643842">深入SpringIOC原理解析,带你实现一个SpringIOC框架</a></td>
</tr>
<tr class="success">
<td>2</td>
<td><a href="https://blog.csdn.net/m0_37892044/article/details/106976372">深入SpringMVC原理解析,带你实现一个SpringMVC框架</a></td>
</tr>
<tr class="warning">
<td>3</td>
<td><a href="https://blog.csdn.net/m0_37892044/article/details/107239656">深入数据库连接池原理解析,带你实现一个连接池框架</a></td>
</tr>
<tr class="danger">
<td>4</td>
<td><a href="https://blog.csdn.net/m0_37892044/article/details/107314371">深入MyBatis原理解析,带你实现一个MyBatis框架</a></td>
</tr>
<tr class="success">
<td>5</td>
<td><a href="https://blog.csdn.net/m0_37892044/article/details/103915284">使用SpringToolSuite快速构建一个SpringBoot项目</a></td>
</tr>
<tr class="active">
<td>6</td>
<td><a href="https://blog.csdn.net/m0_37892044/article/details/107576920">深入SpringBoot启动原理</a></td>
</tr>
<tr class="active">
<td>7</td>
<td><a href="https://blog.csdn.net/m0_37892044/article/details/107887911">SpringBoot使用Atomikos实现分布式事务管理</a></td>
</tr>
<tr class="success">
<td>8</td>
<td><a href="">深入SpringBoot核心原理,带你实现一个SpringBoot框架</a></td>
</tr>
</tbody>
</table>
</body>
</html>