创建SpringBoot项目
- 一、快速创建SpringBoot项目
- 二、 SpringBoot概念及其特点
- 三、SpringBoot--starters
- 四、常用注解
- 五、附录
一、快速创建SpringBoot项目
1. 前提条件
jdk 1.8 版本及以上,Maven 3.3 版本及以上(记得Maven要配置Setting文件,集成环境也要进行相关配置)【见文档:Maven了解与使用】
IntelliJ IDEA 自带 Spring Initializer 工具。可直接新建Spring Boot项目。
Eclipse需要下载STS插件,才可快速创建SpringBoot项目。
2. 创建SpringBoot项目
下面的几个过程都要保证在联网状态。首次使用,会把相关包放置在本地仓库,需等待下载完成。
IntelliJ IDEA 新建SpringBoot项目教程:见链接:inteliJ IDEA 安装与使用
下面展示Eclipse新建SpringBoot项目流程。
3. 目录结构讲解
- DemoApplication:主程序类
- resources/static:保存所有的静态资源,js、css、images等
- resources/templates:保存所有的模板页面。Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面,可以使用模板引擎(freemarker、thymeleaf)。
- application.properties:Spring Boot应用的配置文件。如端口配置:server.port=8081
4. 自动生成的 pom.xml 及 主程序
<!-- 自动生成的 pom.xml 文件 -->
<!-- 各个标签的含义,请看Maven,都是Maven的知识点 -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
// 自动生成的主程序类,程序启动入口
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // 核心注解,必须标记
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
5. 生成jar包
将项目打包,其实就是maven package命令(也常用 maven install)。
IntelliJ IDEA 打包
Eclipse 打包
注:生成的jar包也会在target中显式
二、 SpringBoot概念及其特点
SpringBoot是基于Spring4.0版本开发的框架,SpringBoot是J2EE 一站式解决方案;SpringCloud是分布式整体解决方案
SpringBoot 特点:
- 快速创建独立运行的Spring项目以及与主流框架集成
- 使用嵌入式的Servlet容器,应用无需打成WAR包
- starters自动依赖与版本控制
- 大量的自动配置,简化开发,也可修改默认值
- 无需配置XML,无代码生成,开箱即用
- 准生产环境的运行时应用监控
- 与云计算的天然集成
三、SpringBoot–starters
SpringBoot 优势之一就是整合了开发项目过程中各种依赖包的版本及其相互依赖关系,使我们不必操心依赖包之间的版本兼容问题。
正如上面pom.xml中spring-boot-starter-web 一样,在Springboot官网文档给出了全部 Springboot-starters。官方网站请点击,Starts整理见下:(描述是直译的,不需要特别记)
在使用的时候,只需将下面相关starter 放在artifactId标签中即可。(推荐使用集成工具进行添加依赖,不要手输)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>...starter...</artifactId>
</dependency>
starters | 描述 |
---|---|
spring-boot-starter | 核心starter,包括自动配置,日志和Yaml |
spring-boot-starter-activemq | Apache ActiveMQ的JMS消息传递 |
spring-boot-starter-actuator | 提供了生产就绪功能,可帮助您监视和管理应用程序 |
spring-boot-starter-amqp | Spring AMQP和Rabbit MQ |
spring-boot-starter-aop | Spring AOP和AspectJ进行面向方向编程 |
spring-boot-starter-artemis | Apache Artemis的JMS消息传递 |
spring-boot-starter-batch | Spring Batch |
spring-boot-starter-cache | Spring Framework的缓存支持 |
spring-boot-starter-data-cassandra | Cassandra分布式数据库和Spring Data Cassandra |
spring-boot-starter-data-cassandra-reactive | Cassandra分布式数据库和Spring Data Cassandra Reactive |
spring-boot-starter-data-elasticsearch | Elasticsearch搜索和分析引擎以及Spring Data Elasticsearch |
spring-boot-starter-data-jdbc | Spring Data JDBC |
spring-boot-starter-data-jpa | Spring Data JPA与Hibernate |
spring-boot-starter-data-ldap | Spring Data LDAP |
spring-boot-starter-data-mongodb | MongoDB面向文档的数据库和Spring Data MongoDB |
spring-boot-starter-data-mongodb-reactive | MongoDB面向文档的数据库和Spring Data MongoDB Reactive |
spring-boot-starter-data-neo4j | Neo4j图形数据库和Spring Data Neo4j |
spring-boot-starter-data-r2dbc | Spring Data R2DBC |
spring-boot-starter-data-redis | Redis键值数据存储与Spring Data Redis和Lettuce客户端 |
spring-boot-starter-data-redis-reactive | Redis键值数据存储与Spring Data Redis Reacting和Lettuce客户端一起使用 |
spring-boot-starter-data-rest | Spring Data REST在REST上公开Spring数据存储库 |
spring-boot-starter-data-solr | Apache Solr搜索平台与Spring Data Solr结合,2.3.9版开始不推荐使用 |
spring-boot-starter-freemarker | FreeMarker视图构建MVC Web应用程序 |
spring-boot-starter-groovy-templates | Groovy模板视图构建MVC Web应用程序 |
spring-boot-starter-hateoas | Spring MVC和Spring HATEOAS构建基于超媒体的RESTful Web应用程序 |
spring-boot-starter-integration | 使用JDBC和HikariCP连接池 |
spring-boot-starter-jersey | JAX-RS和Jersey构建RESTful Web应用程序,替代者:spring-boot-starter-web |
spring-boot-starter-jooq | jOOQ访问SQL数据库,替代者:spring-boot-starter-data-jpa和spring-boot-starter-jdbc |
spring-boot-starter-jetty | Jetty作为嵌入式servlet容器的入门者,替代者:spring-boot-starter-tomcat |
spring-boot-starter-json | JSON入门 |
spring-boot-starter-jta-atomikos | Atomikos的JTA交易 |
spring-boot-starter-jta-bitronix | Bitronix的JTA交易。从2.3.0版本开始不推荐使用 |
spring-boot-starter-log4j2 | Log4j2进行日志记录的启动器,替代者:spring-boot-starter-logging |
spring-boot-starter-logging | 使用Logback进行日志记录的启动器。默认记录启动器 |
spring-boot-starter-mail | Java Mail和Spring Framework的电子邮件发送支持 |
spring-boot-starter-mustache | Mustache视图构建Web应用程序 |
spring-boot-starter-oauth2-client | Spring Security的OAuth2 / OpenID Connect客户端功能 |
spring-boot-starter-oauth2-resource-server | Spring Security的OAuth2资源服务器功能 |
spring-boot-starter-quartz | 使用Quartz Scheduler |
spring-boot-starter-reactor-netty | 将Reactor Netty用作嵌入式反应式HTTP服务器 |
spring-boot-starter-rsocket | 构建RSocket客户端和服务器 |
spring-boot-starter-security | Spring Security |
spring-boot-starter-test | 包括JUnit Jupiter,Hamcrest和Mockito在内的库测试Spring Boot应用程序 |
spring-boot-starter-thymeleaf | Thymeleaf视图构建MVC Web应用程序 |
spring-boot-starter-tomcat | 将Tomcat用作嵌入式servlet容器 |
spring-boot-starter-undertow | Undertow作为嵌入式servlet容器 |
spring-boot-starter-validation | 将Java Bean验证与Hibernate Validator结合 |
spring-boot-starter-web | Spring MVC构建Web(包括RESTful)应用程序,Tomcat为默认的嵌入式容器 |
spring-boot-starter-web-services | Spring Web Services |
spring-boot-starter-webflux | Spring Framework的反应式Web支持构建WebFlux应用程序 |
spring-boot-starter-websocket | Spring Framework的WebSocket支持构建WebSocket应用程序 |
四、常用注解
从此处开始使用IDEA集成工具,相关截图也是IDEA的截图。首次学习SpringBoot,看到第6小节即可,剩余小节的注解需要其他知识支撑,我在其他篇幅也会进行介绍。
1. 必备注解
在Web开发过程中,将系统开发分成几个层次。
// 标注在类前(public class)
@Controller // 控制层,负责接受前端信息,并返回前端页面
@Service // 业务逻辑层,负责实现代码逻辑
@Repository // 数据库层(也被叫做Dao层),负责与数据库数据进行交互
@Component // 组件,当不好区分时用此标记,常标注于Bean类前(Bean类,只有属性及相关访问器和更改器,一般与数据库表的字段一一对应)
2. @RequestMapping(@PathVariable搭配)
@RequestMapping 被用来处理请求地址映射,可标注于类或方法前。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解可以搭配六种属性。
// value属性:指定请求的实际地址。
// 1. 不加任何属性,相当于赋值给value
@RequestMapping("/hello")
@RequestMapping(value="/hello")
// 2. 可以指定多个值,用{..} 包裹,逗号(,)分隔
@RequestMapping({"/hello","/wo"})
@RequestMapping(value = {"/hello","/wo"})
// 3. 可以接受变量,@PathVariable 注解接收变量
@RequestMapping(value ="/hello/{id}")
public String test(@PathVariable String id){
......
}
// 4. 可以接受正则表达式,@PathVariable 注解接收变量,'\'要加转义'\\'
@RequestMapping(value ="/hello/{version:\\d*}")
public String test(@PathVariable String version){
......
}
附:正则表达式语法。下面属性使用时,都应指定value属性。
// method属性:指定请求方法类型,如:GET、POST、PUT、DELETE等
@RequestMapping(method = RequestMethod.GET)
@RequestMapping(method = RequestMethod.POST)
@RequestMapping(method = RequestMethod.PUT)
@RequestMapping(method = RequestMethod.DELETE)
// consumes属性:指定处理请求的提交内容类型,如: application/json, text/html
@RequestMapping(consumes = "application/json")
@RequestMapping(consumes = "text/html")
// produces属性:指定返回的内容类型,但仅当request请求头中的(Accept)类型中包含该指定类型才返回
@RequestMapping(produces= "application/json")
// params属性:指定request中必须包含某些参数值时,才让该方法处理
// 1. 指定参数
// 例:浏览器访问:http://localhost:8080/hello?myParam=myValue
@RequestMapping(params= "myParam=myValue")
// 2. 指定多个参数
// 例:浏览器访问:http://localhost:8080/hello?myParam=myValue&nihao=nihao
@RequestMapping(params= {"myParam=myValue","nihao=nihao"})
// 3. 指定参数,不指定值
// 例:浏览器访问:http://localhost:8080/hello?myParam=xxx&nihao=nihao
@RequestMapping(params= {"myParam","nihao=nihao"})
// headers属性:指定request中必须包含某些指定的header值,才能让该方法处理请求。
// 用法与params 类似,1. 指定单个参数
@RequestMapping(headers = "Host=localhost:8080")
// 2. 指定多个参数
@RequestMapping(headers = {"Host=localhost:8080","Accept= text/html"})
// 3. 指定参数,不指定值
@RequestMapping(headers = {"Host","Accept= text/html"})
附:请求头
// 举例,多个属性使用,逗号(,)分隔
@RequestMapping(value ="/hello",method= RequestMethod.GET,params= {"myParam","nihao=nihao"})
3. @RequestParam
@RequestParam对请求参数进行控制,有三个属性,可选择性使用
// @RequestParam 定义在方法参数前
// value: 请求参数名称
// required: 是否必须,默认为true,表示请求参数中必须包含对应的参数,否则抛出异常
// defaultValue: 当请求参数缺少或者有请求参数但值为空时,值采用该设置值
public String test(@RequestParam(value = "age",required = false,defaultValue = "18") int age){
......
}
4. @ResponseBody
@ResponseBody被用来处理响应对象(响应以json方式返回至前台页面),可用于类或方法上。用于类上,表示类中所有方法的响应都是json方式。
5. @Autowired 和 @Resource
5.1 @Autowired
@Autowired 对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
@Autowired只有一个属性required,默认值为true,为true时,找不到就抛异常,为false时,找不到就赋值为null
// 在类成员变量前标注(用的最多,但官方不推荐,IDEA 会提示不推荐使用的标志)
@Autowired
private HelloService helloService;
// 构造方法前使用(可将字段声明为final,那样类实例化期间就会被初始化)
private final HelloService helloService;
@Autowired //(可省略,但当类中有多个构造器,就不能省略了)
public HelloController(HelloService helloService) {
this.helloService = helloService;
}
// set方法前使用(当使用无参数构造函数或无参数静态工厂方法实例化Bean时,为了注入Bean的依赖项,Spring容器将调用这些setter方法)
private HelloService helloService;
@Autowired //(可省略)
public void setHelloService(HelloService helloService) {
this.helloService = helloService;
}
对于必需的依赖,建议使用基于构造函数注入,设置它们为不可变的,并防止它们为null。对于可选的依赖项,建议使用基于set注入。
5.2 @Resource
@Resource有两个常用属性name、type,所以分4种情况:
- 指定name和type:通过name找到唯一的bean,找不到抛出异常;如果type和字段类型不一致,也会抛出异常;
- 指定name:通过name找到唯一的bean,找不到抛出异常;
- 指定type:通过tpye找到唯一的bean,如果不唯一,则抛出异常;
- 都不指定:通过字段名作为key去查找,找到则赋值;找不到则再通过字段类型去查找,如果不唯一,则抛出异常。
@Resource(name="helloService",type = HelloService.class)
private HelloService helloService;
5.3 两者区别
相同点:
- @Resource和@Autowired注解都是用来实现依赖注入的
- Spring都支持
- 都可以作用在字段和setter方法上
不同点:
- @Resource是JDK提供的,而@Autowired是Spring提供的
- @Resource不允许找不到bean的情况,而@Autowired允许
【@Autowired(required = false)】 - @Resource默认通过name查找,而@Autowired通过type查找
- 指定name的方式不一样:@Resource直接用,@Autowired需要搭配@Qualifier
// @Resource 指定name
@Resource(name = "helloService");
// @Autowired指定name
@Autowired
@Qualifier("baseDao")
6. @RestController
标注在类前,表示类中方法全部适用。可理解为@Controller和 @ResponseBody 的组合。
7. @ConfigurationProperties 和 @Value
7.1 @ConfigurationProperties
在指定bean上加注解,功能是将配置文件(application.properties | application.yml)中的配置项,映射至bean中。
// 在JavaBean 类上加注解,必须有spring-boot-configuration-processor 依赖和 @Component注解
// 常用 3 个属性
// prefix:前缀
// ignoreInvalidFields : 忽略不合法的属性(值类型不匹配)
// ignoreUnknownFields : 忽略不知道的属性
@Component
@ConfigurationProperties(prefix = "person")
public class PersonEntity {
private String name;
private int age;
// ... 省略set、get、toString方法
}
# application.properties 文件
person.name=zhangwei
person.age=25
7.2 @Value(@PropertySource搭配)
// 标注在域前
@Component
@PropertySource(value = "classpath:application.properties")
public class HelloEntity {
@Value("normal")
private String normal; // 注入普通字符串
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName; // 注入操作系统属性
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double randomNumber; //注入表达式结果
@Value("#{worldEntity.name}")
private String name; // 注入其他Bean属性,要求必须有访问器方法
@Value("classpath:config.txt") // classpath: 指代src/main/resources 路径
private Resource resourceFile; // 注入文件资源,注:Resource是在org.springframework.core.io.Resource 包下,不要导错类;
@Value("http://www.baidu.com")
private Resource testUrl; // 注入URL资源
@Value("${version}")
private String version; // 注入配置文件,需要搭配@PropertySource注解使用
@SneakyThrows // 该注解表示方法有受查异常抛出
@Override
public String toString() {
return "HelloEntity{" +
"normal='" + normal + '\'' +
", systemPropertiesName='" + systemPropertiesName + '\'' +
", randomNumber=" + randomNumber +
", name='" + name + '\'' +
", resourceFile=" + resourceFile.getFile().exists() +
", testUrl=" + testUrl +
", version=" + version +
'}';
}
}
下面是Hello输入结果:
HelloEntity{normal='normal',
systemPropertiesName='Windows 10',
randomNumber=95.78477140483602,
name='bean name',
resourceFile=true,
testUrl=URL [http://www.baidu.com],
version=1
}
为了方便理解:用到的其他配置情况如下
@Value 还需要注意一点:
@Value("#{}") // 从java代码中读取值
@Value("${}") // 从配置文件中读取值
7.3 两者区别
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 需专门指定 |
松散绑定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
解释:见第五部分
8. @PropertySource
一般与@Value搭配使用,之前默认只能读取properites和xml文件,但现在也能读取其他文件,其他文件会以流的形式加载到properites中。
9. @ImportResource
导入Spring配置文件,主要是xml文件。标注在主程序类前。
@ImportResource(locations = "classpath:aaa.xml") // 项目推荐全注解,不要使用xml
@SpringBootApplication
public class SpringoneApplication {
public static void main(String[] args) {
SpringApplication.run(SpringoneApplication.class, args);
}
}
10. @Configuration
标注在类前,表示当前类为配置类。在该类中可使用@Bean标注于方法上,会将返回值会加载至容器中。
11. @Conditional 条件注解
当@Conditional指定的条件成立,才给容器中添加注解,配置里面的内容才生效。
@Conditional扩展注解 | 作用(判断是否满足当前指定条件) |
---|---|
@ConditionalOnJava | 系统的java版本是否符合要求 |
@ConditionalOnBean | 容器中存在指定Bean; |
@ConditionalOnMissingBean | 容器中不存在指定Bean; |
@ConditionalOnExpression | 满足SpEL表达式指定 |
@ConditionalOnClass | 系统中有指定的类 |
@ConditionalOnMissingClass | 系统中没有指定的类 |
@ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean |
@ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径下是否存在指定资源文件 |
@ConditionalOnWebApplication | 当前是web环境 |
@ConditionalOnNotWebApplication | 当前不是web环境 |
@ConditionalOnJndi | JNDI存在指定项 |
五、附录
1. 松散绑定
// 标准方式
person.firstName
// 不标准方式
person.first-name //中划线(-)
person.first_name //下划线(_)
PERSON_FIRST_NAME //大写加下划线
2. SpEL
SpEL(Spring Expression Language),即Spring表达式语言
。常用于@Value,下面介绍一些SpEL的基础用法。参考文档
// 1. 字面量,字面量赋值要和对应的属性类型兼容,否则报异常
#{"123"}
// 2. 运算符。算术运算符:+,-,*,/,%,^;
// 字符串连接符:+;
// 比较运算符:<,>,==,<=,>=,lt,gt,eq,le,ge
// 逻辑运算符:and,or,not,&&,||,!
// 三目运算符:?true:false
// 正则表达式:matches
#{user.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}'}
// 3. 调用静态方法或静态属性:T() ;T(...) 将返回指定类的一个对象,接下来调用相应属性或方法就行
#{T(java.lang.Math).PI}
3. JSR303数据校验
要使用JSR303数据校验,需引入依赖:validation。将注解标记在域前即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
注解 | 解释 |
---|---|
@Null | 限制必须为 null |
@NotNull | 限制必须不为null |
@AssertFalse | 限制必须为false |
@AssertTrue | 限制必须为true |
@DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
@DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
@Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Future | 限制必须是一个将来的日期 |
@Max(value) | 限制必须为一个不大于指定值的数字 |
@Min(value) | 限制必须为一个不小于指定值的数字 |
@Past | 限制必须是一个过去的日期 |
@Pattern(value) | 限制必须符合指定的正则表达式 |
@Size(max,min) | 限制字符长度必须在min到max之间 |
@Past | 验证注解的元素值(日期类型)比当前时间早 |
@NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 | |
@Size(min=, max=) | 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内 |
@Length(min=, max=) | 验证字符串是否在最小值和最大值之间。 |