尝试手写一个框架(六)手写一套SpringBoot框架,加深对SpringBoot框架得理解


在开始我们手写SpringBoot框架之前,我们还是先来好好的了解下,什么是SpringBoot。
相信有很多小伙伴,从SSM项目到SpringBoot(使用Mybatis)项目发现,编写代码的方式,好像没有什么改变,唯一改变好像就是没有了以前的那一堆Spring配置,当然也发现怎么连web.xml也不见了?
在这里插入图片描述
在这里插入图片描述
总之就是在SpringBoot中,这些东西全不见。通过学习这篇文章,我们就知道为什么不见了。

1.什么是SpringBoot?

SpringBoot 是一个快速开整合第三方框架的框架,全部采用注解形式替代原来的XML形式,内置Tomcat容器。
换句话来说,SpringBoot并不是一个严格的开发框架,而是快速整合框架的框架。例如SpringBoot整合Spring、SpringMVC、MyBatis后,此项目的使用方式和使用maven的SSM框架几乎完全一致,最大的改变是,没了那一堆Spring的配置,以及web.xml配置。
如果我们现在来手写一套SpringBoot,我们需要做什么工作?

2.手写SpringBoot需要什么来支撑?

2.1.怎么整合其他框架?

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

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

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

2.3.怎么使用注解代替XML?

之前的文章中,我们讲了SpringBoot怎么启动的,在这篇文章中,我们介绍了@SpringBootApplication的核心组建之一有@SpringBootConfiguration。
这个注解干嘛用的, 如果没有看过这篇文章,或者忘记了,我们先回顾下
SpringBoot中的@SpringBootConfiguration和Spring3.0版本中发布的Configuration作用完全一致。
@Configuration作用:配置Spring容器,使用 Java代码形式来配置Spring上下文中的bean。当我们把@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的,作用为:配置spring容器(应用上下文)
例如如下配置中的bean可以用java类来配置。
在这里插入图片描述
现在,有了上述三个知识点的支撑,离我们手写SpringBoot框架就不远了。

3.手写我们的SpringBoot框架

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

<!--Java语言操作tomcat -->
			<dependency>
				<groupId>org.apache.tomcat.embed</groupId>
				<artifactId>tomcat-embed-core</artifactId>
				<version>8.5.16</version>
			</dependency>
	
			<!-- tomcat对jsp支持 -->
			<dependency>
				<groupId>org.apache.tomcat</groupId>
				<artifactId>tomcat-jasper</artifactId>
				<version>8.5.16</version>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-web</artifactId>
				<version>5.0.4.RELEASE</version>
				<scope>compile</scope>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-webmvc</artifactId>
				<version>5.0.4.RELEASE</version>
				<scope>compile</scope>
			</dependency>
			<dependency>
			    <groupId>com.fasterxml.jackson.core</groupId>
			    <artifactId>jackson-databind</artifactId>
			    <version>2.9.1</version>
			</dependency>

3.2.编写Http服务器(tomcat)

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

/**
 * @Description:内置tomcat 
 * @author hutao
 * @mail:hutao_2017@aliyun.com
 * @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();
	}

}

3.3.用注解的方式配置Spring

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

/**
 * @Description:Spring上下文注解配置
 * @author hutao
 * @mail:hutao_2017@aliyun.com
 * @date 2020年8月11日
 */
@Configuration
@ComponentScan("com.hutao.springboot.write")
public class SpringApplicationConfig {
	
}

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

/**
 * @Description:SpringMVC注解配置,视图解析器  
 * @author hutao
 * @mail:hutao_2017@aliyun.com
 * @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;
	}
}

3.5.注册DispatcherServlet,以及Spring托管

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

/**
 * @Description:注册DispatcherServlet,以及Spring托管
 * @author hutao
 * @mail:hutao_2017@aliyun.com
 * @date 2020年8月10日
 */
public class AnnotationConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

	/**
	 * @Description:Spring上下文配置:从跟目录去获取上下文应用
	 * @author hutao
	 * @mail:hutao_2017@aliyun.com
	 * @date 2020年8月10日
	 */
	protected Class<?>[] getRootConfigClasses() {
		return new Class[] { SpringApplicationConfig.class };
	}
	
	/**
	 * @Description:SpringMVC配置,本质就是Servlet应用程序上下文的配置 
	 * @author hutao
	 * @mail:hutao_2017@aliyun.com
	 * @date 2020年8月10日
	 */
	protected Class<?>[] getServletConfigClasses() {
		return new Class[] { SpringMvcConfig.class };
	}

	/**
	 * @Description:Servlet映射
	 * @author hutao
	 * @mail:hutao_2017@aliyun.com
	 * @date 2020年8月10日
	 */
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}

}

3.6.设置controller返回值

/**
 * @Description:格式化返回JSON  
 * @author hutao
 * @mail:hutao_2017@aliyun.com
 * @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();
	}
}

3.7.使用示例:restful接口

3.7.1.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;
	}
}

3.7.2.HelloService

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

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

3.7.3.启动Http服务器(tomcat)

启动tomcat以后,我们看到我们的controller被扫描并且注册了
在这里插入图片描述

3.7.4.restful调用演示效果

接下来我们访问下这个接口
在这里插入图片描述

3.8.使用示例:返回到页面

创建返回页面的controller

3.8.1.PageController

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

3.8.2.pageIndex

在WEB-INF目录下,创建一个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>

3.8.3.演示效果

通过访问我们的pageController,实现访问我们的页面
在这里插入图片描述

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值