目录
一 自定义Starter
1 starter依赖介绍与使用原理
1.Starter介绍
Starter场景启动器是Spring Boot中一种非常重要的机制,它将繁琐的配置统一集成到stater中,我们只需要通过在Maven将starter的依赖导入项目,SpringBoot 就能自动扫描并加载相应的默认配置。starter的出现简化了开发人员的工作量,从繁琐的框架配置中解救出来,让更多的时间专注在业务逻辑的开发,提高了开发效率。
2.命名规范
SpringBoot 提供的 starter 以 spring-boot-starter-xxx 的形式命名。为了与 SpringBoot 生态提供的 starter 进行区分,官方建议第三方开发者或技术(例如 Druid、Mybatis 等等)厂商自定义的 starter 使用 xxx-spring-boot-starter 的形式命名,例如 mybatis-spring-boot-starter、druid-spring-boot-starter 等等。
3.模块规范
Spring Boot 官方建议我们在自定义 starter 时,创建两个 Module :autoConfigure Module(SpringBoot模块) 和 starter Module(Maven 模块),其中 starter Module 依赖于 autoConfigure Module。当然,这只是 Spring Boot 官方的建议,并不是硬性规定,若不需要自动配置代码和依赖项目分离,我们也可以将它们组合到同一个 Module 里。
4.自定义Starter
starter启动原理
starter-pom引入 autoconfigure 包
autoconfigure包中配置使用 META-INF/spring.factories 中 EnableAutoConfiguration 的值,使得项目启动加载指定的自动配置类
编写自动配置类 xxxAutoConfiguration -> xxxxProperties
@Configuration //配置类
@ConditionalOnMissingBean //条件装配
@EnableConfigurationProperties(xxxProperties.class) //开启属性绑定功能(在配置文件中修改值)+将绑定类xxxProperties加入容器
@Bean //生成组件
…
引入starter — xxxAutoConfiguration — 容器中放入组件 ---- 绑定xxxProperties ---- 配置项修改
2 新建maven工程
该起始依赖主要用于动态读取配置文件,通过springmvc响应给请求页面
3 引入所需相关依赖
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<groupId>com.demo</groupId>
<artifactId>demo-spring-boot-starter</artifactId>
<version>0.0.1-RELEASE</version>
<name>demo-spring-boot-starter</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
// springmvc需要用到
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
4 定义实体类映射配置信息
package com.demo.starter.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 描述:配置信息 实体
*
**/
// @ConfigurationProperties(prefix = "demo") 它可以把配置文件中叫“demo”的配置项名称映射成实体类,比如我们这里指定 prefix = "demo" 这样,我们就能将以demo为前缀的配置项拿到了。
@ConfigurationProperties(prefix = "demo")
public class DemoProperties {
private String sayWhat;
private String toWho;
public String getSayWhat() {
return sayWhat;
}
public void setSayWhat(String sayWhat) {
this.sayWhat = sayWhat;
}
public String getToWho() {
return toWho;
}
public void setToWho(String toWho) {
this.toWho = toWho;
}
}
5 定义一个service返回信息
package com.demo.starter.service;
/**
* 描述:随便定义一个Service,用于把读取到的配置文件信息返回
*
**/
public class DemoService {
public String sayWhat;
public String toWho;
public DemoService(String sayWhat, String toWho){
this.sayWhat = sayWhat;
this.toWho = toWho;
}
public String say(){
return this.sayWhat + "! " + toWho;
}
}
6 定义一个被spring管理的自动配置类
这里,我们将DemoService类定义为一个Bean,交给Ioc容器。
▲ @Configuration 注解就不多说了。
▲ @EnableConfigurationProperties 注解。该注解是用来开启对3步骤中 @ConfigurationProperties 注解配置Bean的支持。也就是@EnableConfigurationProperties注解告诉Spring Boot 能支持@ConfigurationProperties。
当然了,也可以在 @ConfigurationProperties 注解的类上添加 @Configuration 或者 @Component 注解
▲ @ConditionalOnProperty 注解控制 @Configuration 是否生效。简单来说也就是我们可以通过在yml配置文件中控制 @Configuration 注解的配置类是否生效。
package com.demo.starter.config;
import com.demo.starter.properties.DemoProperties;
import com.demo.starter.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 描述:配置类
*
**/
@Configuration
@EnableConfigurationProperties(DemoProperties.class)
@ConditionalOnProperty(
prefix = "demo",
name = "isopen",
havingValue = "true"
)
public class DemoConfig {
@Autowired
private DemoProperties demoProperties;
@Bean(name = "demo")
public DemoService demoService(){
return new DemoService(demoProperties.getSayWhat(), demoProperties.getToWho());
}
}
7 创建spring.factories文件
新建META-INF文件夹,然后创建spring.factories文件,
在该文件中加入如下配置,该配置指定上步骤中定义的配置类为自动装配的配置。
// spring启动后通过以下路径查找,就能把我们自定义的starter注册进入容器内,实现自动配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.demo.starter.config.DemoConfig
8 maven打包放入本地仓库
在demo-spring-boot-starter工程中执行mvn clean 然后install 一个自定义的starter就放入进本地仓库了。
9 测试
新建一个测试项目
然后打开mavn刷新本地仓库
引入自定义依赖
<dependency>
<groupId>com.demo</groupId>
<artifactId>demo-spring-boot-starter</artifactId>
<version>0.0.1-RELEASE</version>
</dependency>
在application.property中编写配置文件
demo.isopen=true
demo.say-what=hello
demo.to-who=shf
server.port = 8080
编写测试类
package com.example.test.controller;
import com.demo.starter.service.DemoService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
*
**/
@RestController
public class DemoController {
@Resource(name = "demo")
private DemoService demoService;
@GetMapping("/say")
public String sayWhat(){
return demoService.say();
}
}
打开浏览器访问
二 常见问题
自定义starter无法引入,一直爆红
记得要刷新maven,重新扫描本地仓库
spring boot maven install 生成jar含有BOOT-INF ,导致被其他工程依赖时找不到类
自定义的依赖能够被成功引入,但是引入后项目无法使用,一直爆红,这多是因为依赖中含有BOOT-INf,导致被其他工程依赖时找不到类。
解决方法:
首先jar中多了这个BOOT-INF文件夹的原因,主要是因为我们在maven的pom文件中加入了spring-boot-maven-plugin这个插件。 既然知道原因了,那么怎么解决呢?其实非常简单,我们只需要将加个configuration标签,并在里面嵌套加入一个skip子标签,并将skip的值设为true,意思也就是跳过这个插件的配置 .或者直接注释掉
<plugins>
<plugin>
<groupId>org.spingframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass> XXXXX </mainClass>
<skip>true</skip>
</configuration>
</plugin>
</plugins>