SpringBoot学习笔记(1)—注解的使用
是整个Spring技术栈的一个整合,简化了其应用。其关系可以形象地表示为:
伴随Spring4.0版本发布,其团队发布了SpringBoot框架,just run就能创建一个独立的产品级别的应用,用户基本上可以零配置;starters可以自动进行版本控制。
推荐最低环境准备:
jdk1.8
maven 3.x
IntelliJIDEA2017
Spring 1.5
或者使用STS集成环境
2.helloWord项目
一个功能:
浏览器发送hello请求,服务器接受请求并处理,响应为HelloWord字符串
2.1 创建maven项目
#### 2.1.1 导入SpringBoot相关依赖
maven项目自动生成的pom.xml如下:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>demo03</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
接下来加入springboot相关依赖:
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Idea会自动下载所需的依赖,(settings.xml决定了镜像来源)
2.2 POM文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
点击父项目spring-boot-starter-parent进去,可以看到,
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.3.RELEASE</version>
</parent>
点击父项目spring-boot-dependencies进入,可以看到:
<properties>
<activemq.version>5.15.13</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.81</appengine-sdk.version>
<artemis.version>2.12.0</artemis.version>
<aspectj.version>1.9.6</aspectj.version>
<assertj.version>3.16.1</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
<awaitility.version>4.0.3</awaitility.version>
<bitronix.version>2.1.4</bitronix.version>
<build-helper-maven-plugin.version>3.1.0</build-helper-maven-plugin.version>
<byte-buddy.version>1.10.14</byte-buddy.version>
<caffeine.version>2.8.5</caffeine.version>
<cassandra-driver.version>4.6.1</cassandra-driver.version>
<classmate.version>1.5.1</classmate.version>
<commons-codec.version>1.14</commons-codec.version>
<commons-dbcp2.version>2.7.0</commons-dbcp2.version>
<commons-lang3.version>3.10</commons-lang3.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-pool2.version>2.8.1</commons-pool2.version>
<couchbase-client.version>3.0.7</couchbase-client.version>
<db2-jdbc.version>11.5.4.0</db2-jdbc.version>
<dependency-management-plugin.version>1.0.10.RELEASE</dependency-management-plugin.version>
<derby.version>10.14.2.0</derby.version>
<dropwizard-metrics.version>4.1.12.1</dropwizard-metrics.version>
<ehcache.version>2.10.6</ehcache.version>
<ehcache3.version>3.8.1</ehcache3.version>
<elasticsearch.version>7.6.2</elasticsearch.version>
<embedded-mongo.version>2.2.0</embedded-mongo.version>
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
<flatten-maven-plugin.version>1.2.4</flatten-maven-plugin.version>
<flyway.version>6.4.4</flyway.version>
<freemarker.version>2.3.30</freemarker.version>
<git-commit-id-plugin.version>3.0.1</git-commit-id-plugin.version>
<glassfish-el.version>3.0.3</glassfish-el.version>
<glassfish-jaxb.version>2.3.3</glassfish-jaxb.version>
<groovy.version>2.5.13</groovy.version>
<gson.version>2.8.6</gson.version>
<h2.version>1.4.200</h2.version>
<hamcrest.version>2.2</hamcrest.version>
<hazelcast.version>3.12.8</hazelcast.version>
<hazelcast-hibernate5.version>1.3.2</hazelcast-hibernate5.version>
<hibernate.version>5.4.20.Final</hibernate.version>
<hibernate-validator.version>6.1.5.Final</hibernate-validator.version>
<hikaricp.version>3.4.5</hikaricp.version>
<hsqldb.version>2.5.1</hsqldb.version>
<htmlunit.version>2.40.0</htmlunit.version>
<httpasyncclient.version>4.1.4</httpasyncclient.version>
<httpclient.version>4.5.12</httpclient.version>
<httpcore.version>4.4.13</httpcore.version>
<infinispan.version>10.1.8.Final</infinispan.version>
<influxdb-java.version>2.18</influxdb-java.version>
<jackson-bom.version>2.11.2</jackson-bom.version>
<jakarta-activation.version>1.2.2</jakarta-activation.version>
<jakarta-annotation.version>1.3.5</jakarta-annotation.version>
<jakarta-jms.version>2.0.3</jakarta-jms.version>
<jakarta-json.version>1.1.6</jakarta-json.version>
<jakarta-json-bind.version>1.0.2</jakarta-json-bind.version>
<jakarta-mail.version>1.6.5</jakarta-mail.version>
<jakarta-persistence.version>2.2.3</jakarta-persistence.version>
<jakarta-servlet.version>4.0.4</jakarta-servlet.version>
<jakarta-servlet-jsp-jstl.version>1.2.7</jakarta-servlet-jsp-jstl.version>
<jakarta-transaction.version>1.3.3</jakarta-transaction.version>
<jakarta-validation.version>2.0.2</jakarta-validation.version>
<jakarta-websocket.version>1.1.2</jakarta-websocket.version>
<jakarta-ws-rs.version>2.1.6</jakarta-ws-rs.version>
<jakarta-xml-bind.version>2.3.3</jakarta-xml-bind.version>
<jakarta-xml-soap.version>1.4.2</jakarta-xml-soap.version>
<jakarta-xml-ws.version>2.3.3</jakarta-xml-ws.version>
<janino.version>3.1.2</janino.version>
<javax-activation.version>1.2.0</javax-activation.version>
<javax-annotation.version>1.3.2</javax-annotation.version>
<javax-cache.version>1.1.1</javax-cache.version>
<javax-jaxb.version>2.3.1</javax-jaxb.version>
<javax-jaxws.version>2.3.1</javax-jaxws.version>
<javax-jms.version>2.0.1</javax-jms.version>
<javax-json.version>1.1.4</javax-json.version>
<javax-jsonb.version>1.0</javax-jsonb.version>
<javax-mail.version>1.6.2</javax-mail.version>
<javax-money.version>1.0.3</javax-money.version>
<javax-persistence.version>2.2</javax-persistence.version>
<javax-transaction.version>1.3</javax-transaction.version>
<javax-validation.version>2.0.1.Final</javax-validation.version>
<javax-websocket.version>1.1</javax-websocket.version>
<jaxen.version>1.2.0</jaxen.version>
<jaybird.version>3.0.9</jaybird.version>
<jboss-logging.version>3.4.1.Final</jboss-logging.version>
<jboss-transaction-spi.version>7.6.0.Final</jboss-transaction-spi.version>
<jdom2.version>2.0.6</jdom2.version>
<jedis.version>3.3.0</jedis.version>
<jersey.version>2.30.1</jersey.version>
<jetty-el.version>8.5.54</jetty-el.version>
<jetty-jsp.version>2.2.0.v201112011158</jetty-jsp.version>
<jetty-reactive-httpclient.version>1.1.4</jetty-reactive-httpclient.version>
<jetty.version>9.4.31.v20200723</jetty.version>
<jmustache.version>1.15</jmustache.version>
<johnzon.version>1.2.8</johnzon.version>
<jolokia.version>1.6.2</jolokia.version>
...
插入了一系列包以及其版本控制,这实现了真正的依赖管理,称为springboot的版本仲裁中心。因此我们导入依赖,不需要写版本号。当然没有在dependency里面的,则需要自己注明版本号。
2.3 分析导入的依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
可以分为spring-boot-starter和它的后缀,spring-boot-starter称为其为springboot场景启动器,登录其官网看帮助文档https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2hu4xm7s-1597822533730)(C:\Users\wanglei\AppData\Roaming\Typora\typora-user-images\image-20200819105152016.png)]
可以根据不同的开发场景,选择不同类型的启动器。
2.4主程序类
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@SpringBootApplication:这个注解标注在某个类上,表示这个类是主程序类,主配置类,运行这个类的main方法来启动整个应用。具体其实现不再赘述,可以看源码理解其运行方式。
2.5配置文件
可以通过配置文件,修改Springboot默认设置。例如修改端口号,可写为:
server:
port: 8081
后续章节将介绍yml的语法及用法。
3 yml文件
3.1 基本语法
以空格控制层级关系,同一层的语法为 key 空格 value ,例如:
server:
port: 8081
path: /hello
字面量写法:
k: v 字面量直接来写,字符串默认不用加引号
对象的写法,如下:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo01serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: qsxcdw123
3.2 利用yml文件,动态注入对象
首先在.yml文件中写出对象:
person:
lastName: zhangsan
age: 14
maps:
k1: hefei
k2: 20
lists:
-lisi
-zhaoliu
-www
dog:
name: xiaogou
age: 2
在对应的类上,加注解:
/*
将配置文件中的配置的每一个属性的值,映射到这个组件中
@ConfigurationProperties 将本类中的属性将配置文件中的相关配置进行绑定
* */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
//@Value("${person.lastName}")
private String lastName;
private Integer age;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
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 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;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
创建测试类:
/*
单元测试
* */
@RunWith(SpringRunner.class)
@SpringBootTest
class DemoApplicationTests {
@Autowired
Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
运行测试类可以看到:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0wfPrTk6-1597822533734)(C:\Users\wanglei\AppData\Roaming\Typora\typora-user-images\image-20200819151539978.png)]
person通过注入的方式,创建了对象。此外,更常用的是对类的某个属性进行注入,此时常常用到@Value注解。yml的创建方式不变,以类的lastName 属性为例(大篇幅的代码为get和set函数,可自动生成):
/*
测试@Value注解的作用
* */
@Component
//@ConfigurationProperties(prefix = "person")
public class Person {
@Value("${person.lastName}")
private String lastName;
private Integer age;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
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 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;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
注解@Value(${person.lastName})将yml文件中的关于person的lastName的值注入,运行测试类得到:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zNbZaPPP-1597822533736)(C:\Users\wanglei\AppData\Roaming\Typora\typora-user-images\image-20200819152142497.png)]
对比之前的结果,我们发现,lastName属性已经被实例化,体现了@Value注解的作用。
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
注解@Value(${person.lastName})将yml文件中的关于person的lastName的值注入,运行测试类得到:
[外链图片转存中...(img-zNbZaPPP-1597822533736)]
对比之前的结果,我们发现,lastName属性已经被实例化,体现了@Value注解的作用。
此外发现,当缺少getter函数时,@Value仍然能发挥作用,但是@ConfigurationProperties则无法注入值,笔者推测,@ConfigurationProperties的可能是通过类的getter函数进行赋值,而@Value则是一种反射方法。