目录
- SpringBoot简介
- SpringBoot第一个程序输出Hello Wrold
- SpringBoot细节分析之场景启动器(starter)
- 如何快速创建Spring Boot应用
- SpringBoot的配置(配置文件、加载顺序、配置原理)
SpringBoot简介
Spring Boot来简化Spring应用,约定大于配置,去繁从简,just run就能创建一个独立的,产品级别的应用
背景:
J2EE笨重的开发,繁多的配置,低下的开发效率,复杂的部署流程,第三方技术集成难度大
解决:
"Spring全家桶"时代
Spring Boot—>J2EE一站式解决方案
Spring Cloud—>分布式整体解决方案
优点:
- 快速创建独立运行的Spring项目以及与主流框架集成
- 使用嵌入式的Servlet容器,应用无需打成WAR包
- starters(启动器)自动依赖与版本控制
- 大量的自动配置,简化开发,也可修改默认值
- 无需配置XML,无代码生成,开箱即用
- 准生产环境的运行时应用监控
- 与云计算的天然集成
缺点: 入门容易精通难(要想精通,必须精通其源码,API)
微服务
2014,Martin Fowler
微服务:架构风格
一个应用应该是一组小型服务;可以通过HTTP的方式进行互通;
单体应用:ALL IN ONE
每一个功能元素最终都是一个可独立替换和独立升级的软件单元;
环境因数:
–jdk1.8:
–maven3.x
–IntellijIDEA
–SpringBoot 1.5.9.RELEASE
SpringBoot第一个程序输出Hello Wrold
返回目录
完成一个功能
浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串
1.创建一个maven工程;(jar)
2.导入SpringBoot相关依赖
pom文件里配置:
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
3.编写一个主程序;启动SpringBoot应用
@SpringBootApplication//来标注一个主程序类,说明这是一个SpringBoot应用
public class HelloWorldMainApplication {
public static void main(String[] args) {
//Spring应用启动起来
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
4.编写相关的Controller、Service
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "Hello World!";
}
}
注意点在包的位置一定要对:
其他类与启动类在同一个包下或者同一级包的下面(后面有解释原因!!!)
5、运行主程序测试
6、简化部署
pom文件里配置:
<!--这个插件,可以将应用打包成一个可执行的jar包(必不可少)-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
将这个应用打成jar包(Maven的package命令),直接使用java -jar的命令进行执行
成功!
再用浏览器访问一下地址吧
没问题!
SpringBoot细节分析之场景启动器(starter)
Hello World探究
1、pom文件
父项目:
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>1.5.9.RELEASE</version>
</parent>
spring-boot-starter-parent它的父项目是
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
它才是来真正管理Spring Boot应用里面的所有依赖版本;
它被称为SpringBoot的版本仲裁中心
所有以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)
2、导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web
spring-boot-starter:spring-boot场景启动器;帮我们导入了web模块正常运行所依赖的组件;
SpringBoot将所有的功能场景都抽取出来,做成一个个starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器
SpringBoot细节分析之-自动配置
主程序类,主入口类
@SpringBootApplication//来标注一个主程序类,说明这是一个SpringBoot应用
public class HelloWorldMainApplication {
public static void main(String[] args) {
//Spring应用启动起来
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
@SpringBootApplication:SpringBoot应用标注在某个类上说明这个类是SpringBoot主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@SpringBootConfiguration: SpringBoot的配置类;
标注在某个类上,表示这是一个SpringBoot的配置类;
@Configuration: 配置类上来标注这个注解
配置类————配置文件;配置类也是容器中的一个组件:@Component
@EnableAutoConfiguration: 开启自动配置功能
以前我们需要配置的东西,SpringBoot帮我们自动配置;这个注解会告诉SpringBoot开启自动配置功能;这样自动配置才能生效;
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
@AutoConfigurationPackage: 自动配置包
@Import({Registrar.class})
Spring的底层注解@Import,给容器中导入一个组件;导入的组件由({Registrar.class}决定
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
@Import({EnableAutoConfigurationImportSelector.class}):给容器中导入组件
EnableAutoConfigurationImportSelector.class:导入哪些组件的选择器;
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;
会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给导入这个场景需要的所有组件,并配置好这些组件;
有了自动配置类,就免去了我们手动编写配置注入功能等的工作;
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);
==SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效了,帮我们进行自动配置工作;==以前我们需要自己配置的东西,自动配置类都帮我们做了;
J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar;
如何快速创建Spring Boot应用
返回目录
IDEA使用Spring Initializer快速创建SpringBoot项目
步骤:
启动并测试:(成功!!!)
IDE都支持使用Spring的项目创建向导快速创建一个SpringBoot项目;
选择我们需要的模板;向导会联网创建SpringBoot项目;
默认生成的SpringBoot项目:
- 主程序已经生成好了,我们只需要我们自己的逻辑
- resource文件夹目录结构
- static:保存所有的静态ziyuan;js文件,css文件,images图片文件等等
- templates:保存所有的模板页面;(SpringBoot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面,但是可以使用模板引擎:freemarker、thymeleaf);
- application.properties:SpringBoot应用的配置文件;可以修改一些默认设置
SpringBoot的配置(配置文件、加载顺序、配置原理)
1、配置文件YML介绍
SpringBoot使用一个全局的配置文件(配置文件名是固定的)
- application.properties
- application.yml
配置文件放在src/main/resources目录或者类路径/config下
配置文件的作用:修改SpringBoot自动配置的默认值;
原因在于SpringBoot在底层都给我们自动的配置好了;要想修改默认配置,只能使用这些全局配置文件。
.yml是YAML(YAML Ain’t Markup Language)语言的文件,以数据为中心,比json、xml等更适合做配置文件
.yml全称有两种写法合并:
- YAML A Markup Language:是一个标记语言
- YAML isn’t Markup Language:不是一个标记语言
标记语言:
以前的配置文件;大多都使用 xxx.xml
YAML:以数据为中心,比json、xml等更适合做配置文件
YAML:配置例子
server:
port: 8081
xml配置:(大量的数据都浪费在标签的开闭上)
<server>
<port>8081</port>
</server>
2、YAML语法:
基本语法:
- 属性写法为k:(空格)v:表示一对键值对(空格必须有);
- 以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一层级的
server:
port: 8081
path: /hello
属性和值也是大小写敏感;
值的写法:
- 字面量:普通的值(数字,字符串,布尔)
k:v:字面直接来写(字符串默认不用加上单引号或者双引号)
“”:双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的样子
例:name:“zhangsan \n lisi”:输出:zhangsan 换行 lisi
‘’:单引号:会转义特殊字符,特殊字符最终只是一个普通的字符串数据
例:name:“zhangsan \n lisi”:输出:zhangsan \n lisi
注:这里的转义是转换为字符串的意思,\n在双引号中不会被转义为字符串,而是执行换行,\n在单引号中会被转义为字符串原样输出(转义的意思是转换字符本来的意义) - 对象、Map(属性和值)(键值对)
k:v:对象还是这种方式,例:
在下一行来写对象的属性和值的关系;注意缩进
(这里的lastName和age就作为friends对象的属性名,对应其属性值)
friends:
lastName: zhangsan
age: 20
行内写法:
展示效果一:
friends: {
lastName: zhangsan,
age: 18
}
展示效果二:
friends: { lastName: zhangsan,age: 18}
- 数组(List、Set)
用-值表示数组中的一个元素
pets:
- cat
- dog
- pig
行内写法:
pets: [cat,dog,pig]
以上皆可嵌套!!!
实例:
配置文件值注入
- 第一步导入配置文件处理器
我们可以导入配置文件处理器,以后编写配置就有提示了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
- 第二步写好yml配置文件信息:
person:
lastName: c
age: 18
boss: true
birth: 2021/6/6
maps: {k1: v1,k2: v2}
lists:
- 张三
- 李四
dog:
name: 狗哥
age: 2
- 写好实体类person和dog:
/**
* 将配置文件中配置的每一个属性的值,映射到这个组件中
* /@ConfigurationProperties :告诉SpringBoot将本类中所有属性和配置文件相关的配置进行绑定;
* prefix = "person":表示指定配置文件中哪个名字下面的所有属性进行一一映射(这里是person下面)
* /@Component :标明只有这个组件是容器的组件,才能使用容器提供的@ConfigurationProperties功能;
*/
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String lastName;
private Integer age;
private Boolean boss;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
//生成的getter和setter方法还有toString方法的重写略
}
public class Dog {
private String name;
private Integer age;
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
- 第四步运行测试类
@SpringBootTest//SpringBoot单元测试
class SpringBoot01HelloworldQuickApplicationTests {
@Autowired//自动注入
Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
结果:
再展示一下properties编写person类信息
#properties编写person类信息
person.last-name=张三
person.age=18
person.birth=2021/6/6
person.boss=true
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=dog
person.dog.age=2
其他不变,运行即可
配置@ConfigurationProperties与@Value区别
@Value的使用:
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 可以批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value
如果说,我们专门编写了一个JavaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;