授课环境:
● Java8以上
● Maven3.3以上
● SpringBoot 2.3.4
为解决Spring生态圈中组装多组件,组装系列技术栈的问题(配置地狱),SpringBoot应运而生。
简化了Spring应用的初始搭建以及开发过程,提高效率。它是整合Spring技术栈的一站式框架。
● 优点
(1) 创建独立的Spring应用
(2) 内嵌web服务器(无需我们自己再安装Tomcat等容器)
(3) 自动starter依赖(简化第三方jar包的引入,并保证jar包之间的版本兼容问题,直接使用它的启动器)
(4) 自动配置Spring以及第三方功能(没有配置地狱)
(5) 提供生产级别的监控、健康检查及外部化配置
(6) 无额外代码、xml配置文件生成
● 缺点
(1) 人称版本低,迭代快,需要时刻关注变化
(2) 封装太深,内部原理复杂,不容易精通
一、快速入门
(0) 修改maven的核心配置文件:添加镜像、使用jdk1.8
settings.xml
<settings>
...
<!-- 使用阿里云镜像下载依赖,提高下载速度 -->
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
<!-- 设置Java项目为使用JDK1.8 -->
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
...
</settings>
(1) 创建maven项目,并在pom.xml中做相关配置。
● spring-boot-starter-parent
指定Spring Boot项目的父工程,它提供了默认的配置和插件来帮助简化项目构建和依赖管理。
● spring-boot-starter-web
指定构建Web应用所需的依赖项,包括:Spring MVC、Spring Web、Tomcat、Jackson等其他相关的依赖项,简化了Web应用的开发和部署。
pom.xml
<project...>
自己项目的坐标
<!-- Spring Boot项目的父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<parent>
<!-- Spring Boot构建Web应用的依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 由父项目做依赖管理,这里不需要写版本号 -->
</dependency>
</dependencies>
</project>
(2) 创建主程序类(也叫主配置类)【固定写法】
● @SpringBootApplication:指定是一个SpringBoot应用
● SpringApplication.run(主程序class, args):
// 主程序类
@SpringBootApplication
public class MainApplication{
public static void main(String[] args){
SpringApplication.run(MainApplication.class, args);
}
}
// 进行业务逻辑的编写
@Controller
@ResponseBody
// 也可以使用@RestController,它是@Controller和@ResponseBody的复合组件
public class HelloController{
@RequestMapping("/hello")
public String hello(){
return "hello";
}
}
(3) 编写配置文件application.properties【固定写法】
它帮我们简化了SpringMVC、Tomcat等组件的配置,直接在application.properties用键值对的形式修改即可。
application.properties(main目录→resources目录→application.properties)
server.port=8888 # 举例:修改Tomcat的端口号
(4) 简化部署
引入SpringBoot提供的【插件】,无需我们在服务器上部署war包,只需要打成简单的jar包(fat-jars,里面内置了Tomcat等...),放到服务器上,服务器就可以用这个jar包运行。
pom.xml
<project...>
...
坐标
<packaging>jar</packaging> <!-- 打包成jar -->
...
<dependencies>
...
</dependencies>
<!-- 引入插件,简化部署 -->
<build>
<plugins>
<plugin>
<!-- 插件的坐标信息 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- 由父项目做依赖管理,这里不需要写版本号 -->
</plugin>
</plugins>
</build>
</project>
在服务器上,使用以下命令运行jar包即可。
java -jar jar包文件名.jar
二、SpringBoot特点
2.1 依赖管理
(1) ● spring-boot-starter-parent还有父项目 ● spring-boot-dependencies
● spring-boot-dependencies:几乎声明了所有开发中常用的依赖的版本号,所以一般情况下,我们引入自己的依赖,不需要写版本号,除非有特殊需求,可以重写。
(2) 场景启动器:只要引入某一个场景启动器,那么就会自动引入这个场景所有的常规依赖。
● spring-boot-starter-*:SpringBoot内部给我们提供的各种场景,可以在官方文档中查找。
● 也可以自己创建starter,推荐命名:*-spring-boot-starter。
● spring-boot-starter:场景启动器最底层的依赖。
(3) 版本重写的两种方式
● 在自己项目的pom.xml中使用<property>+自定义标签,重写
● 在自己项目的pom.xml对应的依赖项中直接写<version>
2.2 自动配置
2.2.1 扫描包路径
● 默认情况下:主程序所在的父目录
● 更改扫描包路径
方式1:@SpringBootApplication(scanBasePackages="...")
它的本质是复合注解,包含:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
方式2:@ComponentScan("...")
2.2.2 自动配置项
● SpringBoot中的自动配置通常会伴随着一个对应的Properties类,它会给里面的每一个配置提供默认值。
● 我们可以通过application.properties修改某个配置的值,它会绑定在某个Properties类中,这个Properties类会在容器中创建对象。
● spring-boot-autoconfigure包:实现了SpringBoot的所有自动配置功能,想要使用包里的某个类,必须引入相应场景的starter依赖。
三、容器功能
3.1 使用注解完成容器功能
3.1.1 @Configuration
使用一个Java类替代Spring.xml(声明各种Bean),只需要在它上面@Configuration,这个配置类本身也是组件。
重要属性
● proxyBeanMethods 是否代理Bean方法
(假定在配置类中使用@Bean对两个类分别创建对象)
@Configuration
public class MyConfig{
@Bean
public User user1(){
User u = new User(1, "张三");
u.setPet(pet1());
return u;
}
@Bean
public Pet pet1(){
Pet p = new Pet("狸花猫");
return p;
}
}
● 注意如果在@Bean中不指定值,默认创建的对象id为方法名!
● true(Full Mode,默认):表示每次从配置类中调用方法时,返回的Bean,要先从容器中找,如果找不到,再去创建,放入容器。【保证单例】
⭕ 最佳实践:存在组件依赖关系。例如user对象依赖pet,希望每次获取的pet是同一个。
● false(Lite Mode):不从容器中找,也不放入容器,直接创建。【运行快】
⭕ 最佳实践:单纯注册组件,该组件不被任何其他组件依赖。
3.1.2 @Import
● 功能:添加一个新的对象到容器中
● 作用于:组件之上
● 语法:@Import({X1.class, X2.class, ...})
(1) 用于Configuration组件上:方便地将多个配置类组合在一起
@Configuration
@Import({DatabaseConfig.class, WebConfig.class})
public class AppConfig {
// ...
}
(2) 用于非Configuration组件上:方便组件的使用
@import({User.class, Pet.class})
@Component
public class test{
@Autowired
private Pet pet;
@Autowired
private User user;
}
3.1.3 @Conditional
● 功能:条件装配,当满足条件时,才进行后续的组件注入。
● 作用于:组件
(1) 当加在普通的组件上(如:@Bean、@Component等),满足条件时,才会将该组件加入到容器中。
(2) 当加在@Configuration配置类组件上,满足条件时,才会将该类中所有声明的组件加入到容器中。
3.1.4 @ImportResource
将(原生)Spring配置文件(声明了诸多Bean)应用起来,即将里面的Bean加入到容器中。
我们原来是在web.xml中利用 <context-param> + contextLoaderListener 配置contextConfigPath来指定Spring配置文件的位置;
● 在使用了SpringBoot后,没有了web.xml,但又想用Spring.xml,该如何告诉SpringBoot?——@ImportResource("classpath:Spring.xml"),它会自动将配置文件中的Bean加入到容器中。
利用创建的DispatcherServlet中的<init-param> 配置contextConfigPath来指定SpringMVC配置文件的位置。
● 在使用了SpringBoot后,可以省略SpringMVC配置文件。
3.1.5 properties配置文件自动装配
可以通过两种方式,将写在【application.properties】中的值,自动装配。
● 方式一:@Component + @ConfigurationProperties(prefix="指定properties中键的前缀【后缀就是当前被自动装配的变量名】")
● 方式二:@EnableConfigurationProperties(X.class)
它会开启X类中的配置装配,并且创建X组件,加入到容器中
四、自动配置原理(入门)
4.1 引导加载自动配置类
● @EnableAutoConfiguration(@SpringBootApplication复合注解中的一个)
它也是一个复合注解,里面有:
● @AutoConfigurationPackage
这个注解的作用:将当前包及其子包中所有的@Configuration标注的类进行【注册】,但这个注册不是直接注册自定义Bean,而是注册自动配置类,注册包路径信息,以确保自动配置类能够正确被扫描到。
● @Import(AutoConfigurationImportSelector.class)
这个注解的作用:找到所有META-INF/spring.factories文件,并将其中写死的自动配置类全部加载
4.2 按需开启自动配置项
尽管默认将所有的自动配置类加载进来,但是它会按照【条件装配】,只有导入了对应的包,才会生效。
4.3 定制化修改自动配置
以MultipartResolver为例,需要配置的名字为multipartResolver,但是可能用户配置的命名不符合规范,那么就获取过来,给你改回来。
4.4 总结 ⭐
(1) SpringBoot先加载所有的自动配置类XxxAutoConfiguration,但并不是全部生效(按条件装配)。
(2) 这些配置类中的组件都有默认的值→从XxxProperties类里面拿,而这些Properties又和application.properties配置文件进行了绑定。
(3) 生效的配置类会给容器装配很多组件,只要将组件放入容器中,对应的功能就有了。
(4) 只要有用户自己配置的,就以用户的优先。
(5) 定制化配置
● 使用@Configuration + @Bean替换底层默认组件
● 修改application.properties【更常用】
4.5 使用SpringBoot的最佳实践
(1) 引入场景依赖
可以在官方文档查:Developing with Spring Boot
(2) 查看自动配置了哪些(选做)
● 自己分析
● 在application.properties中开启debug模式,会生成自动配置报告。Negative(不生效)、Postive(生效)
application.properties
debug=true
(3) 是否需要修改
① 修改配置文件项
● 参照官方文档:Common Application Properties (spring.io)
● 自己分析绑定了什么XxxProperties类
② @Configuration中自定义加入或替换组件
@Bean、@Component...
③ @EnableWebMvc 使得WebMvcAutoConfiguration失效,只保留了最底层必须的组件,需要自己进行全面接管
WebMvcAutoConfiguration起作用的条件之一:
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)——@EnableWebMvc的类继承了它
【慎用】可以自己实现WebMvcConfigurer接口 + 使用@Bean
五、开发小技巧
5.1 Lombok:简化JavaBean开发
(1) 引入依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- 版本spring-boot-dependencies管理了这个依赖的版本 -->
</dependency>
(2) 安装插件
(3) 添加注解
● @Data:包含getter、setter、equals、hashCode、toString等
● @NoArgsConstructor
● @AllArgsConstructor
public class User(){
private Integer id;
private String name;
private Pet pet;
// 自定义构造器,可以自己生成
public User(Integer id, String name){
this.id = id;
this.name = name;
}
}
5.2 dev-tools(developer-tools):自动重新构建项目
(1) 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
(2) 【ctrl + F9】 → 项目更改后,重build项目
5.3 Spring Initializer【常用】⭐
在创建项目时,有Spring Initializer,它能帮助我们快速的创建SpringBoot应用,一站式搭建好初始架构。(项目初始化向导)
● 实现了添加starter场景、常用插件(如,打fat-jars包)的友好可视化界面。进行响应的勾选就可以自动帮我们引入各种starter、插件等,方便开发。
● 自动帮我们创建了项目结构(目录),创建了application.properties配置文件。并帮助我们创建了主程序。