手写一个SpringBoot框架!

共 6356字,需浏览 13分钟

 ·

2022-03-01 18:07

你知道的越多,不知道的就越多,业余的像一棵小草!

你来,我们一起精进!你不来,我和你的竞争对手一起精进!

编辑:业余草

blog.csdn.net/m0_37892044

推荐:https://www.xttblog.com/?p=5317

文章目录

  • 什么是SpringBoot?
  • 手写SpringBoot需要什么来支撑?
  • 怎么整合其他框架?
    • 怎么构建一个Http服务器(tomcat)?
    • 怎么使用注解代替XML?
  • 手写我们的SpringBoot框架
    • PageController
    • pageIndex
    • 演示效果
    • HelloService
    • 启动Http服务器(tomcat)
    • restful调用演示效果
    • 创建maven项目,引入对应依赖
    • 编写Http服务器(tomcat)
    • 用注解的方式配置Spring
    • 用注解的方式配置视图解析器
    • 注册DispatcherServlet,以及Spring托管
    • 设置controller返回值
    • 使用示例:restful接口
    • RestController
    • 使用示例:返回到页面

在开始我们手写 SpringBoot 框架之前,我们还是先来好好的了解下,什么是 SpringBoot。

相信有很多小伙伴,从 SSM 项目到 SpringBoot(使用 Mybatis)项目发现,编写代码的方式,好像没有什么改变,唯一改变好像就是没有了以前的那一堆 Spring 配置,当然也发现怎么连 web.xml 也不见了?

SpringBoot的web.xml哪去了
web.xml

总之就是在SpringBoot中,这些东西全不见。通过学习这篇文章,我们就知道为什么不见了。

什么是SpringBoot?

SpringBoot 是一个快速开整合第三方框架的框架,全部采用注解形式替代原来的XML形式,内置Tomcat容器。

换句话来说,SpringBoot并不是一个严格的开发框架,而是快速整合框架的框架。例如SpringBoot整合Spring、SpringMVC、MyBatis后,此项目的使用方式和使用maven的SSM框架几乎完全一致,最大的改变是,没了那一堆Spring的配置,以及web.xml配置。

如果我们现在来手写一套SpringBoot,我们需要做什么工作?

手写SpringBoot需要什么来支撑?

怎么整合其他框架?

这个比较简单,maven依赖就能实现了。所以创建一个maven项目就gameover了。

怎么构建一个Http服务器(tomcat)?

之前的文章已经着重讲述了构建一个tomcat服务,这里不在重复。

怎么使用注解代替XML?

之前的文章中,我们讲了SpringBoot怎么启动的,在这篇文章中,我们介绍了@SpringBootApplication的核心组建之一有@SpringBootConfiguration。

这个注解干嘛用的, 如果没有看过这篇文章,或者忘记了,我们先回顾下
SpringBoot中的@SpringBootConfiguration和Spring3.0版本中发布的Configuration作用完全一致。

@Configuration作用:配置Spring容器,使用 Java代码形式来配置Spring上下文中的bean。当我们把@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的,作用为:配置spring容器(应用上下文)

例如如下配置中的 bean 可以用 java 类来配置。

手写 SpringBoot 框架

现在,有了上述三个知识点的支撑,离我们手写 SpringBoot 框架就不远了。

手写我们的SpringBoot框架

创建maven项目,引入对应依赖


<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>

编写Http服务器(tomcat)

这里跟我们之前的文章:教你用Java的方式创建一个自己的Tomcat容器,功能几乎一致,唯一区别,就是这里我们不是配置servlet,而是将提供的web应用资源添加到此Web应用程序,这种方式比较灵活,毕竟应该是资源文件有什么,我们加什么,总不能一个一个资源用手动的方式去加载吧。

/**
 * @Description:内置tomcat
 */

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();
 }

}

用注解的方式配置Spring

@Configuration注解声明它是配置类,@ComponentScan指定扫包的范围。

/**
 * @Description:Spring上下文注解配置
 */

@Configuration
@ComponentScan("com.hutao.springboot.write")
public class SpringApplicationConfig {
 
}

用注解的方式配置视图解析器

/**
 * @Description:SpringMVC注解配置,视图解析器
 */

@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;
 }
}

注册DispatcherServlet,以及Spring托管

通过实现org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer这个接口,来完成托管和注册

/**
 * @Description:注册DispatcherServlet,以及Spring托管
 */

public class AnnotationConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

 /**
  * @Description:Spring上下文配置:从跟目录去获取上下文应用
  */

 protected Class[] getRootConfigClasses() {
  return new Class[] { SpringApplicationConfig.class };
 }
 
 /**
  * @Description:SpringMVC配置,本质就是Servlet应用程序上下文的配置
  */

 protected Class[] getServletConfigClasses() {
  return new Class[] { SpringMvcConfig.class };
 }

 /**
  * @Description:Servlet映射
  */

 protected String[] getServletMappings() {
  return new String[] { "/" };
 }

}

设置controller返回值

/**
 * @Description:格式化返回JSON
 */

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();
 }
}

使用示例:restful接口

RestController

@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;
 }
}

HelloService

public interface HelloService {
 
  String hello(String userName);
  
}
@Service
public class HelloServiceImpl implements HelloService{

 public String hello(String userName) {
  return userName+"手写SpringBoot集成SpringMVC和Spring";
 }
}

启动Http服务器(tomcat)

启动 tomcat 以后,我们看到我们的 controller被扫描并且注册了。

controller被扫描并且注册

restful调用演示效果

接下来我们访问下这个接口。

restful调用演示效果

使用示例:返回到页面

创建返回页面的 controller

PageController

@Controller
@RequestMapping("/page")
public class PageController {
  
 @RequestMapping("/pageIndex")
 public String pageIndex() {
  return "pageIndex";
 }
}

pageIndex

在 WEB-INF 目录下,创建一个 pageIndex 页面。

手写SpringBoot
<%@ page language="java" pageEncoding="utf-8"%>



 "UTF-8">
 主页面
 "stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">  
 
 
 



class="table">
 
  
   "width:10%">序号
   "width:90%">内容
  
 
 
  class="active">
   1
   "">深入SpringIOC原理解析,带你实现一个SpringIOC框架
  
  class="success">
   2
   "">深入SpringMVC原理解析,带你实现一个SpringMVC框架
  
  class="warning">
   3
   "">深入数据库连接池原理解析,带你实现一个连接池框架
  
  class="danger">
   4
   "">深入MyBatis原理解析,带你实现一个MyBatis框架
  
  class="success">
   5
   "">使用SpringToolSuite快速构建一个SpringBoot项目
  
  class="active">
   6
   "">深入SpringBoot启动原理
  
  class="active">
   7
   "">SpringBoot使用Atomikos实现分布式事务管理
  
  class="success">
   8
   "">深入SpringBoot核心原理,带你实现一个SpringBoot框架
  
 



演示效果

通过访问我们的 pageController,实现访问我们的页面。

手写SpringBoot

浏览 55
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报