SpringBoot学习(上)
一:入门
2014伴随spring4.0版本发布的一个框架。整个spring技术栈的一个整合。简化spring应用开发,约定大于配置。
spring全家桶时代:spring boot–>J2EE一站式解决方案
spring cloud --> 分布式整体解决方案
优点:
快速创建独立运行的spring项目以及与主流框架集成。使用嵌入式的servlet容器,应用无需打成war包。
starters自动依赖与版本控制。
大量自动配置,简化开发,也可修改默认值。
无需xml,无代码生成,开箱即用。
准生产环境的运行时应用监控。
与云计算的天然集成。
微服务:2014年martin fowler发表的文章。
微服务是一种架构风格,一个应用应该是一组小型服务。
小型服务可以通过http方式进行互通。
一个微服务架构把每个功能元素放进一个独立的服务中,并且通过跨服务器分发这些服务进行扩展,只在需要时才复制。
每一个功能元素最终都是一个可独立替换和独立升级的软件单元。
单体应用:all in one;开发测试简单,部署简单(打成一个war包),负载均衡多个服务器提高并发能力。
不好维护,牵一发动全身。
spring boot(build anything)可以快速构建出一个应用,
然后spring cloud(coordinate anything)进行互联互调,做出分布式。
spring cloud data flow(connect everything)
一个示例:浏览器发送hello请求,服务器接受请求并处理,响应hello world字符串;
1、创建一个maven工程;
2、导入spring boot的相关依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
3、编写一个主程序(启动spring boot 应用)
/**
* @SpringBootApplication标注一个主程序类,说明这是一个spring boot应用
*/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
//spring应用启动起来
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
4、编写相关controller、service等
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "hello liubei !";
}
}
5、运行主程序测试
6、简化部署
只需导入maven插件:
<build>
<plugins>
<!--
这个插件可以将应用打包成一个可执行的jar包
-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
左下角调出右边maven工具,找到项目–lifecycle–clean–package
打包在target目录下的jar包。然后在cmd窗口执行java -jar jar包即可。
jar包lib目录下的tomcat嵌入如下:
二:探究hello world
1:POM文件
1,父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</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应用里面的所有依赖版本
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(启动器),只要项目里面引入这些starter相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景启动器。
2:主程序类,主入口类
/**
* @SpringBootApplication标注一个主程序类,说明这是一个spring boot应用
*/
@SpringBootApplication
//一个组合注解
@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}
)}
)
@SpringBootConfiguration:spring boot配置类
@Configuration:配置类上来标注这个注解;
配置类-------配置文件;配置类也是容器中的一个组件;@Component
@EnableAutoConfiguration:开启自动配置功能;
以前需要配置的东西,spring boot帮助我们自动配置。
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
@AutoConfigurationPackage:自动配置包 |
@Import({Registrar.class})
spring的底层注解@Import,给容器中导入一个组件;导入的组件由Registrar.class
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件 扫描到spring 容器中。 |
@Import({EnableAutoConfigurationImportSelector.class})
EnableAutoConfigurationImportSelector:导入哪些组件的选择器;
将所有需要导入的组件以全类名的方式返回;这些组件就能添加到容器中。
会给容器中导入非常多的自动配置类(xxxAutoConfigration):就是给容器中导入这个场景需要的所有组件并配置好这些组件;
有了自动配置类,免去了我们手动编写配置,注入功能组件等的工作。
getCandidateConfigurations方法里的:
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, classLoader);
loadFactoryNames()方法的作用:
classLoader.getResources(“META-INF/spring.factories”)获取urls,当做Properties处理
再拿出factoryClassName:classLoader.getResources(“META-INF/spring.factories”)
spring boot启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值。
将这些值作为自动配置类导入到容器中,自动配置类就生效,帮助我们进行自动配置工作。
以前我们需要自己配置的东西,自动配置类都帮我们;
spring-boot-autoconfigure-1.5.9.RELEASE.jar
三:快速新建一个spring boot项目
使用spring assistant:
下载此插件
然后new project–选择要加载的dependencies–写项目的groupid,制品id,项目名称,项目的包生成一个pom文件:
<?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>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hxh</groupId>
<artifactId>spring-boot-01-helloword-quick</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-01-helloword-quick</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>
spring-boot-starter-test用于测试
/*@Controller
//这个类的所有方法返回的数据直接写给浏览器(如果是对象,转化为json数据)
@ResponseBody*/
//是上两个注解的组合体
@RestController
public class HelloAgain {
@RequestMapping("/helloLIUBEI")
public String hello(){
return "Hello Alone Again !";
}
}
主程序已生成好,我们只需建立逻辑。
resources文件夹里面已经有结构:
- static:保存所有的静态资源;js css images;
- templates:保存所有的模板页面;(spring boot默认jar包使用嵌入式的tomcat,默认不支持JSP页面);
可以使用模板引擎(freemarker、thymeleaf); - application.properties:Spring boot应用的配置文件;
可以在配置文件里添加修改端口号的语句:server.port=8989
四:配置文件-01
配置文件+加载顺序+配置原理
spring boot使用一个全局配置文件:配置文件名是固定的;
application.properties
application.yml
配置文件作用:修改springboot自动配置的默认值;
spring boot在底层都给我们配置好了。
标记语言:
以前的配置文件大多是xxx.xml文件;YMAL以数据为中心,更适合做配置文件。
yml配置实例:
server:
port: 8081
xml配置实例:
<server>
<port>8081</port>
</server>
YAML的基本语法:
一:基本语法
key: value表示一对键值对,value前必须有空格。
以空格的缩进来控制层级关系,空格多少没关系,
只要是左对齐的一列数据,都是同一层级的。
属性和值也是大小写敏感的。
二:值的写法
字面量:普通的值(数字,字符串,布尔):
k: v 字面直接来写,字符串默认不用加上单引号与双引号;
“”:双引号会转义字符串里的特殊字符;特殊字符会作为本身想表示的意思。
name: “zhangsan \n lisi” 输出:zhangsan 换行 lisi
‘’:单引号;不会转义特殊字符,特殊字符最终只是一个普通的字符串数据。
name: “zhangsan \n lisi” 输出:zhangsan \n lisi
对象、Map(属性与值)(键值对):
k: v:
对象还是k:v方式
friends:
lastName: zhangsan
age: 20
行内写法:
friends: {lastName: zhangsan,age: 18}
数组(List,Set):
用- 空格 值表示数组中的一个元素
pets:
- cat
- dog
- pig
行内写法:
pets: [cat,dog,pig]
结合示例:
//自己添加getset与tostring方法
public class Person {
private String Name;
private Integer Age;
private Boolean crippled;
private Map<String,Object> maps;
private List<Object> lists;
private Pet pet;
}
//自己添加getset与tostring方法
public class Pet {
private String petName;
private Integer petAge;
}
application.yml内容:
petName可以写为pet-name
server:
port: 8089
person:
Name: 韩**
Age: 27
crippled: false
maps: {k1: woqu,k2: dani}
lists:
- lisi
- zhaoliu
pet:
petName: Harry
petAge: 2
如何将此person配置映射到Person对象,通过注解:
/**
* 将配置文件中配置的每个属性的值,映射到这个组件中
* @ConfigurationProperties告诉springboot将本类中的
* 所有属性和配置文件中相关配置进行绑定
* 只有组件是容器中的组件,才能使用容器提供的功能。
*/
@Component
@ConfigurationProperties(prefix = "person")
test是如何的呢?
/**
* SpringBoot单元测试
* 可以在测试期间类似编码一样进行自动注入
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBoot01HellowordQuickApplication.class)
public class Test01 {
@Resource
private Person person;
@Test
public void test001(){
System.out.println(person);
}
}
结果为:
Person{Name='韩**', Age=18, crippled=false, maps={k1=woqu, k2=dani}, lists=[lisi, zhaoliu], pet=pet{petName='Harry', petAge=2}}
yml注释只需要“ctrl+/”;
yml提供自动检测输入内容需要在pom文件里提供一个配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
properties文件的配置如下:
#server.port=8989
person.Name = 韩**
person.age = 33
person.crippled = false
person.maps.k1 = v1
person.maps.k2 = v2
person.lists = a,b,c
person.pet.petName = Robbert
person.pet.petAge = 1
输出内容的中文可能乱码,这时需要对file encodings进行如下设置:勾选transparent native-to-ascii conversion即可。