Spring Boot starter
我们知道Spring Boot大大简化了项目初始搭建以及开发过程,而这些都是通过Spring Boot提供的starter来完成的。在实际项目中一些基础模块其本质就是starter,所以我们需要对Spring Boot的starter有一个全面深入的了解,这是我们的必备知识。
starter介绍
spring boot 在配置上相比spring要简单许多, 其核心在于spring-boot-starter, 在使用spring boot来搭建一个项目时, 只需要引入官方提供的starter, 就可以直接使用, 免去了各种配置。starter简单来讲就是引入了一些相关依赖和一些初始化的配置。
Spring官方提供了很多starter,第三方也可以定义starter。为了加以区分,starter从名称上进行了如下规范:
-
Spring官方提供的starter名称为:spring-boot-starter-xxx
例如Spring官方提供的spring-boot-starter-web
-
第三方提供的starter名称为:xxx-spring-boot-starter
例如由mybatis提供的mybatis-spring-boot-starter
starter原理
Spring Boot之所以能够帮我们简化项目的搭建和开发过程,主要是基于它提供的起步依赖和自动配置。
起步依赖
起步依赖,其实就是将具备某种功能的坐标打包到一起,可以简化依赖导入的过程。例如,我们导入spring-boot-starter-web这个starter,则和web开发相关的jar包都一起导入到项目中了。如下图所示:
自动配置
自动配置,就是无须手动配置xml,自动配置并管理bean,可以简化开发过程。那么Spring Boot是如何完成自动配置的呢?
自动配置涉及到如下几个关键步骤,我们可以将自动配置的关键几步以及相应的注解总结如下:
1、@Configuration与@Bean:基于Java代码的bean配置
2、@Conditional:设置自动配置条件依赖
3、@EnableConfigurationProperties与@ConfigurationProperties:读取配置文件转换为bean
4、@EnableAutoConfiguration与@Import:实现bean发现与加载
关键注解解释
@Configuration和@Bean这两个注解一起使用就可以创建一个基于java代码的配置类,可以用来替代传统的xml配置文件。
@Configuration 注解的类可以看作是能生产让Spring IoC容器管理的Bean实例的工厂。
@Bean 注解的方法返回的对象可以被注册到spring容器中。
@ConfigurationProperties注解,这个注解的作用就是把yml或者properties配置文件中的配置参数信息封装到ConfigurationProperties注解标注的bean的相应属性上。
@EnableConfigurationProperties注解的作用是使@ConfigurationProperties注解生效。
@SpringBootConfiguration:标注这个类是一个配置类; 它只是@Configuration注解的派生注解; 它与@Configuration注解的功能一致; 只不过@SpringBootConfiguration是springboot的注解,而@Configuration是spring的注解。
@ComponentScan:作用就是自动扫描并加载符合条件的组件,最终将这些bean加载到spring容器中
@EnableAutoConfiguration :这个注解很重要,借助@Import的支持,收集和注册依赖包中相关的bean定义
这些注解是spring boot特有的,常见的条件依赖注解有:
注解 | 功能说明 |
---|---|
@ConditionalOnBean | 仅在当前上下文中存在某个bean时,才会实例化这个Bean |
@ConditionalOnClass | 某个class位于类路径上,才会实例化这个Bean |
@ConditionalOnExpression | 当表达式为true的时候,才会实例化这个Bean |
@ConditionalOnMissingBean | 仅在当前上下文中不存在某个bean时,才会实例化这个Bean |
@ConditionalOnMissingClass | 某个class在类路径上不存在的时候,才会实例化这个Bean |
@ConditionalOnNotWebApplication | 不是web应用时才会实例化这个Bean |
@AutoConfigureAfter | 在某个bean完成自动配置后实例化这个bean |
@AutoConfigureBefore | 在某个bean完成自动配置前实例化这个bean |
自定义 Starter 起步依赖
假设我们需要开发一个框架,配置需要用户在 properties 文件中自己定义 url 、port、username、password 四个字段,如下所示:
hello:
url: 10.38.233.22
port: 8868
username: 刘培强
password: 123456789
这和我们自定义数据库的配置文件类似,当用户使用我们的依赖时只需要导入坐标依赖和配置如上属性即可;
我们参考starter的原理可以分为四步来实现自定义的starter依赖:
- 创建配置属性类
- 创建服务类
- 创建自动配置类
- 在resources目录下指定需要开启的自动配置类
以上四个步骤对应的模块如下面红色矩形框起来的,下面将详细讲解四个模块!
开始之前需要导入spring的起步依赖:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>hello-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Archetype - hello-spring-boot-starter</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
创建配置属性类(HelloProperties)
有四个字段,和普通的实体类一样,设置get和set方法;唯一不一样的地方需要特别注意,@ConfigurationProperties(prefix = “hello”),表示这个类是配置属性类,作用是读取用户配置中的hello属性下的字段包装成一个属性类,特别注意回头看上面配置中的hello。只需要将配置中的属性字段与类中的属性一一对应即可。
package com.example.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "hello")
public class HelloProperties {
private String url;
private String port;
private String username;
private String password;
public void setUrl(String url) {
this.url = url;
}
public void setPort(String port) {
this.port = port;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public String getPort() {
return port;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
创建服务类(HelloService)
这个类是真正实现业务逻辑的类,它需要依赖上一步属性类HelloProperties获得的用户配置,然后实现一些功能!
package com.example.service;
public class HelloService {
private String url;
private String port;
private String username;
private String password;
public HelloService(String url, String port, String username, String password) {
this.url = url;
this.port = port;
this.username = username;
this.password = password;
}
public String ConnectSystem() throws InterruptedException {
/**
* do something.......
*/
System.out.println("连接中>>> "+url+":"+port);
Thread.sleep(1000);
System.out.println("认证中>>> "+username);
Thread.sleep(1000);
System.out.println("连接成功>>>"+ username +"中校您好!您已成功连接到国防系统");
return "链接地址:"+url+":"+port+","+"访问者:"+username+"中校";
}
}
创建自动配置类(HelloServiceAutoConfiguration)
这个类的作用就是将第一步的属性类HelloProperties的数据传给第二步的服务类HelloService的对象,并在容器中实例化该此类。需要将其指定为@Configuration 用来指明为配置类 并且用@EnableConfigurationProperties(HelloProperties.class) 开启自动配置。
package com.example.config;
import com.example.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 配置类,基于Java代码的bean配置
* 作用:将properties的配置文件的字段自动加载到HelloProperties类中
*/
@Configuration //指明配置类
@EnableConfigurationProperties(HelloProperties.class) //开启自动配置
public class HelloServiceAutoConfiguration {
@Autowired
private HelloProperties helloProperties;
//实例化HelloService并载入Spring IoC容器
@Bean
@ConditionalOnMissingBean //条件:容器中没有Bean才创建
public HelloService helloService(){
return new HelloService(helloProperties.getUrl(),helloProperties.getPort(),helloProperties.getUsername(),helloProperties.getPassword());
}
}
在resources目录下创建META-INF/spring.factories
上一步中我们只是指定了HelloServiceAutoConfiguration为配置类,但是没有加载此类,因此我们需要告诉Spring容器去加载此配置类,在resources目录下创建META-INF/spring.factories并指定自动加载的配置类。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.config.HelloServiceAutoConfiguration
最后使用maven将我们的自定义starter依赖进行安装,如果不会请百度!
使用自定义依赖
创建maven工程myapp并配置pom.xml文件
<!--导入自定义starter-->
<dependency>
<groupId>cn.itcast</groupId>
<artifactId>hello-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
创建application.yml文件
package com.example.controller;
import com.example.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/connectSystem")
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/hello")
public String hello() throws InterruptedException {
return helloService.ConnectSystem();
}
}
创建启动类HelloApplication
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class,args);
}
}
访问链接:loaclhost:8080/connectSystem/hello
代码下载:https://download.csdn.net/download/cj151525/87944694