Spring Boot
maven配置:
第一步、创建maven项目
第二部、导入springboot依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
3、编写 一个主程序:启动springboot应用
创建启动类:HelloWorldMainApplication
/*
* @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
*
*/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
//Spring应用启动起来
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
4、编写相关的Controller、Service
创建controller
@Controller
public class HelloController {
@ResponseBody //将"Hello World" 写给浏览器
@RequestMapping("/hello") //接受浏览器的/hello请求
public String hello(){
return "Hello World";
}
}
5、测试运行
运行main方法
启动后默认8080端口:
浏览器输入localhost:8080/hello 访问hello请求,浏览器显示Hello World
6、项目简化部署
idea中添加打包插件:
<!-- 这个插件,可以将应用打包成一个可执的jar包 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
双击package打包:
在target下找到jar包:
复制到桌面:
cmd中找到桌面jar包:
运次jar包:
java -jar spring-boot-01-helloworld-1.0-SNAPSHOT.jar
访问localhost:8080/hello
成功。
STS打包:请查看另一个博客:https://blog.csdn.net/weixin_41919354/article/details/105041878
7、HelloWorld探索
(1)父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
他的父项目是
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
他来真正管理spring boot 应用里面的所有依赖版本;
Spring Boot的版本仲裁中心;
所以以后我们导入依赖默认是不需要写版本的(没有在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模块正常运行所需要的依赖组件。
Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starters,相关场景的所有依赖都会导入进来,要什么功能就导入什么场景的启动器。
(3)、主程序类,主入口类
@SpringBootApplication :Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,Spring boot 就应该运行这个类的main方法来启动Spring Boot应用;
@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:Spring Boot的配置类 (springboott中注解)
标注在某个类上,表示这是spring boot的配置类;
@Confuguration:配置类上来标注这个注解;(spring中注解)
配置类—配置文件;配置类也是容器中的一个组件;@Component
@EnableAutoConfiguration:开启自动配置功能
以前需要配置的东西,现在Spring boot帮助我们自动配置;@EnableAutoConfiguration告诉我们Spring Boot开启自动配置功能;这样自动配置才能生效
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
@AutoConfigurationPackage:自动配置包
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
@Import({Registrar.class}); 或者@Import({AutoConfigurationPackage.Registrar.class})
Spring的底层注解@import,给容器中导入一个组件;导入的组件由
AutoConfigurationPackage.Registrar.class;
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面所有组件扫描到Spring容器;
@Import({AutoConfigurationImportSelector.class})
给容器中导入组件?
AutoConfigurationImportSelector:导入哪些组件的选择器;
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;
会给容器中导入非常多的自动配置类(xxxAutoConfigution);就是给容器中导入这个场景所需要的所有组件,并配置好这些组件;
有了自动配置类,免去了我们手动编写配置功能
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
SpringBoot启动的时候从类路径MATA-INF/spring.factories中获取EnableAutoonfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮助我们进行自动配置工作;
以前我们需要自己配置的东西,自动配置全做了;
J2EE的整体解决方案和自动配置都在:
路径:
C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.2.2.RELEASE\spring-boot-autoconfigure-2.2.2.RELEASE.jar
8、使用spring initializer快速创建Spring Boot项目(联网)
Idea中快速创建:
IDE都支持使用Spring的项目创建向导快速创建一个Spring Boot项目;
选择我们需要的模块;向导会联网创建Spring Boot项目;
默认生成的Spring Boot项目:
主程序已经生成好了,我们只需要我们自己的逻辑
resources文件夹中目录结构:
-static:保存所有的静态资源:js、css、image;
-templates:保存所有的模板页面:(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持jsp页面);可以使用模板引擎(freemarker、thymeleaf);
-application.properties:Spring boot应用的配置文件; 可以修改一些默认设置。
将生成的java文件在file-project structure中将src设置为Sources,否则无法在下面目录下创建java类(class)
ok。。。。。
@RestController //4.0版本后可替代@ResponseBody和@Controller的合并
application.properties中可手动设置端口号 server.port=8081
STS快速创建spring boot项目:
选择添加组件:
创建成功:
二、Spring Boot 配置文件 (配置文件、加载顺序、配置原理)
application.properties格式:
application.yml :
同时配置后8083端口生效。
2、YAML语法:
(1)基本语法:
k(空格)v:表示一对键值对(空格必须有)
以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的
```
server:
port: 8081
path: /hello
```
属性和值也是大小写敏感的;
(2)值的写法
(3)配置文件注入
server:
port: 8081
person:
lastName: zhangsan
age: 18
boss: false
birth: 2017/12/12
maps: {k1: v1,k2: 12}
lists:
-lisi
-zhaoliu
dog:
name: 小狗
age: 2
创建个Person类:
package com.geke.bean;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/*
* 将配置文件中配置的每一个属性值,映射到这个组件中
*@ConfigurationProperties:
* 告诉SpringBoot将本类中所有的属性和配置文件中相关的配置进行绑定;
*
* 只有这个组件是容器中的组件,才能容器提供的@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;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getBoss() {
return boss;
}
public void setBoss(Boolean boss) {
this.boss = boss;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
@Override
public String toString() {
return "Person [lastName=" + lastName + ", age=" + age + ", boss=" + boss + ", birth=" + birth + ", maps="
+ maps + ", lists=" + lists + "]";
}
}
导入配置文件处理器,配置文件application.yml进行绑定就会有提示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
spring boot测试类依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
测试类测试person配置的属性是否生效:
package com.geke;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.geke.bean.Person;
/*Spring Boot单元测试
*可以在测试期间很方便的类似编码一样进行自动注入等容器的功能
* */
@SpringBootTest
class SpringBootQuickStartApplicationTests {
@Autowired
Person person;
@Test
void contextLoads() {
System.out.println("test------------");
System.out.println(person);
}
}
person属性值添加成功,即Person类和配置文件application.yml配置绑定成功。
application.properties配置类似:
#配置person的值
person.last-name=zhangsan
person.age=18
person.birth=2017/3/6
person.boss=false
person.lists=a,b,c
person.maps.k1=v1
person.maps.k2=14
运行测试类结果为:
application.properties默认是utf-8编码格式,开发工具也应设置成utf-8格式。
@Value可替代@ConfigurationProperties进行赋值,但是存在区别:
SpEL 语言 :@Value("#{112}") #{112}
@ConfigurationProperties支持JSR303数据校验:
校验提示未通过报错:
-------配置文件yml还是properties他们都能获取到值;
-------如果说,只是获取配置文件中的某项值,使用@Value
浏览器输出 Hello zhangsan:
------如果说,我们专门写了一个javaBean来和配置文件进行映射,那么直接使用@ConfigurationProperties
(4)@PropertySource @ImportResource
@PropertySource:加载指定的配置文件
如果配置文件中配置太多,比较冗杂,可以新建例如person.properties添加person配置
@PropertySource(value = {"classpath:person.properties"})
新建person.properties添加person配置:
测试类运行:
ok。。
@ImportResource:导入Spring配置文件,让配置文件里面的内容生效
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
想让Spring的配置文件生效,加载进来:将@ImportRecource标注在配置类上;
@ImportResource(locations = {"classpath:beans.xml"})
导入Spring配置文件让其生效
创建个HelloService:
创建beans.xml 并配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloService" class="com.geke.service.HelloService"></bean>
</beans>
导入Spring配置文件:
运行结果:true,说明导入成功
Spring Boot推荐给容器中添加组件的方式: 推荐使用全注解的方式
1、配置类=====Spring配置文件
2、使用@Bean给容器中添加组件
/*@Configuration指明当前类是一个配置类;就是来替代之前的Spring配置文件
*
* 之前在配置文件中用<bean></bean>配置
*/
@Configuration
public class MyAppConfig {
//将方法的返回值添加到容器中,容器中这个组件默认的id就是方法名
@Bean
public HelloService helloService() {
System.out.println("配置类@Bean给容器中添加组件了。。。");
return new HelloService();
}
}
不需要beans.xml 和 @ImportResource(locations = {“classpath:beans.xml”}),更加简便
4、配置文件占位符:
1、随机数
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int(1024,65536)}
2、占位符获取 之前配置的值,如果没有可以是用:指定默认值
person打印:
Person [lastName=zhangsanbc9bd289-e9d7-4477-9910-ebb24969e121, age=-1902556100, boss=false, birth=Mon Mar 06 00:00:00 CST 2017, maps={k1=zhangsanca3aac7b-13d2-4faf-914b-a916b21904b4_v1 , k2=hello_14}, lists=[a, b, c]]
5、Profile
1、多Profile文件
我们在主配置文件编写的时候,文件名可以使 application-{profiles}.properties/yml
默认使用application.properties的配置;
2、yml支持多文档块方式
server:
port: 8081
spring:
profiles:
active:
- dev
---
server:
port: 8082
spring:
profiles: dev
---
server:
port: 8083
spring:
profiles: prod
调用8082端口:
3、激活指定profile
(1)在配置文件中 指定 spring.profiles.active=div
启动的端口号是默认配置文件中激活的div配置文件中的8082端口:
加粗样式
(2)命令行参数
打好jar包后,cmd运行:
java -jar spring-boot-quick-start-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
可覆盖yml中制定好的激活端口。
(3)虚拟机参数
-Dspring.profiles.active=dev
6、配置文件加载位置
互不配置;高优先级覆盖相同的功能,低优先级配置部分功能
classpath:/config/下配置文件优先级高于classpath:/下配置文件,所以运行后端口使用8082
可以通过spring.config.location来改变默认的配置文件位置
项目打包好后(不是在项目启动时,时打包好后),我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互不配置;
在配置文件中不会生效,如下(不会生效,具体操作时将之删除掉):
需要先dajar包,运行配置文件时加入代码块才能生效,调用指定位置的配置文件:
java -jar spring-boot-quick-start-0.0.1-SNAPSHOT.jar --spring.config.location=C:/Users/Administrator/Desktop/application.properties
结果,调用了指定位置的配置文件,端口号为8086:
设置项目访问路径:
#配置訪問路徑(未生效,springboot版本问题,以下两种试一下)
#server.context-path=/springboot
server.servlet.context-path=/springboot
添加后项目访问路径变为:
中间加了个springboot
7、外部配置的加载顺序
以上优先级从高到低,相同配置高覆盖低;
(1)命令行参数
java -jar spring-boot-quick-start-0.0.1-SNAPSHOT.jar --server.port=8088 运行后有两种访问方式:
–1、localhost:8085/springboot/hello
–2、localhost:8088/hello
多个配置可用空格分开:
java -jar spring-boot-quick-start-0.0.1-SNAPSHOT.jar --server.port=8088 --server.servlet.context-path=/springppp
访问方式(一种了):
外部配置文件:
外部配置文件配置:
java -jar spring-boot-quick-start-0.0.1-SNAPSHOT.jar
运行项目:
端口号和访问路径被外部配置文件覆盖;
8、1自动配置原理
配置文件到底能写什么?怎么写?自动配置原理;
https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/html/appendix-application-properties.html#common-application-properties
根据当前不同的条件判断,决定这个配置类是否生效;
一旦配置类生效,这个配置类就会给容器中添加各种组件;
这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
Spring Boot精髓:
8.2细节
1)@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效