文章目录
微服务概念
简单说就是每个功能独立可部署
目前有两套常用的解决方案
- springBoot + springCloud
- 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 :
- springboot-starter-jdbc 数据库访问
- springboot-starter-web WEB层访问
- springboot-starter-actuator 监控
4种创建方法
- 访问https://start.spring.io 创建
- CLI创建
- 创建MAVEN项目添加依赖
- 创建MAVEN项目
- pom.xml添加依赖
- 创建springBoot主启动类 @SpringBootApplication
- 开发工具自带创建方式
案例: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等等)
-
JAR包
首先电脑要安装好maven- 进入工程目录(也就是pom.xml所在目录)命令行执行
mvn package
命令 - 或者在eclipse中右击项目,选择Run As - Maven install
就会在target目录生成一个jar包
通过java -jar xxx.jar
就启动服务了
- 进入工程目录(也就是pom.xml所在目录)命令行执行
-
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
启动过程分析
- 入口 @SpringBootApplication注释的java类
- @SpringBootApplication 主要是
- @SpringBootConfiguration(内部为@Configuration) 配置bean
- @EnableAutoConfiguration 开启自动配置spring的上下文
- @ComponentScan 组件扫描,可自动发现和装配Bean。需要放在根路径扫描的才是整个项目
- @SpringBootApplication 主要是
SpringApplication.run(启动类.class, args);
- 执行 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);
}
- 创建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();
}
- 运行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);
}
}