自定义springboot-starter揭秘自动配置骚操作
SpringBoot的自动配置
springBoot为什么能够0配置?
这个问题需要我们去看一下SpringBoot的源码,先看一下流程图:
==SpringBoot会自动扫描类路径下的 META-INF/spring.factories
文件,根据配置加载配置文件,完成自动配置==
spring.factories这个主要是提供了一个功能,就是自动配置,不需要使用@EnableXXX来开启,也就是说只要你用了springboot,并且依赖了一个jar包,这个jar包就会自动进行初始化 ,那么这个过程就是使用了spring.factories这个文件配置
为什么会有SrringBoot的自动配置?
举一个应用场景:有一个B项目引用A项目,但是默认情况下@SpringApplication只会扫描类路径下的bean所以A项目的注解就扫描不到!解决这个的办法一个是在B项目上配置扫描A的注解Scan 一种就是让A项目在B项目引用时,自动配置!
如何编写自动配置呢?
pom资源
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
</dependencies>
1.编写配置类,用来映射application.yml里面的参数配置,使我们的自定义组件能够通过配置完成一些特定的功能
注意:@ConfigurationProperties 会飘红线 暂且不用管,是因为没有指定配置所导致的,后面会写
package com.my.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 配置对应类
* @author huangfu
*/
@ConfigurationProperties("example.service")
public class ExampleServiceProperties {
private String prefix;
private String suffix;
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public ExampleServiceProperties(String prefix, String suffix) {
this.prefix = prefix;
this.suffix = suffix;
}
public ExampleServiceProperties() {
}
}
解释:==@ConfigurationProperties("example.service")== 对应 application.yml
的前缀
==例如:==
example:
service:
prefix: @@
suffix: ##
以上这个配置就能对应上面的配置信息类
2.编写一个服务 完成我们所需要的功能
这个例子:功能是为在传入参数上面增加一个前缀和后缀!前缀和后缀可以通过yml来配置
package com.my.service;
/**
* 添加自定义前缀+后缀
* @author huangfu
*/
public class ExampleService {
private String prefix;
private String suffix;
public ExampleService(String prefix, String suffix) {
this.prefix = prefix;
this.suffix = suffix;
}
public String join(String content){
return prefix + content + suffix;
}
}
3.编写配置类
package com.my.conf;
import com.my.properties.ExampleServiceProperties;
import com.my.service.ExampleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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;
/**
* @EnableConfigurationProperties 当classpath下发现该类的情况下进行自动配置。
* @author huangfu
*/
@Configuration
@EnableConfigurationProperties(ExampleServiceProperties.class)
public class ExampleAutoConfigure {
@Autowired
private ExampleServiceProperties exampleServiceProperties;
@Bean
/**
* @ConditionalOnProperty 当yml 配置example.service.enabled=true 时,才会触发
* 仅当 BeanFactory 中不包含指定的 bean class 和/或 name 时条件匹配
*/
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "example.service" , value = "enabled" ,havingValue = "true")
public ExampleService exampleService(){
return new ExampleService(exampleServiceProperties.getPrefix(),exampleServiceProperties.getSuffix());
}
}
4.最后一步
在==resources==目录下创建 META-INF/spring.factories文件
,并将配置类 ExampleAutoConfigure
配置进 spring.factories文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.my.conf.ExampleAutoConfigure
引用
打包之后,在其他项目引用
<dependency>
<groupId>com.example</groupId>
<artifactId>example-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
配置配置文件
example:
service:
suffix: 我是后缀
prefix: 我是前缀
enabled: true
在使用的地方直接引用
@Autowired
private ExampleService exampleService;
public String example(String content){
return exampleService.join(content);
}
结果
肺腑之言:
在业务逻辑中,如果大家遇到注入此类的需求中,大家一定不要敷衍了事,这类脱离CRUD的需求,小公司的普通码农很难遇见,所以一定要好好设计里面的每一个逻辑代码,使其有更好的扩展性,低耦合性!写代码时多想,多画图,不要一上来就啪啪啪写代码,这个习惯我觉的很不好!
哈哈,上面也是作者的心里话,不喜勿喷!下次文章是SpringBoot的自动装配原理,敬请期待啊!如果读者有好的想法和建议,希望私聊作者!共同学习,共同进步!
- 用R语言做逻辑回归
- 当Java虚拟机遇上Linux Arena内存池
- Activiti学习——Activiti与Spring集成
- spring boot 发送邮件
- spark 2.0主要特性预览
- y叔的ChIP-seq数据分析大礼包
- springboot的Web开发-Web相关配置
- Centos7下yum安装配置nginx与php
- CentOS7安装MySQL
- 分布式系统唯一ID生成方案汇总
- 操作系统底层技术——CPU亲和性
- AngularJS例子 ng-repeat遍历输出 通过js的splice方法删除当前行
- mongoDB报错Cannot find module '../build/Release/bson'
- 计算机视觉处理三大任务:分类、定位和检测
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- R语言对混合分布中的不可观测与可观测异质性因子分析
- R替换函数gsub
- R语言泊松回归对保险定价建模中的应用:风险敞口作为可能的解释变量
- asp dotnet core 提供大文件下载的测试
- R语言模拟人类生活预期寿命动态可视化动画图gif
- Python遍历字典
- R语言随机森林模型中具有相关特征的变量重要性
- WPF 使用 Direct Manipulation 的方法
- R语言分析负利率下金融市场:负利率和年金价值的变化
- python字典-增、删、改
- C# dotnet 使用判断文件夹存在的方法判断一个文件路径会怎样
- 怎样给wordpress网站模板,添加最新文章、随机文章、热评文章?
- [医疗信息化][DICOM教程]1.使用Java的DICOM基础-理解DICOM文件-DICOM Basics using Java - Making Sense of the DICOM File
- python自动播放网课
- Istio实战——流量管理