高科技上网的小伙伴应该很容易就可以搭建springboot项目,就像我,但是国内的没有科学上网的小伙伴如何搭建项目呢?

https://spring.io/projects/spring-boot 这个是springboot的官网,这个里面会有很多你想知道的东西,但是自己读懂不是很容易

创建项目

利用官方提供的初始化

在官网页面你会找到这个页面,如下图

aM21aD

点进去后发现:

aM23Ie

没错,这就是一个自带的初始化工具,最终会生成一个压缩包,下载了之后跟你用idea生成的初始化项目一样

利用工具初始化

aM2lVO

下面的是让你选择初始化的依赖,这个可以什么都不选

aM2MqK.png

https://start.aliyun.com/ 阿里云真挺好,用了这个创建项目,就是看你国内网ok不ok了,但是如果你用default,那你一定是个科学上网者

手动创建项目

如果你对项目足够了解的话,你就知道了,springboot项目其实可以自己手动创建

我们首先需要了解springboot项目最重要的两个配置文件,和一个自带启动类:

不论是自动创建还是手动创建,都是要有这些配置文件的,你迟早都要熟悉他们,只是我放在这里方便一些只想自己动手创建项目的人,帮助理解

pom.xml(父工程):

用官方的初始化之后,看他的pom配置中自带了一个 引入父工程

1
2
3
4
5
6
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

就是它自带的这个,帮我们管理了繁琐的版本控制,依赖兼容的问题,按住ctrl 左键 点击 spring-boot-starter-parent,然后看到他的父依赖,可以知道他到底干了多少好事,直接让我们从 gav 变成ga,这个是我们手动创建springboot项目的关键角色

dependencies中的原本一个依赖多一个功能,现在是以一当十,比如这个:

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

看着只是一个依赖,但是这个里面已经为我们封装了web项目所需要的所有依赖了

application.properties:

这里面需要配置的最重要的是关于链接服务器数据库的,而且强制你配置,否则报错,所以必须要有 ,并且当项目启动后读取配置的时候,会寻找两个配置文件,其中一个是这个,另一个就是application.yml,但是个人推荐properties的,这个如果你配置正确,就会有代码提示。yml有自己的语法结构 ,常用配置文件只有两个,application.properties、application.yml 这两个文件只是格式有差别,如果同时存在,但是配置中并无冲突,则它们一起生效

application.yml(可有可无):

这个配置文件属于一种公共规范,而不是像properties那种spring项目独有的

编写规则:

1、使用key:(空格)value表示键和值,注意冒号右边必须有空格。

  • value不论什么类型不需要加引号,直接写,都默认解析为字符

  • 如果value值中有特殊表达式需要解析(\t \n …),就加双引号,单引号不会解析这些表达式,会原样输出:

    1
    2
    3
    testKey1: "ls\t学院"  # ls  学院
    testKey2: 'ls\t学院' # ls\t学院
    testKey3: ls\t学院 # ls\t学院

2、大小写敏感,但基本都是全小写

例如: name 和 Name 是表示两个不同的属性值

1
2
name: ls
Name: hhh

3、使用空格Space 缩进对齐表示分层

不同层次之间的缩进可以使用不同数目的空格,(不能使用 Tab,各个系统 Tab对应的 Space 数目可能不同,导致层次混乱),第二个层次的前面两个空格即可

1
2
server:
port:8081

数据结构:

properties和YML文件中保存的数据都是键值对结构,但是根据不同的写法,可以表示出不同类型的数据:

普通键值对
1
2
3
4
5
6
7
# 普通键值对
clazz: 大数据
houseNumber: 202
# 多层级属性,相当于province.city.area=shuyang
province:
city:
area: shuyang
对象类型
1
2
3
4
5
6
7
8
9
# 对象类型
user:
username: tom
age: 12
birthday: 1997-10-10
isVip: true

# 对象行内写法
person: {pname: tom,age: 22, birthday: 1997-10-10 }
数组和集合类型
1
2
3
4
5
6
7
8
9
10
11
12
# 数组 list set写法一致
valueList:
- MyBatis
- SpringMVC
- SpringBoot

ageArray:
- 18
- 20
- 22
# 数组 list set行内写法
inlineNum: [1,2,3]

@Value取值

在类属性上使用@value(“${key}”)获取配置,获取方式分为2种:

  1. 键值对(普通属性/map/对象)都是通过key取值
  2. 数组、list、set,取值都是通过索取值[0]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@SpringBootTest
class Springboot01Tests {

@Value("${clazz}")
private String clazzs; //相当于 private String clazzs = "clazz" 所以这种方法不会经常使用

@Value("${houseNumber}")
private Integer num;

@Value("${province.city.area}")
private String address;

//注意这里需要使用字符串接收,如果要转Date类型可以自己转
@Value("${user.birthday}")
private String birthday;

@Value("${person.age}")
private Integer age;

@Value("${valueList[1]}")
private String subject;

@Value("${userList[1].age}")
private Integer listMapAge;

@Test
void contextLoads() {
System.out.println("clazz = "+clazzs);
System.out.println("houseNumber = "+num);
System.out.println("province.city.area = "+address);
System.out.println("user.birthday = "+birthday);
System.out.println("person.age = "+age);
System.out.println("valueList[1] = "+subject);
System.out.println("userList[1].age = "+listMapAge);
}

}
  • @Value特殊用法

${} 从字面量、环境变量取值、支持 #{spEL} 表达式语法(就是spring的 el表达式,这个比jsp的强一百倍)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.czxy.springboot;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class ValueTest {

//字面量
@Value("hello")
private String strValue;

//${} 配置文件中没有该属性值就从环境变量中获取
@Value("${Path}")
private String pathValue;

//#{SpEL}表达式
@Value("#{10+10}")
private String spValue_1;

//#{SpEL}表达式
@Value("#{'HelloWorld'.toLowerCase()}")
private String spValue_2;

@Test
public void testSpEL(){
System.out.println("strValue = "+strValue);
System.out.println("pathValue = "+pathValue);
System.out.println("spValue_1 = "+spValue_1);
System.out.println("spValue_2 = "+spValue_2);
}
}

@ConfigurationProperties

该注解支持将多个配置属性一次读取到实体类中

1、添加配置处理器依赖

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

这个依赖会让你的yml有自动提示功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
1
2
3
4
5
6
7
8
9
10
11
config-properties:
value: this is config properties #对应单个键值对
valueMap: #对应map
name: lily
age: 18
sex: girl
valueArray: [1,2,3,4] #对应数组/list/set(行内写法)
value-list: #对应数组/list/set
- SpringBoot
- SpringMVC
- MyBatis

2、编写配置类

1
2
3
4
5
6
7
8
9
10
@Component
@ConfigurationProperties(prefix = "config-properties")
public class Config {
private String value;
private String[] valueArray;
private List<String> valueList;
private HashMap<String, String> valueMap;

//get set toString()
}

上面的方法@ConfigurationProperties的prefix 会直接 将配置文件中config-properties部分下面所有的属性和类中的属性进行绑定,全部封装到Config实体类中,@Component可以将这个项目提交给spring容器管理,使用的时候可以直接注入

3、测试

1
2
3
4
5
6
7
8
9
10
11
@SpringBootTest
public class ConfigPropertiesTest {

@Autowired
ConfigProperties config;

@Test
public void test(){
System.out.println(config);
}
}

@ConfigurationProperties注解支持配置文件中属性名称的松散写法:valueList 和value-list都能和类中的属性valueList绑定。

但是@Value注解不支持这种松散写法,类中的属性和配置文件中的属性必须一致

@PropertySource:

假如你非要自己定义一个配置文件存放重要数据呢?这里演示的是用properties文件储存yaml格式转换后的内容,其实properties格式就是将yml的格式改为 . 的方式

读取自定义properties

在resource目录下新建config-dev.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#对应单个键值对
config-properties.value = this is config properties

#对应map
config-properties.valueMap.name = lily
config-properties.valueMap.age = 18
config-properties.valueMap.sex = girl

#对应数组/list/set(行内写法)
config-properties.value-array = [1,2,3,4]

#对应数组/list/set
config-properties.valueList[0] = SpringBoot
config-properties.valueList[1] = SpringMVC
config-properties.valueList[2] = MyBatis
config-properties.valueListMap[0].name = tom
config-properties.valueListMap[0].age = 22
config-properties.valueListMap[1].name = Jack
config-properties.valueListMap[1].age = 20

# list<User>
config-properties.users[0].username = zhangsan
config-properties.users[0].salary = 13000.1
config-properties.users[1].username = lisi
config-properties.users[1].salary = 15000.2

修改配置类,添加@PropertySource

1
2
3
4
5
6
@Component
@ConfigurationProperties(prefix = "config-properties")
@PropertySource("classpath:config-dev.properties")
public class ConfigProperties {
//...
}

运行测试方法:

1
2
3
4
5
6
7
8
9
10
11
@SpringBootTest
public class ConfigPropertiesTest {

@Autowired
ConfigProperties config;

@Test
public void test(){
System.out.println(config);
}
}

运行测试类必须要在test文件夹下的绿色java文件夹下进行

注意不要忘记springboottest注解,否则报错

读取自定义 yml文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 用于 @PropertySource 加载 yml 配置文件
*/
public class PropertySourceFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name,
EncodedResource resource) throws IOException {
if (resource == null) {
return super.createPropertySource(name, resource);
}
//使用yml资源加载器加载yml配置
List<PropertySource<?>> sources = new YamlPropertySourceLoader().
load(resource.getResource().getFilename(), resource.getResource());
return sources.get(0);
}
}

使用自定义的yml读取

1
2
3
4
5
6
7
@Component
@ConfigurationProperties(prefix = "config-properties")
@PropertySource(value = "classpath:config-prop.yml",
factory = com.czxy.springboot.config.PropertySourceFactory.class)
public class ConfigProperties {
//...
}

多了个factory锁定工厂

yml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
config-properties:
value: this is config properties #对应单个键值对
valueMap: #对应map
name: lily
age: 18
sex: girl
value-array: [1,2,3,4] #对应数组/list/set(行内写法)
value-list: #对应数组/list/set
- SpringBoot
- SpringMVC
- MyBatis
value-list-map:
- name: tom
age: 22
- name: Jack
age: 20
users:
- username: zhangsan
salary: 13000.1
- username: lisi
salary: 15000.2

测试方法:

1
2
3
4
5
6
7
8
9
10
@SpringBootTest
public class ConfigPropertiesTest {
@Autowired
ConfigProperties config;

@Test
public void test(){
System.out.println(config);
}
}
@PropertySource 功能扩展
导入多个配置文件
1
@PropertySource(value= {"classpath:emp-dev.properties","classpath:emp-test.properties"})
是否忽略不存在的文件
1
@PropertySource(value= {"classpath:emp-dev.properties","classpath:emp-test.properties"},ignoreResourceNotFound = true)
指定打开属性文件的编码

指定读取属性文件所使用的编码,默认没有配置,安装项目环境编码读取属性文件。可以不设置或设置为UTF-8

1
2
3
@PropertySource(value= {"classpath:emp-dev.properties","classpath:emp-test.properties"},
ignoreResourceNotFound = true,
encoding = "utf-8")
配置文件生效优先级

SpringBoot默认会扫描以下位置的application.properties application.yml作为SpringBoot的默认配置,但是他们并不一定会生效,这取决于他们的优先程度

1、file:./config/:项目jar包所在目录的config目录(就是你的jar包你爱放哪放哪,但是如果它旁边恰巧有个文件夹叫config文件夹,而里面又恰好有 配置文件,那他就是你真正的配置文件)

2、file:./ :项目jar包所在的同级目录(还是你的jar包你爱放哪放哪,不过这次直接放一个配置文件在你的 jar包旁边,这个比上面要次一等)

3、classpath:/config:classpath(resource)目录下config目录(也就是你未打包的项目中的resources目录下创建config文件夹,然后文件夹里有个配置文件的话)

4、classpath:/:classpath(resource)目录下(也就是我们默认的application.properties)(这就是我们最普通的配置文件了,只要你创建项目就会自带给你的,但其实优先度最低)

优先度: 1 > 2 > 3 > 4

config目录中的配置优先级高于外部配置

使用场景就是当你的jar包已经打好了,但是你有些配置想要修改,所以这个时候很尴尬,你不能更加麻烦的拆开jar包,或者是重新打包,都很繁琐,所以这个时候,你可以在jar包的 同级目录下创建一个application.properties 文件,重新书写的你的配置,或者在jar包的同级目录下创建一个config文件夹,这里面存放 application.properties 文件

springbootapplication:

启动器,添加一个注解和一个方法,即可直接启动spring项目,并且这个启动器,启动之后,会直接调用内置tomcat,要注意的是,启动器必须位于controller包的父包下,也会是必须与controller位于同一层级

在我们搞懂了这些东西之后,就可以通过一个maven项目,然后自己diy成一个springboot项目了

1、创建maven项目,不需要选择任何模板

2、创建完成之后,选择好idea的右下角弹窗的第二个选项,让他自动导报

3、导入pom中你的依赖,也就是springboot依赖

4、看看有没有 resources和java文件夹并且是资源路径,没有就创建

5、在resources下创建application.properties文件,并且顺便写入配置信息

6、在项目目录下创建各种文件夹,(controller、service、dao、domain等)

7、controller文件夹下创建springboot实体类

这个过程按照我上面说的来就肯定可以实现,不演示了

项目创建完成后:

一些看似没有用的东西:

.gitignore

分布式版本控制系统git的配置文件,意思为忽略提交,使用git开发时需要保留。目前没有用到git,可以选择删除,让
在 .gitingore 文件中,遵循相应的语法,即在每一行指定一个忽略规则。 如:.log、/target/、.idea

mvnw:全名是maven wrapper
它的作用是在maven-wrapper.properties文件中记录你要使用的maven版本,当用户执行mvnw clean 命令时,发现当前用户的maven版本和期望的版本不一致,那么就下载期望的版本,然后用期望的版本来执行mvn命令,比如mvn clean命令。我们使用的本地Maven版本不会变,因此删除相关文件。

mvn.cmd:执行mvnw命令的cmd入口
*注:mvnw文件适用于Linux(bash),mvnw.cmd适用于Windows 环境。

HELP.md

获取帮助文档的相关信息

.iml文件:intellij idea的工程配置文件,不能删除
里面包含当前project的一些配置信息,如模块开发的相关信息,比如java组件,maven组件,插件组件等,还可能会存储一些模块路径信息,依赖信息以及一些别的信息。

小案例

application.properties

1
2
3
4
5
6
7
# 应用服务 WEB 访问端口
server.port=8080
# Actuator Web 访问端口
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/test

不配置报错

pom:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.0.RELEASE</spring-boot.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<!--简化项目部署-->
<!--将项目打成一个可执行jar包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

我们以前用的springmvc打包方式,都是idea将我们的项目打包好了之后发送到tomcat下面进行部署的,但是现在我们有了springboot这个jar包之后,就可以对我们的项目直接打包到内置的tomcat下面运行,用springboot生成的项目可以直接运行在部署好了java开发环境的服务器中,当然是作为一个项目运行,这个是 build下面的插件的作用 运行方式 java -jar 项目jar包名字

controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.ls.springbootp02.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController //相当于@Controller + @ResponseBody
public class HtlloController {

@GetMapping("/get01")
public String hello01(@RequestParam(value = "name", defaultValue = "yom") String name) {
return String.format("nihao %s!", name);
}

}

启动器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.ls.springbootp02;

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

@SpringBootApplication
public class Springbootp02Application {

public static void main(String[] args) {
SpringApplication.run(Springbootp02Application.class, args);
}

}

启动器一般项目初始化会准备好,所以不需要你来写,但是我还是选择贴出来,我的项目结构

aM2Kr6.png

springboot注解理解帮助

springboot启动器注解继承了三个注解

1
2
3
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

@SpringBootConfiguration

这个注解 继承了 @Configuration ,有关@Configuration:

案例

1
2
3
4
5
6
7
8
9
@Bean
public UserFactory userFactory(){
UserFactory userFactory = new UserFactory();
return userFactory;
}


@Autowired
UserFactory userFactory;

@EnableAutoConfiguration

1
2
3
4
5
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
//...
}
  • @AutoConfigurationPackage :将添加该注解的类所在的package,作为 自动配置package进行管理。
  • @Import({AutoConfigurationImportSelector.class}):确定引入哪些配置

@ComponentScan

这个注解是组件扫描,扫描指定的包下的类,并加载符合条件的组件。这个是我们最熟悉的注解,在spring的配置文件中使用过<context:component-scan base-package="com.xxx.xxx"/>