SpringBoot基础学习
Posted yfyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot基础学习相关的知识,希望对你有一定的参考价值。
SpringBoot基础
回顾
JavaSE:OOP
MySQL:持久化
html+css+js+jquey+框架:
JavaWeb:原始MVC框架
SSM:框架,简化了开发流程,配置复杂
war:Tomcat运行
SpringBoot:内嵌tomcat,微服务架构
微服务
微服务是一种风格、要求我们在开发一个应用时,这个应用必须构建成一系列小服务的组合,可以通过http的方式进行互通
单体应用架构
指我们将一个应用中的所有应用服务器都封装在一个应用中。
无论ERP、CRM、或其他系统,都把数据库访问、web访问,等等各个功能放到一个war包内。
- 好处是,易于开发和测试:也十分方便部署;当需要扩展时,只需要将war复制多份,然后放到多个服务器上,再做个负载均衡即可。
- 缺点是,修改一个小地方,都需要停掉整个服务,重新打包、部署这个应用war包。
微服务架构
all in one的架构方式,我们把所有的功能单元放在一个应用里面。然后我们把整个应用部署到服务器上。如果负载能力不行,我们将整个应用进行水平复制,进行扩展,然后在负载均衡。
所谓微服务架构,就是打破之前all in one的架构方式,把每个功能元素独立出来。把独立出来的功能元素的动态组合,需要的功能元素才去拿来组合,需要多一些时可以整合多个功能元素。所以微服务架构是对功能元素进行复制,而没有对整个应用进行复制。
这样做的好处是:
- 节省了调用资源。
- 每个功能元素的服务都是一个可替换的、可独立升级的软件代码。
构建微服务
一个大型系统的微服务架构,就像一个复杂交织的神经网络,每一个神经元就是一个功能元素,它们各自完成自己的功能,然后通过http相互请求调用。比如一个电商系统,查缓存、连数据库、浏览页面、结账、支付等服务都是一个个独立的功能服务,都被微化了,它们作为一个个微服务共同构建了一个庞大的系统。如果修改其中的一个功能,只需要更新升级其中一个功能服务单元即可。
但是这种庞大的系统架构给部署和运维带来很大的难度。于是,spring为我们带来了构建大型分布式微服务的全套、全程产品:
- 构建一个个功能独立的微服务应用单元,可以使用springboot,可以帮我们快速构建一个应用;
- 大型分布式网络服务的调用,这部分由spring cloud来完成,实现分布式;
- 在分布式中间,进行流式数据计算、批处理,我们有spring cloud data flow。
- spring为我们想清楚了整个从开始构建应用到大型分布式应用全流程方案。
SpringBoot简介
Spring是如何简化Java开发的:
- 基于POJO的轻量级和最小侵入性编程
- 通过IOC,依赖注入(DI)和面向接口是实现松耦合
- 基于切面(AOP)和惯例进行声明式编程
- 通过切面和模板减少样式代码
Spring优点:
Spring是Java企业版的轻量级代替品。无需开发重量级的EnterpriseJavaBean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象实现了EJB功能。
Spring缺点:
虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。还包括依赖管理,也是十分复杂的,各种依赖的兼容问题。
SpringBoot概述
SpringBoot基于Spring开发,SpringBoot本身不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring框架的应用程序。
约定大于配置
SpringBoot优点
- 开箱即用
- 没有冗余代码一级XML配置要求
- 内嵌式容器简化Web项目
- SpringBoot不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式
SpringBoot的核心功能
- 起步依赖
- 自动配置
第一个SpringBoot程序
- jdk
- maven
- springboot
- idea
官方:提供了快速网站
@SpringBootApplication
public class HelloworldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloworldApplication.class, args);
}
}
SpringBoot的热部署
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
勾选Build project automatically,然后 shift + ctrl + alt + / 选择 registy
原理初探
自动配置
pom.xml
spring-boot-starter-parent: 核心依赖在父工程中
<!-- web功能起步依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
引入一些springboot依赖时,不需要指定版本,因为有版本仓库
启动器
- 就是springboot的启动场景
- 比如Spring-boot-starter-web,他就会帮我们自动导入web环境所有的依赖
- springboot会将所有的功能场景都设置为启动器
我们需要什么功能,直接找到对应的启动器即可starter
主程序
//标注这个类是一个springboot的应用
@SpringBootApplication
public class HelloworldApplication {
public static void main(String[] args) {
//将springboot应用启动
SpringApplication.run(HelloworldApplication.class, args);
}
}
注解
@SpringBootConfiguration: springboot的配置
? @Configuration: spring配置类
? @Component: 说明其是spring的一个组件
@EnableAutoConfiguration: 自动配置核心注解
? @AutoConfigurationPackage: 自动配置包
? @Import(AutoConfigurationPackages.Registrar.class): 自动配置包注册
? @Import(AutoConfigurationImportSelector.class): 自动配置导入选择
//获取所有配置
Listconfigurations= getCandidateConfigurations(annotationMetadata, attributes); protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; }
META-INF/spring.factories:自动配置的核心文件
结论:springboot所有自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里面,但是不一定生效,需要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后配置成功
- springboot在启动时,从类路径下/META-INF/spring.factories获取指定的值
- 将这些自动配置的类导入容器,自动配置就会生效,帮我进行自动配置
- 以前我们需要自动配置的东西,springboot帮我们做了
- 整合JavaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.2.0.RELEASE.jar这个包下
- 它会把所有需要导入的主键以类名的方式返回,这些组件就会被添加到容器
- 容器中会存在非常多的xxxAutoConfiguration的文件,就是这些类给容器中导入了这个场景需要的所有组件;并自动配置,@Configuration,JavaConfig!
- 有了自动配置类,免去了我们手动编写配置文件的工作
Run
@SpringBootApplication
public class SpringbootDemo02Application {
public static void main(String[] args) {
//该方法返回一个ConfigurableApplicationContext对象
//参数一:应用入口的类 参数类:命令行参数
SpringApplication.run(SpringbootDemo02Application.class, args);
}
}
该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;
SpringApplication
这个类主要做了以下四件事情
- 推断应用的类型是普通的项目还是Web项目
- 查找并加载所有可用初始化器 , 设置到initializers属性中
- 找出所有的应用程序监听器,设置到listeners属性中
- 推断并设置main方法的定义类,找到运行的主类
Run方法
SpringBoot配置文件
SpringBoot使用全局配置文件,配置文件名称是固定的
- application.properties
- 语法结构: key = value
- application.yml
- 语法结构: key: 空格 value
配置文件的作用:修改了SpringBoot自动配置默认的值,因为SpringBoot在底层都给我们自动配置好了
Yaml
YML是YAML(YAML Aint Markup Language)编写的文件格式,YAML是一种直观的能够被电脑识别的数据序列化格式,容易被阅读,容易和脚本语言交互,可以支持YAML库的不同编程语言程序导入,YML文件是以数据为核心,比传统的XML方式更加简洁
#普通的key - value
name: 张磊
#对象
student:
name: 张磊
age: 22
#行内写法
teacher: { name: 张磊, age: 22 }
#改端口
service:
prot: 8082
#数组
pets:
- cat
- dog
- pig
petss: [cat,dog,pig]
#集合、数据(对象数据)
student:
- name: tom
age: 22
addr: beijing
- name: cat
age: 18
addr: shanghai
student: [{name: tom, age: 22, addr: beijing},{name: cat, age: 18, addr: shanghai}]
#Map配置
map:
key1: value1
key2: value2
yaml可以直接给实体类赋值
原生方式
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired
private Dog dog;
@Test
void contextLoads() {
System.out.println(dog.toString());
}
}
不影响程序运行,可以到官网解决
yaml赋值
person:
name: 张磊
age: 22
happy: yes
birth: 2020/02/22
maps: {k1: v1, k2: v2}
lists:
- code
- music
- girl
dog:
name: 纪烁
age: 3
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
@ConfigurationProperties(prefix = "person")
ConfigurationProperties的作用:
将配置文件中配置每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = "person" :将配置文件中的person下面的所有属性--对应
只要这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
使用properties的后果
乱码问题-
settings ----> FileEncodings 中配置
@ConfigurationProperties与@Value的区别
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个绑定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
- cp只需要写一次即可,value则需要每个字段都添加
- last-name,与lastName是一样的
- JSR303数据校验,这个就是我们可以在字段是增加一层过滤器验证,可以保证数据的合法性
- 复杂类型封装,yml可以封装对象,使用@Value就不支持
结论
- 配置yml和配置properties都可以获取到值 , 强烈推荐 yml
- 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value
- 如果说,我们专门编写了一个JavaBean来和配置文件进行映射,就直接使用@configurationProperties,不要犹豫!
JSR303数据校验
spring-boot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。我们这里来写个注解让我们的name只能支持Email格式
@Component //注册bean
@ConfigurationProperties(prefix = "person")
@Validated //数据校验
public class Person {
//@Value("${person.name}")
@Email //name必须是邮箱格式
private String name;
}
加载指定配置文件
@PropertySource(value = "classpath:person.properties")
配置文件占位符
${random.value}、${random.int}、${random.long}、${random.int(10)}等等
SpringBoot多环境切换
多配置文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;
例如:application-test.properties 代表测试环境配置 application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;
我们需要通过一个配置来选择需要激活的环境;
#比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试; #我们启动SpringBoot,就可以看到已经切换到dev下的配置了; spring.profiles.active=dev
yml的多文档块
和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了
server: port: 8081 #选择要激活那个环境块 spring: profiles: active: prod --- server: port: 8083 #配置环境的名称 spring: profiles: dev --- server: port: 8084 spring: profiles: prod #配置环境的名称
配置文件加载位置
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
优先级1:项目路径下的config文件夹配置文件 优先级2:项目路径下配置文件 优先级3:资源路径下的config文件夹配置文件 优先级4:资源路径下配置文件
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;*互补配置*;
我们在最低级的配置文件中设置一个项目访问路径的配置来测试互补问题;
#配置项目的访问路径 server.servlet.context-path=/kuang
SpringBoot集成其他技术
Mybatis
1.添加依赖
<!-- web功能起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加数据库驱动坐标 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- Mybatis起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
2.添加数据库连接信息
#数据库连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/zl?useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=1870535196
3.dao层
@Mapper
public interface UserMapper {
@Select("select * from user")
List<User> selectAll();
}
4.pojo层
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
private String name;
}
5.controller层
@Controller
public class MybatisController {
@Autowired
private UserMapper userMapper;
@RequestMapping("/query")
@ResponseBody
public List<User> queryAll() {
List<User> users = userMapper.selectAll();
return users;
}
}
以上是关于SpringBoot基础学习的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot启动报错“Consider defining a bean of type ‘xxx.mapper.UserMapper‘ in your configuration.“(代码片段