1. 了解 springboot
- 什么是 springboot
- 为什么要学习 springboot
- springboot 的特点
1.1 什么是 springboot
Spring Boot 推崇约定大于配置的方式以便于你能够尽可能快速的启动并运行程序。人们常把 Spring Boot 称为搭建程序的 脚手架
。其最主要作用就是帮我们快速的构建庞大的 spring 项目,并且尽可能的减少一切 xml 配置,做到开箱即用,迅速上手,让我们关注与业务而非配置。
1.2 为什么要学习 springboot
java 一直被人诟病的一点就是臃肿、麻烦。
复杂的配置
项目各种配置其实是开发时的损耗,因为在思考 Spring 特性配置和解决业务问题之间需要进行思维切换,所以写配置挤占了写应用程序逻辑的时间。一个是混乱的依赖管理
项目的依赖管理也是件吃力不讨好的事情。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这难题实在太棘手。并且,依赖管理也是一种损耗,添加依赖不是写应用程序代码。一旦选错了依赖的版本,随之而来的不兼容问题毫无疑问会是生产力杀手。
而 SpringBoot 让这一切成为过去!
Spring Boot 简化了基于 Spring 的应用开发,只需要“run”就能创建一个独立的、生产级别的 Spring 应用。Spring Boot 为 Spring 平台及第三方库提供开箱即用的设置(提供默认设置,存放默认配置的包就是启动器),这样我们就可以简单的开始。多数 Spring Boot 应用只需要很少的 Spring 配置。
1.3 springboot 的特点
springboot 的主要特点
为所有的 spring 开发者提供了一个非常快速的,广泛接受的入门体验。开箱即用(启动器 starter- 其实就是 SpringBoot 提供的一个 jar 包),但通过自己设置参数(.properties),即可快速摆脱这种方式
提供了一些大型项目中常见的非功能性特性,如内嵌服务器、安全、指标,健康检测、外部化配置等
绝对没有代码生成,也无需 XML 配置
2.java 配置
主要任务:如何去掉 xml 配置
2.1 回顾历史
事实上,在 Spring3.0 开始,Spring 官方就已经开始推荐使用 java 配置来代替传统的 xml 配置了
Spring1.0 时代
在此时因为 jdk1.5 刚刚出来,注解开发并未盛行,因此一切 Spring 配置都是 xml 格式,想象一下所有的 bean 都用 xml 配置,细思极恐啊
Spring2.0 时代
Spring 引入了注解开发,但是因为并不完善,因此并未完全替代 xml,此时的程序员往往是把 xml 与注解进行结合,貌似我们之前都是这种方式
Spring3.0 及以后
3.0 以后 Spring 的注解已经非常完善了,因此 Spring 推荐大家使用完全的 java 配置来代替以前的 xml,不过似乎在国内并未推广盛行。然后当 SpringBoot 来临,人们才慢慢认识到 java 配置的优雅
2.2 尝试 java 配置
java 配置主要靠 java 类和一些注解,比较常用的注解有:
@Configuration:声明一个类作为配置类,代替 xml 文件
@Bean:声明在方法上,将方法的返回值加入 Bean 容器,代替 `<bean>` 标签
@value:属性注入
@PropertySource:指定外部属性文件
我们接下来用 java 配置来尝试实现连接池配置:
步骤一:首先引入 Druid 连接池依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
步骤二:创建一个 jdbc.properties 文件,编写 jdbc 属性
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/demo
jdbc.username=root
jdbc.password=123
步骤三:然后编写代码
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {@Value("${jdbc.url}")
String url;
@Value("${jdbc.driverClassName}")
String driverClassName;
@Value("${jdbc.username}")
String username;
@Value("${jdbc.password}")
String password;
@Bean
public DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
步骤四:测试
@RestController
public class HelloController {
@Autowired
private DataSource dataSource;
@GetMapping("hello")
public String hello() {return "hello, spring boot!" + dataSource;}
}
debug 查看信息,可以看到属性注入成功!
2.3 Springboot 属性注入
上面的案例,我们实践了 java 配置方式。不过属性注入使用的是 @Value 注解。这种方式需要可以,但是不够强大,因为他只支持基本数据类型值。
在 springboot 中,提供了一种新的属性注入方式,支持各种 java 基本类型及复杂类型的注入。
步骤一:新建一个类,用来进行属性注入
@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
private String url;
private String driverClassName;
private String username;
private String password;
// ... 略
// getters 和 setters
}
在类上通过 @ConfigurationProperties 注解声明当前类为属性读取类
prefix="jdbc" 读取属性文件中,前缀为 jdbc 的值
需要注意的是,这里我们并没有指定属性文件的地址,所以我们需要把 jdbc.properties 名称改为 application.properties,这是 SpringBoot 默认读取的属性文件名
步骤二:在 JdbcConfig 中使用这个属性
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig {
@Bean
public DataSource dataSource(JdbcProperties jdbc) {DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(jdbc.getUrl());
dataSource.setDriverClassName(jdbc.getDriverClassName());
dataSource.setUsername(jdbc.getUsername());
dataSource.setPassword(jdbc.getPassword());
return dataSource;
}
}
步骤三:测试(同上:略)
2.4 更优雅的注入
事实上,如果一段属性只有一个 Bean 需要使用,我们无需将其注入到一个类(JdbcProperties)中。而是直接在需要的地方声明即可:
@Configuration
public class JdbcConfig {
@Bean
// 声明要注入的属性前缀,SpringBoot 会自动把相关属性通过 set 方法注入到 DataSource 中
@ConfigurationProperties(prefix = "jdbc")
public DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
}
3 自动配置原理
主要任务:
了解 @SpringBootApplication
默认配置原理
3.1 @SpringBootApplication
该注解下重点注解有 3 个:@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
3.1.1 @SpringBootConfiguration
这个注解的作用就是声明当前类是一个配置类,然后 Spring 会自动扫描到添加了 @Configuration
的类,并且读取其中的配置信息。而 @SpringBootConfiguration
是来声明当前类是 SpringBoot 应用的配置类,项目中只能有一个。所以一般我们无需自己添加。
3.1.2 @EnableAutoConfiguration
@EnableAutoConfiguration
:告诉 SpringBoot 基于你所添加的依赖,去“猜测”你想要如何配置 Spring。比如我们引入了 spring-boot-starter-web
,而这个启动器中帮我们添加了tomcat
、SpringMVC
的依赖。此时自动配置就知道你是要开发一个 web 应用,所以就帮你完成了 web 及 SpringMVC 的默认配置了!
总结,SpringBoot 内部对大量的第三方库或 Spring 内部库进行了默认配置,这些配置是否生效,取决于我们是否引入了对应库所需的依赖,如果有那么默认配置就会生效。
所以,我们使用 SpringBoot 构建一个项目,只需要引入所需框架的依赖,配置就可以交给 SpringBoot 处理了。除非你不希望使用 SpringBoot 的默认配置,它也提供了自定义配置的入口。
3.1.3 @ComponentScan
配置组件扫描的指令。提供了类似与 <context:component-scan>
标签的作用
通过 basePackageClasses 或者 basePackages 属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包
而我们的 @SpringBootApplication 注解声明的类就是 main 函数所在的启动类,因此扫描的包是该类所在包及其子包。因此,一般启动类会放在一个比较前的包目录中。
3.2 默认配置原理
SpringBoot 为我们提供了默认配置,而默认配置生效的条件一般有两个:
1. 你引入了相关依赖
2. 你自己没有配置
启动器:
所以,我们如果不想配置,只需要引入依赖即可,而依赖版本我们也不用操心,因为只要引入了 SpringBoot 提供的 stater(启动器),就会自动管理依赖及版本了。因此,玩 SpringBoot 的第一件事情,就是找启动器,SpringBoot 提供了大量的默认启动器
全局配置
SpringBoot 的默认配置,都会读取默认属性,而这些属性可以通过自定义 `application.properties` 文件来进行覆盖。这样虽然使用的还是默认配置,但是配置中的值改成了我们自定义的
因此,玩 SpringBoot 的第二件事情,就是通过 `application.properties` 来覆盖默认属性值,形成自定义配置。我们需要知道 SpringBoot 的默认属性 key,非常多