SpringBoot创建方法,启动流程分析

微服务概念

简单说就是每个功能独立可部署
目前有两套常用的解决方案

  1. springBoot + springCloud
  2. Dubboo + Zookeeper

SpringBoot

个人觉得 SpringBoot说是框架, 更接近于脚手架
就是用spring,Spring MVC,Thymeleaf ,Tomcat ,Jetty ,Maven等等构建成了一个独立启动,容易扩展的项目

springboot这东西就是为了方便开发的, 所以基本都是开发技巧 , 敲一遍就都明白了, 没什么新的原理需要学习

springboot练习demo https://github.com/xu1211/springbootdemo

springBoot是对spring框架进一步封装, 相当于一个配置好(spring+servlet容器)的jar包工程, 其本质上是一个 Java 应用程序,内置了容器, 可以独立运行, 非常契合微服务的理念

默认 不支持JSP, 支持Thymeleaf ,freemarker
默认内置Tomcat容器

场景启动器starter (场景/模板/可拔插式的插件) , 每个场景都封装成starter, 导入这个starter就有了这个场景的一切jar包,配置文件,依赖信息等等

常用的starter :

  1. springboot-starter-jdbc 数据库访问
  2. springboot-starter-web WEB层访问
  3. springboot-starter-actuator 监控

4种创建方法

  1. 访问https://start.spring.io 创建
  2. CLI创建
  3. 创建MAVEN项目添加依赖
    1. 创建MAVEN项目
    2. pom.xml添加依赖
    3. 创建springBoot主启动类 @SpringBootApplication
  4. 开发工具自带创建方式

案例:maven创建springboot

1. 创建Maven项目

https://blog.csdn.net/xyc1211/article/details/83216074

2. 加入SpringBoot相关依赖

右键点击项目->Maven->Update Project 更新项目就会自动下载jar包, 得下一段时间

<!-- 继承SpringBoot官方指定的父工程 -->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.6.RELEASE</version>
</parent>

<dependencies>
	<!-- 加入Web开发所需要的场景启动器 -->
	<dependency>
		<!-- 指定groupId和artifactId即可,版本已在父工程中定义 -->
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>

<!-- Maven构建过程相关配置 -->
<build>
	<!-- 构建过程中所需要用到的插件 -->
	<plugins>
		<!-- 这个插件将SpringBoot应用打包成一个可执行的jar包 -->
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

3. @SpringBootApplication创建主启动类
package ......;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloWorldMainType {
	
	public static void main(String[] args) {
		SpringApplication.run(HelloWorldMainType.class, args);
	}
}
4. @Controller创建控制器类
package ......;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldHandler {
	
	@RequestMapping("/hello")
	public String hello() {
		return "Hello Spring Boot!!!";
	}
}
5. 开发完毕, 打包部署

SpringBoot默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动。其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat)。当然也可以将项目打包成war包,放到独立的web容器中(Tomcat、weblogic等等)

  1. JAR包
    首先电脑要安装好maven

    1. 进入工程目录(也就是pom.xml所在目录)命令行执行mvn package命令
    2. 或者在eclipse中右击项目,选择Run As - Maven install
      就会在target目录生成一个jar包
      通过java -jar xxx.jar 就启动服务了
  2. war包

配置文件

SpringBoot本身有自动配置 约定>配置
项目都按照 约定(自动配置) 运行, 比如约定好Tomcat用8080端口
可在项目src/main/resources路径下创建配置文件, 文件名是application.properties或application.yml
配置文件是对自动配置的调整和修改。

  • 使用多个配置文件,启动时用参数确定用那个
    开发环境用的配置文件:application-dev.properties
    生产环境用的配置文件:application-pro.properties
    java -jar xxx.jar --spring.profiles.active=pro
    java -jar xxx.jar --spring.profiles.active=dev
    ​​​​​​

启动过程分析

在这里插入图片描述

  1. 入口 @SpringBootApplication注释的java类
    • @SpringBootApplication 主要是
      1. @SpringBootConfiguration(内部为@Configuration) 配置bean
      2. @EnableAutoConfiguration 开启自动配置spring的上下文
      3. @ComponentScan 组件扫描,可自动发现和装配Bean。需要放在根路径扫描的才是整个项目
SpringApplication.run(启动类.class, args);
  1. 执行 SpringApplication类的 静态 run方法
    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class[]{primarySource}, args);
    }

    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return (new SpringApplication(primarySources)).run(args);
    }
  1. 创建SpringApplication实例
    SpringApplication实例的 构造方法
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
	// 资源加载器
    this.resourceLoader = resourceLoader;
    // 判断资源加载类不能为null
    Assert.notNull(primarySources, "PrimarySources must not be null");
    // 初始化资源加载类并去重
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    // 通过核心类判断是否开启、开启什么web容器
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    // 应用上下文初始器
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    // 监听器
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    // 判断主类入口
    this.mainApplicationClass = deduceMainApplicationClass();
}
  1. 运行SpringApplication实例的run方法
    run方法完成了所有Spring的整个启动过程:准备Environment——发布事件——创建上下文、bean——刷新上下文——结束
    public ConfigurableApplicationContext run(String... args) {
    	// 创建并启动计时监控类, 用来统计启动时间并在日志打印
        StopWatch stopWatch = new StopWatch();
// 开始执行,记录时间
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
        // 创建所有spring监听器 内部只有EventPublishingRunListener 该注册器是一个用于广播Spring事件的广播器
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        // 启动监听,广播出去给SpringApplication中的listeners所监听
        listeners.starting();

        Collection exceptionReporters;
        try {
        	// 封装main方法的参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            // 加载配置环境
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            // 打印标语
            Banner printedBanner = this.printBanner(environment);
            // 创建应用上下文实例, 就是根据Web容器类型的不同来创建不用的上下文实例。
            context = this.createApplicationContext();
            // 异常播报器
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            // 对刚创建的上下文完成加载,设置上下文容器的配置环境,监听等
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            // 刷新上下文
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
// 执行结束,记录时间
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
			// 发布 应用上下文启动完成事件
            listeners.started(context);
            // 执行所有runner运行器
            this.callRunners(context, applicationArguments);
	    } catch (Throwable ex) {
	        this.handleRunFailure(context, ex, exceptionReporters, listeners);
	        throw new IllegalStateException(ex);
	    }
	    
	    try {
	    	// 发布 应用上下文就绪事件
	        listeners.running(context);
	    	// 返回应用上下文
	    	return context;
	    } catch (Throwable ex) {
	        this.handleRunFailure(context, ex, exceptionReporters, null);
	        throw new IllegalStateException(ex);
	    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值