SpringBoot学习笔记
1.概念
SpringBoot采用约定优于配置的概念,大大减少了配置项
1.1 特性
-
SpringBoot Starter:将依赖进行分组整合,将其合并到一个依赖中,这样就可以一次性添加到项目的Maven或Gradle构建中。
-
使编码变得简单,SpringBoot采用 JavaConfig的方式对Spring进行配置,并且提供了大量的注解,极大的提高了工作效率
@Configuration
public Class XXX{
@Bean
public User init(){
return new User();
}
}
-
自动配置:SpringBoot的自动配置特性利用了Spring对条件化配置的支持,合理地推测应用所需的bean并自动化配置他们;SpringBoot在启动过程中,会自动将一些配置类的Bean进行创建,并添加到IOC容器中。
-
使部署变得简单,SpringBoot内置了三种Servlet容器,Tomcat,Jetty,undertow.我们只需要一个Java的运行环境就可以跑SpringBoot的项目了,SpringBoot的项目可以打成一个jar包。
1.2 热部署
在开发项目过程中,当修改了某些代码后需要本地验证时,需要重启本地服务进行验证,启动这个项目,如果项目庞大的话还是需要较长时间的,spring开发团队为我们带来了一个插件:spring-boot-devtools,很好的解决了本地验证缓慢的问题。
1.添加spring-boot-devtools热部署依赖启动器
<!-- 引入热部署依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
2.IDEA工具热部署设置
选择IDEA工具界面的【File】->【Settings】选项,打开Compiler面板设置页面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YodVwhfm-1618239915337)(E:\learning\lagou\学习笔记\1-4_SpringBoot\images\SpringBoot学习笔记.md)]
在项目任意页面中使用组合快捷键“Ctrl+Shift+Alt+/”打开Maintenance选项框,选中并打开Registry页面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MeqSGxn5-1618239915341)(E:\learning\lagou\学习笔记\1-4_SpringBoot\images\image-20210327215353865.png)]
1.2.1热部署原理分析
可以看到,我们引入了spring-boot-devtools插件后,插件会监控我们classpath的资源变化,当classpath有变化后,会触发重启。
重启快速的原因:这里用了两个类记载器来加器,对于第三方jar包采用base-classLoader来加载,对于开发人员编写的使用restartClassLoader来加载,这就比停止重启的效率快得多了。
验证:
@Component
public class Devtools implements InitializingBean {
private static final Logger log = LoggerFactory.getLogger(Devtools.class);
@Override public void afterPropertiesSet() throws Exception {
log.info("guava-jar classLoader: " + DispatcherServlet.class.getClassLoader().toString());
log.info("Devtools ClassLoader: " + this.getClass().getClassLoader().toString()); } }
发现第三方的jar包的类加载器确实是使用的系统的类加载器,而我们自己写的代码的类加载器为RestartClassLoader,并且每次重启,类加载器的实例都会改变
1.2.2 热部署排除资源
某些资源在更改后不一定需要触发重新启动。例如,Thymeleaf模板可以就地编辑。默认情况下,改变资源 /META-INF/maven , /META-INF/resources , /resources , /static , /public , 或 /templates 不触发重新启动,但确会触发现场重装。如果要自定义这些排除项,则可以使用该spring.devtools.restart.exclude 属性。例如,仅排除 /static , /public 您将设置以下属性:
spring.devtools.restart.exclude=static/**,public/**
1.3 全局配置文件
Spring Boot使用一个application.properties或者application.yaml的文件作为全局配置文件
配置文件加载顺序为
–file:./config/
–file:./
–classpath:/config/
–classpath:/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iSYYD3yY-1618239915342)(E:\learning\lagou\学习笔记\1-4_SpringBoot\images\image-20210328134542500.png)]
SpringBoot会从这四个位置全部加载主配置文件,如果高优先级中配置文件属性与低优先级配置文件不冲突的属性,则会共同存在— 互补配置 。
备注: 这里说的配置文件,都还是项目里面。最终都会被打进jar包里面的,需要注意。
1、如果同一个目录下,有application.yml也有application.properties,默认先读取 application.properties。
2、如果同一个配置属性,在多个配置文件都配置了,默认使用第1个读取到的,后面读取的不覆盖前面读取 到的。
3、创建SpringBoot项目时,一般的配置文件放置在“项目的resources目录下”
项目启动时制定配置文件名称(myproject为配置文件名称)
$ java -jar myproject.jar --spring.config.name=myproject
项目启动时制定配置文件位置
java -jar run-0.0.1-SNAPSHOT.jar --spring.config.location=D:/application.properties
application.yml和application.properties优先级
如果是2.4.0之前版本,优先级properties>yaml
但是如果是2.4.0的版本,优先级yaml>properties
如果想继续使用 Spring Boot 2.3 的配置逻辑,也可以通过在 application.properties 或者
application.yml 配置文件中添加以下参数:
spring.config.use-legacy-processing = true
1.4属性注入
常用的注解有
-
@Configuration:声明一个类作为配置类
-
@Bean:声明在方法上,将方法的返回值加入Bean容器
-
@Value:属性注入
-
@ConfigurationProperties(prefix = “jdbc”):批量属性注入
-
@PropertySource(“classpath:/jdbc.properties”)指定外部属性文件。在类上添加
1.4.1 @Value注解属性注入
无需生产set方法,注解作用在字段上
@Value("${jdbc.url}")
1.4.2 @ConfigurationProperties批量注入
@ConfigurationProperties(prefix = "jdbc")
//这里需要定义出在application文件中定义属 性值得前缀信息
public class JdbcProperties {
private String url;
private String driverClassName;
private String username;
private String password; // 注:要生成属性的set方法
}
单独使用@ConfigurationProperties会报警告,需要配置@EnableConfigurationProperties该注解用于启用应用对另外一个注解 @ConfigurationProperties 的支持,,用于设置一组使用了注解,另外还需要@Configuration注解
具体配置形式为
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
或者
@Compent
@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
例外依赖spring-boot-configuration-processor包,在配置配置文件时会有任何书写提示。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency
作用于方法上,为第三方赋值
@Configuration
public class MyService {
@ConfigurationProperties("another")
@Bean
public AnotherComponent anotherComponent(){
return new AnotherComponent();
}
}
1.5 日志框架
日志-抽象层 | 日志-实现层 |
---|---|
JCL(Jakarta Commons Logging)、SLF4J(Simple LoggingFacade for Java)、jboss-logging | jul(java.util.logging)、log4j、logback、log4j2 |
Spring 框架选择使用了 JCL 作为默认日志输出。而 Spring Boot 默认选择了 SLF4J 结合 LogBack
SLF4J 官方给出了简单示例。
首先要为系统导入 SLF4J 的 jar .
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
下图是 SLF4J 结合各种日志框架的官方示例,从图中可以清晰的看出 SLF4J API 永远作为日志的门面,
直接应用与应用程序中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcVLjlgt-1618239915345)(E:\learning\lagou\学习笔记\1-4_SpringBoot\images\image-20210328151003666.png)]
注意:由于每一个日志的实现框架都有自己的配置文件,所以在使用 SLF4j 之后,配置文件还是要使用实现日志框架的配置文件。
1.5.1 统一日志框架的使用
在项目中会依赖其他第三方组件,其依赖的日志框架也不一致。例如:
A项目(slf4J + logback): Spring(commons logging)、Hibernate(jboss-logging)、
mybatis…
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oWkohuIi-1618239915347)(E:\learning\lagou\学习笔记\1-4_SpringBoot\images\image-20210328155524753.png)]
我们得到一种统一日志框架使用的方式,可以使用一种和要替换的日志框架类完全一样的 jar 进行替换,这样不至于原来的第三方 jar 报错,而这个替换的 jar 其实使用了 SLF4J API. 这样项目中的日志就都可以通过 SLF4J API 结合自己选择的框架进行日志输出。
统一日志框架使用步骤归纳如下:
-
排除系统中的其他日志框架。
-
使用中间包替换要替换的日志框架。
-
导入我们选择的 SLF4J 实现。
1.5.2 SpringBoot日志使用
spring-boot-starter-logging 的 Maven 依赖主要引入了 logback-classic (包含了日志框架 Logback的实现),log4j-to-slf4j (在 log4j 日志框架作者开发此框架的时候还没有想到使用日志抽象层进行开发,因此出现了 log4j 向 slf4j 转换的工具),jul-to-slf4j ( Java 自带的日志框架转换为 slf4j).
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!--common-log转换为 slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<!--Java 自带的日志框架转换为 slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
<!--log4j 向 slf4j 转换的工具-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</dependency>
</dependencies>
由此可见,Spring Boot 可以自动的适配日志框架,而且底层使用 SLF4j + LogBack 记录日志,如果我们自行引入其他框架,需要排除其日志框架。
2.Spring Boot 源码剖析
2.1 源码构建
- https://github.com/spring-projects/spring-boot/releases
- 下载对应版本的源码
- 环境准备:JDK 1.8+ ,Maven3.5+
- 编译:进⼊spring-boot源码根⽬录,执⾏mvn命令: mvn clean install -DskipTests -Pfast
3. SpringBoot数据访问
在maven中配置数据库驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
在application.properties中配置数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql:///springboot_h? useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
# spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
配置spring-boot-starter-jdbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
编写测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootMytestApplication.class)
class SpringBootMytestApplicationTests {
@Autowired DataSource dataSource;
@Test
public void contextLoads() throws SQLException {
Connection connection = dataSource.getConnection();
}
}