1. 回顾Spring
在Spring1.x时代,都是通过xml文件配置bean,随着项目的不断扩大,需要将xml配置分放到不同的配置文件中,需要频繁的在java类和xml配置文件中切换。
随着JDK 1.5带来的注解支持,Spring2.x可以使用注解对Bean进行申明和注入,大大的减少了xml配置文件,同时也大大简化了项目的开发。
那么,问题来了,究竟是应该使用xml还是注解呢?
最佳实践:
- 应用的基本配置用xml,比如:数据源、资源文件等;
- 业务开发用注解,比如:Service中注入bean等;
从Spring3.x开始提供了Java配置方式,使用Java配置方式可以更好的理解你配置的Bean,并且Spring4.x和Spring boot都推荐使用java配置的方式。
- Java配置是Spring4.x推荐的配置方式,可以完全替代xml配置。
Spring的Java配置方式是通过 @Configuration 和 @Bean 这两个注解实现的:
- @Configuration 作用于类上,相当于一个xml配置文件;
- @Bean 作用于方法上,相当于xml配置中的;
2. Spring Boot 概述
2.1 什么是Spring Boot
Spring Boot是整个Spring项目中的一个模块,与Spring Framework都是Spring的的产品。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C7kNmkor-1618315407770)(imgs\image-20200727215254484.png)]
上面有红色框中的两段话
第一段:关于Spring项目的说明
From configuration to security, web apps to big data—whatever the infrastructure needs of your application may be, there is a Spring Project to help you build it. Start small and use just what you need—Spring is modular by design.
意思是:
从配置到安全,从web应用程序到大数据——无论应用程序的基础设施需求是什么,都有一个Spring项目可以帮助您构建它。从小处开始,用你需要的东西——spring是模块化设计的。
第二段:关于Spring Boot的说明
Takes an opinionated view of building Spring applications and gets you up and running as quickly as possible.
意思是:
对构建Spring应用程序有自己的设计理念,并尽可能快的启动和运行你的项目。
通常我们称 Spring Boot
为搭建程序的 脚手架
。其最主要作用就是帮助我们开发人员 快速的构建庞大
的spring项目,并且尽可能的减少一切xml配置,让我们 把重心放到业务 而非配置。
2.2 为什么要学习Spring Boot
Java在开发大型项目时,需要使用各种的框架,而框架的基础原理就是 反射、配置文件与设计模式
。所以开发时有大部分的时间都浪费在了各种框架的jar包依赖和配置文件上。
-
依赖管理混乱
项目的jar包依赖管理令人非常头痛,除了决定项目里要用哪些库,你还要知道这些库的哪个版本和其他库不会有冲突,一旦选错了依赖的版本,随之而来的就是jar包兼容问题,这给开发人员带来了极大的挑战。而且这仅仅是添加依赖,还没有到写应用程序代码的时候。
-
复杂的配置文件
项目各种配置其实也是开发时的难题,因为在思考 Spring 的各种配置是如何生效和解决业务问题之间是两种思维模式,切换思维对新手来说,并不是件容易的事,通常写配置就占用大量的开发时间。
Spring Boot让这一切都变得更加简单
官网原文
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.
We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.
意思是:
Spring Boot简化了Spring应用程序的开发,只需要
run
就能够非常容易的创建一个独立的,生产级别的Spring应用程序。Spring Boot为Spring平台以及第三方库提供了默认的设置(启动器starter
,通过启动器提供默认配置)。使得大多数的Spring Boot的应用程序只需要很少的配置就能够能完成大部分的功能。
2.3 Spring Boot的特点
- 创建独立的Spring应用程序
- 直接嵌入Tomcat、Jetty或Undertow(不需要部署WAR文件)
- 提供默认的“启动器”依赖关系来简化构建配置
- 尽可能的自动配置Spring和第三方库
- 提供可用于生产的功能,例如指标,运行状况检查和外部化配置
- 完全没有代码生成,和不必要的XML配置
3. Spring Boot项目的创建
3.1 创建Spring Boot项目
3.2 添加依赖
Spring Boot 提供了一个名称为 spring-boot-starter-parent
的工程,里面对常用的各种依赖的版本进行了管理,而我们的项目只需要引入该项目作为父工程,其余的依赖只需要引入maven的坐标就可以了。
3.2.1 添加父工程
<!-- 引入管理依赖的父工程 -->
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.2.8.RELEASE</version>
</parent>
3.2.2 添加一个web的项目的启动器
假设我们需要开发一个web项目,为了让Sping Boot帮我们完成各种的自动配置,我们需要引入Spring Boot提供的web项目启动器。
<!-- 引入web项目的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
注意:这里我们不需要配置版本,因为之前引入的Spring Boot的父项目已经对版本进行了管理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CTAHxtSy-1618315407772)(imgs\image-20200727230354558.png)]
这些都是Spring Boot根据 spring-boot-starter-web 这个启动器自动引入的,并且所有的版本已经进行了配置和管理,不会出现jar包不匹配等冲突。
3.3 项目启动类
Spring Boot项目可以通过main方法启动,书写一个启动类。
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
3.4 编写一个用于访问的控制器
书写一个HelloController,显示一个欢迎信息。
@RestController
public class HelloController {
@RequestMapping("/")
public String welcome(){
return "Hello, Spring Boot !!!";
}
}
3.5 启动测试
运行程序,程序启动后会在控制台显示如下的信息。
Tomcat启动成功。
端口号是:8080
项目路径:’’
输入地址访问:http://127.0.0.1:8080
项目启动测试成功!
4. Java注解配置
在刚才的示例中,我们没有配置额外的内容,就完成了一个Spring MVC的web项目,快速,简洁,高效。
4.1 Spring Boot中的Bean配置
早期配置bean时需要通过xml文件,添加一个bean标签来完成配置。
而在Spring Boot中,官方推荐使用Java配置的方式来替代传统的xml配置。
4.2.1 进行Java配置
java配置的方式主要是通过Java类和注解来完成,常用的注解
@Configuration
注解:声明一个类作为配置类,用来替代传统的xml文件。@Bean
注解:声明在一个方法上,将方法的返回值加入到Spring IOC容器中进行管理,用来替代bean标签。@Value
注解:属性注入,通常使用在属性上,给属性设置默认值。@PropertySource
注解:指定外部的属性文件。
使用Java的方式配置一个数据源:
引入数据源的支持,这里使用Spring提供的数据源
<!-- SpringBoot提供的jdbc启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
创建一个databse.properties属性文件,并编写属性
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/qingying-erp?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root
编写一个配置类的代码
@Configuration
@PropertySource("classpath:database.properties")
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource getDataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
直接在控制器中进行测试。
@RestController
public class HelloController {
@Autowired
private DataSource dataSource;
@GetMapping("/datasource")
public String dataSource(){
return dataSource.toString();
}
@RequestMapping("/")
public String welcome(){
return "Hello, Spring Boot !!!";
}
}
运行结果
属性注入成功!
通过debug调试查看
4.2.2 使用Spring Boot提供的方式注入
在Spring Boot中,提供了一种新的属性注入方式,支持各种java基本数据类型及复杂类型的注入。
- 创建一个类,完成属性的注入
@ConfigurationProperties
注解:声明当前类为属性读取类。prefix="jdbc"
:读取属性文件中,前缀为jdbc的值- 类中的属性名称必须与属性文件中
jdbc.
后面部分一致 - Spring Boot默认读取
applicaiton.properties
属性文件中的内容
@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
private String driver;
private String url;
private String username;
private String password;
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- 在JdbcConfig类中使用该属性类
@EnableConfigurationProperties(JdbcProperties.class)
注解 :声明需要使用的JdbcProperties
类型的对象- 通过@Bean注解的方法参数注入
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig {
@Bean
public DataSource getDataSource(JdbcProperties jdbcProperties){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(jdbcProperties.getDriver());
dataSource.setUrl(jdbcProperties.getUrl());
dataSource.setUsername(jdbcProperties.getUsername());
dataSource.setPassword(jdbcProperties.getPassword());
return dataSource;
}
}
4.2.3 直接注入
当属性只有一个类使用时,可以直接声明使用,更为简单。
- 直接在
@Bean
的方法上声明@ConfigurationProperties(prefix = "jdbc")
,然后SpringBoot就会自动调用这个Bean(DataSource)的set方法,然后完成注入。 - 注意:该@Bean类必须有对应 `jdbc.属性名 中对应属性名的set方法。
@Configuration
public class JdbcConfig {
@Bean
@ConfigurationProperties(prefix = "jdbc")
public DataSource getDataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
return dataSource;
}
}
5. 自动配置原理
使用Spring Boot 构建项目后,一切都变得非常的简单,它到底是怎么实现的?
接着我们就来查看它的执行过程。
5.1 程序入口
划红线的两个部分
@SpringBootApplicaiton
注解- SpringApplicaiton.run 方法
5.1.1 SpringBootApplicaiton注解
查看源码