一、spring boot 入门
1、环境搭建
1.1 、jdk1.8
1.2 maven3.39
1.3 idea 2017 x64
1.4 springboot
2、 创建工程与测试
2.1 创建maven工程
项目目录结构
[外链图片转存失败(img-iKejUGaR-1565936411964)(E:\markdowm\image\1535696891649.png)]
####2.2 导入springboot依赖
springboot 父项目工程依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
引入springboot web
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.3 创建springboot 启动程序
在项目的包的根目录下创建springboot的启动程序,@SpringBootApplication 标注 这个是个springboot 程序。
/**
* @SpringBootApplication 标注 这个是个springboot 程序
*
*/
@SpringBootApplication
public class Springbootmain {
public static void main(String[] args) {
SpringApplication.run(Springbootmain.class,args);
}
在这个配置类中,@SpringBootApplication: springboot 配置类
标注在某个类上,表是这个是一个springboot 的配置类;
@configuration: 配置类上标注这个注解;
配置类---配置文件;配置类也是容器的一个组件;@Component
@EnableAutoConfiguration: 开启自动配置功能
以前我们需要配置的东西,spring boot 帮我们自动配置
@AutoConfigurationPackage 自动配置包
@AutoConfigurationPackage将主配置类,(@SpringBootApplication 标注的类)的所在包及下面所有的种子包里面的组件扫描到spring容器;
**EnableAutoConfigurationImportSelector**:导入哪些组件的选择器;
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;容器中添加很多自动配置类(xxxAutoConfiguration);就是这个容器中导入场景中所需要使用组件。
@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}
)}
)
有了自动配置类,免去了我们手动的配置注入功能组件等功能;
springboot在动动的时候,从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效了,帮我们进行了自动配置以前我们需要自己配置的东西,自动配置类做了。
J2EE的整体整合解决方案和自动配置都在:spring-boot-autoconfigure-1.5.12.RELEASE.jar;
2.5 测试程序编写
创建controller 包,项目
创建helloController.java文件
package com.liu.spring.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* @RestController
* 这个注解代表 rest 和controller
*
*/
@RestController
public class HelloController {
/**
* @GetMapping 注解路径 url 访问只能使用get的方式请求
*
* @return
*/
@GetMapping("/hello")
public Map<String,String> hello(){
Map<String,String> result = new HashMap<String, String>();
result.put("msg","hello world!!");
return result;
}
}
2.6 测试程序
运行springboot main程序 进行项目启动
[外链图片转存失败(img-zig47hpE-1565936411965)(E:\markdowm\image\1535696734245.png)]
2.7 使用postman测试
这里测试的时候 注意,使用get 请求进行测试,要不然会报错,拒绝请求,这样就得到了我们想要的结果
[外链图片转存失败(img-IfE9MB15-1565936411966)(E:\markdowm\image\1535697295788.png)]
2.8 springboot 打包部署
2.8.1 springboot 打包
引入maven打包插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.8.2 maven 工具打包
使用maven lifecycle 下面的package的打包工具
[外链图片转存失败(img-MjCTsfqV-1565936411966)(E:\markdowm\image\1535697500758.png)]
2.8.3 启动项目
通过java -jar springboot-1.0-SNAPSHOT.jar 的方式进行项目的部署,注意看tomcat启动的端口为8080
e:\work>java -jar springboot-1.0-SNAPSHOT.jar
此处省略N 多的启动日志
2018-08-31 14:40:48.726 INFO 38760 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s):
8080 (http)
2018-08-31 14:40:48.734 INFO 38760 --- [ main] com.liu.spring.Springbootmain : Started Springbootmain in
6.357 seconds (JVM running for 7.618)
3、springboot-start
springboot 通过start 来将各个场景的jar包进行项目导入工作,我们只要关注业务场景即可,无需过多的去关注jar包的导入,只需要选取场景即可。
二、spring boot配置
1 、快速创建springboot工程
IDE都支持使用springInitailer 工具来快速创建springboot工程
选择我们需要的模块,想到会联网创建springboot的项目工程
1.1、目录结构
默认生成springboot项目;
[外链图片转存失败(img-A1H1JVbS-1565936411967)(E:\markdowm\image\1535702087253.png)]
- 主程序已经生成好了,我们需要实现自己的业务逻辑
- resources文件夹中的目录结构
- static 保存所有的静态资源 ;js css images ;
- templates: 保存所有的模板页面;(springboot 默认jar包使用嵌入式的tomcat,默认不支持jsp页面);可以使用模板引擎,freemarker 、thymeleaf;
- application.properties :springboot 应用的配置文件;可以修改一些默认配置的参数;
2 、配置文件
2.1 整体配置
springboot 使用一个全局的配置文件,配置文件名称是固定的;
application.properties
appication.yml
配置文件的作用,修改springboot的自动配置的默认值;springboot在底层都个我们自动配置好。
以前的配置文件一般为xml格式
yaml :以数据为中心,比json、xml更加简洁
2.2 YAML语法
2.2.1 基本语法
K: 空格v: 表示一对键值对 (空格必须要有)
以空格的缩进方式来控制层级关系;只要是左对齐的一列数据都是同一个层级的
server:
context-path: /springboot
port: 8090
属性和值也是大小敏感;
2.2.2 值的写法
字面量:普通的值(数值,字符串,布尔)
字符串默认不用加上单引号或者单引号
“” :双引号 ;不会转义字符串联的特殊字符;特殊字符会作为本身的意思
‘’:单引号 ;会转义特殊的字符,特殊字符串会当做字符串输出
对象、map(属性和值)
k:v 在下一行来写对象的属性和值;注意缩进
表示一个对象的书写格式
user:
name: zhangsan
age: 10
sort: 100
money: 2000
行内写法:
user: { name: "zhangsan",age:10,sort: 100,money: 2000}
数组(list、set)
用-值表示数组中的一个元素
pets:
- cat
- dog
- pig
行内写法:
pets: [cat,dog,pig]
3 配置文件值注入
配置文件:
user:
lastName: zhangsan
age: 10
boss: false
brithday: 2018/10/01
maps: {k1: v1,k2: 12}
list:
- lisi
- zhangsan
- wangwu
dog:
name: 小王
age: 2
实体文件:
package com.liu.bootquick.bean;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @ConfigurationProperties 配置文件属性和该类的属性相关,进行绑定
* @Data lombok 生成getset 等方法
* 只有这个组件是容器中的组件,容器才能提供服务
*/
@Data
@Component
@ConfigurationProperties(prefix = "user")
public class User {
private String lastName;
private Integer age;
private Boolean boss;
private Date brithday;
private Map<String,Object> maps;
private List<Object> list;
private Dog dog;
}
package com.liu.bootquick.bean;
import lombok.Data;
@Data
public class Dog {
private String name;
private Integer age;
}
我们还需要配置文件处理器,配置文件绑定的时候有提示:
<!--导入配置文件处理器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
3.1 properties的中文乱码问题解决
在idea中,配置文件的默认编码为utf-8,但是在运行的时候默认为ascii码,所以在设置的时候 需要把配置文件的编码更改为utf8,运行时勾选上转换成ascii。
[外链图片转存失败(img-b3I99NXA-1565936411967)(E:\markdowm\image\1537343457248.png)]
3.2 @configurationProperties 和@Value获取值的区别
功能 | @configurationProperties | @Value |
---|---|---|
基本功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
spEl | 不支持 | 支持 |
JSR303 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
总结:如果是为了 注入一个对象,或者对象类型复杂,或者做一些数据校验的时候,需要使用@configurationproperties,
如果是使用单独项或者,简单的类型,且不需要校验可以使用@value
@configurationProperties 全局的配置文件
3.3 注入值数据校验
@Data
@Component
@ConfigurationProperties(prefix = "user")
@Validated
public class User {
@Email
private String lastName;
private Integer age;
private Boolean boss;
private Date brithday;
private Map<String,Object> maps;
private List<Object> list;
private Dog dog;
}
报错:
Property: user.lastName
Value: 李四
Origin: class path resource [application.properties]:6:16
Reason: 不是一个合法的电子邮件地址
3.4 @propertiesSource 、@ImportResource @Bean
@propertiesSource 可以加载自定义的配置文件,可以加载多个。使用数组的方式加载 classpath:
//实例中是配置多个配置文件 单个的就不多说了
@PropertySource({
"classpath:person.properties"
,"classpath:user.properties"
})
实体类:
@Data
@Component
@ConfigurationProperties(prefix = "user")
@PropertySource({"classpath:person.properties"})
//@Validated
public class User {
// @Email
private String lastName;
private Integer age;
private Boolean boss;
private Date brithday;
private Map<String,Object> maps;
private List<Object> list;
private Dog dog;
}
配置文件:person.properties
user.age=10
user.boss=true
user.brithday=2017/10/10
user.dog.name=张三
user.dog.age=10
user.last-name=李四
user.list=a,b,c
user.maps.k1=v1
user.maps.k2=v2
@ImportResource 导入spring的配置文件,让配置文件的内容生效。我们自己写的配置文件也不能被自动识别,想让我们的spring的配置文件生效,加载进来,我们需要将这个注解加载到主程序上面
package com.liu.bootquick;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
//将beans 注入到spring容器中
@ImportResource(locations={"classpath:beans.xml"})
public class BootQuickApplication {
public static void main(String[] args) {
SpringApplication.run(BootQuickApplication.class, args);
}
}
// 配置文件: 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.liu.bootquick.service.HellwordService"/>
</beans>
springboot推荐给容器中添加组件的方式:推荐使用全注解的方式添加组件
1、配置类 =====spring配置文件
package com.liu.bootquick.config;
import com.liu.bootquick.service.HellwordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
* @Configuration 指明当前类是一个配置类,就是来代替之前的spring的配置文件
* @Bean 配置文件中来添加组件
* *
*/
@Configuration
@Slf4j
public class MyConfig {
// 该方法的返回值就是添加到容器中的组件,
// 该方法的名称为该组件在容器中的默认的id
// springboot推荐使用该方式进行初始化组件
@Bean
public HellwordService helloService(){
log.info("向springboot 容器中添加helloService 组件");
return new HellwordService();
}
}
4 占位符
随机数
${random.init}配置文件中可以用占位符
${random.uuid}配置文件可以用占位符
占位符获取之前配置的值,如果没有可以用:指定默认值
${person.hello:hello} 如果获取的值为空,则表达式取值为hello
5 profile
5.1 多profile文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties
默认使用的是application.properties的配置
5.2 yml 支持多文档块方式
spring:
activemq:
broker-url: tcp://192.168.0.143:61616
in-memory: true
pool:
enabled: false
user: admin
password: admin
profiles:
active: dev
---
#开发环境
spring:
profiles: dev
---
#生成环境
spring:
profiles: prod
5.3 激活指定profile
方法一:
spring.profiles.active= dev
方法二 :
在打成jar后 使用java -jar xxxx.jar --spring.profiles.active=dev
[外链图片转存失败(img-5MX9v65L-1565936411968)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1537422576002.png)]
方法三 :
虚拟机参数设定: -Dspring.profiles.active=dev
[外链图片转存失败(img-gWJ8JRhw-1565936411968)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1537422855028.png)]
6 配置文件的加载位置:
在配置文件的存放位置是有优先级的,
1、file/config
2、file
3、classpath/config
4、classpath
以上是按照优先级从高到低的顺序,所有的文件的文件都会被加载,***高优先级配置***内容会***覆盖低优先级配置***内容。
低优先级的配置可以和高优先级的配置文件形成互补配置,这样就可以使用合集来配置springboot
在项目已经打包的情况下,我们可以使用命令的方式给项目指定配置文件来启动项目,如:
注意:这里的配置文件会和原有的配置文件形成互补配置,默认优先级最高
java -jar xxx.jar --spring.config.location=g:\application.properties
7 外部配置加载顺序
总结:
1、由jar包外向jar包内进行寻找,优先加载带profile的,再来加载不带profile
2、命令行的参数 优先级最高
8 自动配置原理
自动配置原理
1)springboot启动的时候加载了主配置类,开启了自动配置功能
精髓:
1) springboot启动时候会加载大量的自动配置类
2)我们看到我们需要功能有没有springboot默认写好的自动配置类
3)我们再来看这个自动配置类到底配置了哪些组件
4)给容器中自动配置类的时候,会自动从properties中获取某些属性,我们就可以在配置文件中指定这些属性。
自动配置类在一定条件下才能生效;
开启springboot debug 模式,来让控制台打印自动配置报告,这样我们就可以很方便指定哪些自动配置类生效
debug =true
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:(自动配置匹配)
-----------------
ActiveMQAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
Negative matches:(自动配置未匹配)
-----------------
ActiveMQConnectionFactoryConfiguration.PooledConnectionFactoryConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.apache.activemq.pool.PooledConnectionFactory' (OnClassCondition)
三、springboot日志
1、日志框架
日志门面:SLF4J
日志实现: logback
springboot:底层是spring框架,spring框架默认是用jcl
springboot 选用SLF4j 和logback
2 、slf4j使用
2.1 如何在系统中使用SLF4J
以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,二是电泳日志抽象层里面的方法
给系统里面导入slf4j的jar和logback的实现jar
package com.liu.bootquick.log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Hello {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Hello.class);
logger.info("slf4j");
}
}
可以通过下图可以很方便的来配置日志:
[外链图片转存失败(img-8RJmmJRC-1565936411969)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1537489807553.png)]
每一个日志实现框架都有自己的配置文件,使用slf4j以后,配置文件还是做成日志是想框架自己本身的配置文件;
2.2 日志遗留问题
slf4j +logback : spring(commons-logging) 、hibernate(jboss-logging)。。。。
在依赖其他框架的时候,其他框架 底层可能依赖于其他的日志框架。通过下图可以解决日志的统一的方案;
统一日志记录,及时使用别的框架和我一起统一使用
[外链图片转存失败(img-13bkJr9q-1565936411970)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1537489748744.png)]
如何用系统中的日志都统一到SLF4J
1、将系统中的其他日志框架先排除出去;
2、用中间包来替换换原来的日志框架
3、我们到如slf4j其他的实现
#springboot 处理日志的依赖关系 ,将其他几种日志的转换成slf4j 日志框架 并提供实现
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.0.4.RELEASE</version>
<scope>compile</scope>
</dependency>
[外链图片转存失败(img-jtoe9Egq-1565936411971)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1537491900569.png)]
总结:
springboot底层也是使用slf4j+logback的凡是进行日志记录;
springboot 也吧其他的日志替换成了slf4j;
在使用替换包的时候,虽然是名称相同, 但是在底层实现的时候,已经被改成了 slf4j 的工厂
//JUL
public static void install() {
LogManager.getLogManager().getLogger("")
.addHandler(new SLF4JBridgeHandler());
}
//log4j
public class SLF4JLoggerContextFactory implements LoggerContextFactory {
private static final StatusLogger LOGGER = StatusLogger.getLogger();
排除commons-logging
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
springboot 能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他的框架的时候,只需要把这个日志框架的日志框架排除掉。
4 日志使用:
4.1 日志的配置
#指定日志级别
logging.level.com.liu=debug
#不指定全路径,则表示在当前工程路劲下,如果指定则 就在指定的目录
logging.file=boot.log
#在当前磁盘路径下创建spring/logs日志目录,使用spring.log 作为默认的文件名
logging.path=/spring/logs
#控制台的日志格式
logging.pattern.console=
#文件的日志格式输出
logging.pattern.file=
日志文件格式化的参数详解:
%m | 输出代码中指定的消息 |
---|---|
%p | 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL |
%r | 输出自应用启动到输出该log信息耗费的毫秒数 |
%c | 输出所属的类目,通常就是所在类的全名 |
%t | 输出产生该日志事件的线程名 |
%n | 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n” |
%d | 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921 |
%l | 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10) |
4.2 指定日志文件
不同的日志系统:使用的默认配置文件
Logging System | Customization |
---|---|
Logback | logback-spring.xml , logback-spring.groovy , logback.xml or logback.groovy |
Log4j2 | log4j2-spring.xml or log4j2.xml |
JDK (Java Util Logging) | logging.properties |
logback.xml: 会直接被日志框架识别,会跳过spring
logback-spring.xml : 会先被springboot 来识别并配置,可以使用高级特性,可以使用boot的标签,来使用
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>
<springProfile name="dev, staging">
<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>
<springProfile name="!production">
<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>
5 切换日志
可以按照slf4j 的日志是配图,进行相关的切换.可以右键进行排除jar包,然后倒入新的jar包就可以了
具体可以参照上面的日志图,来切换日志;
starter-log4j2 就可以完成日志的切换
四 、springboot 与web开发
1、使用springboot
1)创建springboot应用,选中我们需要的模块;
2)springboot已经默认帮我们将这些场景配置好了;我们只需要再配置文件中指定少量的配置文件,就可以运行起来了。
2、springboot对静态资源的映射
-
/** 访问当项目的任何资源,都去静态资源文件夹找映射
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
-
欢迎页面;静态资源文件夹下面所有的index.html 页面;被/**映射
-
所有的**/favicon.ico 都是在静态资源文件下找;
3 模板引擎
jsp、velocity、freemark、thymeleaf
[外链图片转存失败(img-dSpuyZy1-1565936411971)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1537503836331.png)]
springboot 推荐使用Thymeleaf
3.1 thymeleaf 的引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
六 springboot 与数据访问
1、jdbc
springboot 基础jar包 来支持 jdbc操作
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
yml 配置
spring:
datasource:
username: root
password: Root123
url: jdbc:mysql://127.0.0.1:3306/springboot
driver-class-name: com.mysql.jdbc.Driver
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency>
配置阿里的数据源
spring:
datasource:
username: root
password: Root123
url: jdbc:mysql://127.0.0.1:3306/springboot
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource