一、SpringBoot简介
1.1 什么是SpringBoot
SpringBoot是Spring快速开发的脚手架,通过约定大于配置的方式,快速构建和启动Spring项目
1.2 为什么学习SpringBoot
Spring的缺点:
- 复杂的配置。
项目各种配置是开发时的损耗,写配置挤占了写应用程序逻辑的时间 - 混乱的依赖管理
项目的依赖管理非常繁琐。一旦选错依赖版本,随之而来的就是各种不兼容的bug SpringBoot可以解决以上两个问题
1.3 SpringBoot的特点
- 快速开发Spring应用的框架
- 内嵌Tomcat和Jetty容器,不需要单独安装容器,jar包直接发布一个web应用
- 内嵌maven配置,parent方式,一站式引入需要的各种依赖
- 和各种流行框架,Spring Web MVC、Mybatis、Spring Cloud无缝整合
可以查看官网了解更多细节
二、入门案例
2.1 新建Maven项目
2.2 添加依赖
SpringBoot提供了一个名为spring-boot-starter-parent的构件,里面对常用的依赖版本进行了管理,SpringBoot项目需要以这个项目为父工程。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dmllll</groupId>
<artifactId>spring-boot-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
2.3 启动类
SpringBoot项目通过main函数启动即可,我们需要创建一个启动类: 编写main函数:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
2.4 编写Controller
下面就可以像开发SpringMVC的项目一样了。 编写一个Controller: 代码:
@Controller
@ResponseBody
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello spring boot";
}
}
2.5 启动项目
运行main函数: 访问:http://localhost:8080/hello
三、全注解配置和属性注入
在入门案例中,并没有进行任何的配置,就可以实现一个SpringMVC的项目。如果没有任何的xml,我们如果要配置一个Bean该怎么办?比如我们要配置一个数据库连接池。 学习SpringBoot之前:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
SpringBoot中: 通过Spring全注解配置,主要依靠java类和一些注解。常用注解有:
@Configuration :声明一个类作为配置类,代替xml文件@Bean :声明在方法上,将方法的返回值加入Bean容器,代替<bean> 标签@Value :属性注入@PropertySource :指定外部属性文件
3.1 使用java配置来尝试实现连接池配置
3.1.1 引入连接池依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
3.1.2 创建jdbc.properties文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/aaa
jdbc.username=root
jdbc.password=123
3.1.3 编写配置类
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
@Value("${jdbc.driverClassName}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setUrl(url);
return dataSource;
}
}
@Configuration :声明该类是一个配置类@PropertySource :引入类路径下的jdbc.properties文件@Value :为属性注入值@Bean :将dataSource()方法声明为一个注册bean的方法,Spring会调用该方法,将该方法的返回值加入Spring容器中。默认的对象名id=方法名,可以通过@Bean(“自定义名称”),指定新的对象名,然后就可以在任意位置通过@Autowried注入DataSource。
3.1.4 在HelloController测试
@Controller
@ResponseBody
public class HelloController {
@Autowired
private DataSource dataSource;
@GetMapping("/hello")
public String hello(){
return "hello spring boot"+dataSource;
}
}
3.1.5 debug启动
在hello()中断点,重新访问http://localhost:8080/hello
可以看到dataSource已被注入值
3.1.6 目录结构展示
3.2 SpringBoot属性注入
上面使用了Java配置方式。不过属性注入使用的是@Value注解。这种方式虽然可行,但是只能注入基本类型值。 SpringBoot中提供了一种新的属性注入方式,支持各种Java基本数据类型和复杂类型注入。
3.2.1 新建类,进行属性注入
@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
private String url;
private String driverClassName;
private String username;
private String password;
}
- 在类上通过@ConfigurationProperties注解声明当前类为属性读取类
prefix="jdbc" 读取属性文件中前缀为jdbc的值- 在类上定义各个属性,名称必须与属性文件中
jdbc. 后面部分一致 - 读取时,SpringBoot默认读取application.properties文件,新建application.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/bbb
jdbc.username=abc
jdbc.password=456
- 此时@ConfigurationProperties会报错
3.2.2 新建JdbcConfig2使用JdbcProperties
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig2 {
@Bean("dataSource2")
public DataSource dataSource(JdbcProperties jdbc){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(jdbc.getDriverClassName());
dataSource.setUsername(jdbc.getUsername());
dataSource.setPassword(jdbc.getPassword());
dataSource.setUrl(jdbc.getUrl());
return dataSource;
}
}
- 通过
@EnableConfigurationProperties(JdbcProperties jdbc) 来声明要使用JdbcProperties这个类的对象
3.2.3 修改HelloContoller
@Controller
@ResponseBody
public class HelloController {
@Autowired
private DataSource dataSource2;
@GetMapping("/hello")
public String hello(){
return "hello spring boot"+dataSource2;
}
}
3.2.4 启动项目
可以看到注入的值变为application.properties中的值
3.2.5 SpringBoot注入方式
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig3 {
@Autowired
private JdbcProperties jdbc;
@Bean("dataSource3")
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(jdbc.getDriverClassName());
dataSource.setUsername(jdbc.getUsername());
dataSource.setPassword(jdbc.getPassword());
dataSource.setUrl(jdbc.getUrl());
return dataSource;
}
}
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig4 {
private JdbcProperties jdbc;
public JdbcConfig4(JdbcProperties jdbc) {
this.jdbc = jdbc;
}
@Bean("dataSource4")
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(jdbc.getDriverClassName());
dataSource.setUsername(jdbc.getUsername());
dataSource.setPassword(jdbc.getPassword());
dataSource.setUrl(jdbc.getUrl());
return dataSource;
}
}
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig2 {
@Bean("dataSource2")
public DataSource dataSource(JdbcProperties jdbc){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(jdbc.getDriverClassName());
dataSource.setUsername(jdbc.getUsername());
dataSource.setPassword(jdbc.getPassword());
dataSource.setUrl(jdbc.getUrl());
return dataSource;
}
}
- 直接在@Bean方法上使用@ConfigurationProperties(prefix = “jdbc”)
前提:DruidDataSource 该类必须有对应属性的set方法
@Configuration
public class JdbcConfig5 {
@Bean("dataSource5")
@ConfigurationProperties(prefix = "jdbc")
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
}
3.3 自动配置原理
- 首先查看@SpringBootApplication注解
- 这里有三个重点注解:
-
@SpringBootConfiguration 通过这里可以看到@SpringBootConfiguration是一个配置类,Spring会自动扫描到添加了@Configuration的类,读取其中的配置信息 -
@EnableAutoConfiguration 会开启SpringBoot的自动配置,并且根据你引入的依赖来生效对应的默认配置 -
@ComponentScan 配置组件扫描指令,提供了类似<context:component-scan> 标签的作用;通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包。 @SpringBootApplication注解声明的类就是main函数所在的启动类,因此扫描的包是该类所在包及其子包。因此,一般启动类会放在一个比较前的包目录中
3.3.1 默认配置原理
在项目中引入了spring-boot-autoconfigure依赖,其中定义了大量的自动配置类,几乎涵盖了现在的主流开源框架
3.3.1.1 SpringMVC自动配置解析
打开WebMvcAutoConfiguration:
@Configuration :声明一个配置类@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) 这里的条件是OnClass,也就是满足Servlet、DispatcherServlet、WebMvcConfigurer。其中Servlet只要引入tomcat依赖就会存在,后两个需要引入SpringMVC才会有。这里就是判断你是否引入了相关依赖,引入依赖后该条件成立,当前类的配置才生效@ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) 这里的条件是OnMissingBean,就是说环境中没有指定的Bean才生效。其实这就是自定义SpringMVC配置的入口。也就是说自己配置一个WebMvcConfigurationSupport的类,默认配置就会失效
|