专栏首页求道自定义springboot-starter揭秘自动配置骚操作

自定义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的自动装配原理,敬请期待啊!如果读者有好的想法和建议,希望私聊作者!共同学习,共同进步!

本文分享自微信公众号 - JAVA程序狗(javacxg),作者:皇甫嗷嗷叫

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringBoot对全局异常的处理封装

    springMvc为我们提供的全局异常处理很好的解决了我们在开发中对于异常的捕获与控制,他能够监控所有的@Controller注解类,并提供异常捕捉与处理!

    止术
  • 设计原则之单一职责

    上述就违反了单一职责原则,对于不同的交通工具,代码逻辑完全耦合在一起,我们无论修改那一类的交通工具,都会影响其他两种数据

    止术
  • 设计模式之单例模式

    小弟最近在研究设计模式,准备边学边发博客,与众多大佬们交流学习,希望各位能够指出不足之处(废话不多说了,直接开花)** **

    止术
  • 【SpringBoot 基础系列】实现一个自定义配置加载器(应用篇)

    Spring 中提供了@Value注解,用来绑定配置,可以实现从配置文件中,读取对应的配置并赋值给成员变量;某些时候,我们的配置可能并不是在配置文件中,如存在 ...

    一灰灰blog
  • Java 设计模式 适配器模式

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.c...

    亦山
  • 快速学习Mybatis-自定义 Mybatis 框架

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    cwl_java
  • (79) 方便的CompletionService / 计算机程序的思维逻辑

    上节,我们提到,在异步任务程序中,一种常见的场景是,主线程提交多个异步任务,然后希望有任务完成就处理结果,并且按任务完成顺序逐个处理,对于这种场景,Java并发...

    swiftma
  • Java实现计数器 Counter

    最终实现版本使用泛型,使得可以对任意对象进行技术,但是在编写过程中,先以String为例.

    呼延十
  • Java如何实现任务超时处理

    任务超时处理是比较常见的需求,比如在进行一些比较耗时的操作(如网络请求)或者在占用一些比较宝贵的资源(如数据库连接)时,我们通常需要给这些操作设置一个超时时间,...

    黄泽杰
  • 快速掌握模板方法模式

    模板模式就是定义一个操作中的算法骨架,然后将一些步骤延迟到子类中。模板方法使得子类在不改变算法的结构即可重定义该算法的某些步骤。

    田维常

扫码关注云+社区

领取腾讯云代金券