一个初学者对mica-auto的理解

最近因为参加中科院和openEuler主办的开源软件供应链点亮计划 - 暑期2021活动,第一次接触了mica-auto这个利器。从最初的一片迷茫到现在的开始稍微入门,这个过程是艰苦的,所以我希望这篇文章可以帮助到很多像我一样的对mica-auto感兴趣的初学者。

什么是mica-auto

github上的解释是:

mica-auto 是 Spring cloud 微服务框架 Mica 中的一个基础组件,用来生成 Spring boot starter 的一些基础配置。

在我这几天的学习中,我所了解的生成Spring boot starter的一些配置大多为生成 spring.factories。那么首先我们来说一说什么是Spring boot starter.

什么是Spring boot starter

Spring boot starter就是创建SpringBoot应用,tarter是一种服务,使用某个功能的开发者不需要关注各种依赖库的处理,不需要具体的配置信息,由Spring Boot自动通过classpath路径下的类发现并加载需要的Bean。说白了,就是当你写Springboot项目时,如果你想用mybatisplus,那么你就引入mybatisplus的依赖,如果你想要RabbitMQ,那么你就引入RabbitMQ的依赖,实现开箱即用,而不用手动引入jar包,方便开发人员的操作。

那么问题就来了,Spring boot starter这个东西这么好用,我可不可以开发一个自己的Spring boot starter呢?答案是肯定的,于是昨天晚上我参考网上实现了一个自己的Spring boot starter

如何实现一个自己的Spring boot starter

我这个Spring boot starter功能是将Java对象转化为Json字符串,并在字符串前加一个名称,支持通过配置文件的方式来配置

如何命名

官网发布的为Spring-boot-starter-xxx
而我们应该xxx-Spring-boot-starter

第一步

新建Maven项目,在项目pom.xml文件引入所需依赖
如图:
在这里插入图片描述

第二步

新建配置类,写好配置和默认配置项,指明配置项前缀 -> xxxProperties.java
如图:
在这里插入图片描述

第三步

新建自动装配类,使用@Configuration和@Bean来进行自动装配 -> xxxAutoConfiguration.java
如图:
在这里插入图片描述

第四步

新建spring.factories文件,指定starter的自动装配
里面写:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.lyh.myjson.config.MyJsonAutoConfiguration

第五步

我使用的是IDEA,所以自带mvn install,右侧Maven找到install并双击,则可将该项目打包,完成自己的一个starter。
我使用的是Linux系统,所以打包好的文件在/.m2/repository/org/example/myjson-spring-stater
如图:在这里插入图片描述

最后项目结构为:在这里插入图片描述

第六步

测试:新建一个spring-boot项目,在pom.xml文件里引入自己的starter,如图:
在这里插入图片描述
spring-boot项目结构:
在这里插入图片描述
MyJsonController文件:

package com.lyh.myjson.controller;

import com.lyh.myjson.pojo.User;
import com.lyh.myjson.service.MyJsonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyJsonController {
    private MyJsonService myJsonService;

    @Autowired
    public MyJsonController(MyJsonService myJsonService){
        this.myJsonService = myJsonService;
    }

    @GetMapping("/user")
    public String getJsonStr(){
        User user = new User();
        user.setUserId(100);
        user.setUserName("Tom");
        user.setAge(60);

        return myJsonService.ObjectToJson(user);
    }

}

pojo文件:

package com.lyh.myjson.pojo;

import lombok.Data;

@Data
public class User {
    private Integer userId;
    private String userName;
    private Integer age;
}

.yml文件

server:
  port: 8080
lyh:
  json:
    name: com.lyh

最后的测试结果:
在这里插入图片描述
说明我写的Spring-boot-starter成功。

spring.factories机制

类似java中的SPI机制,它在META-INFO/spring.factories文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化。

实现原理

pring -core 包里定义了SpringFactoriesLoader 类,这个类实现了检索META-INF/spring.factories文件,并获取指定接口的配置的功能。 在这个类中定义了两个对外的方法:

loadFactories 根据接口类获取其实现类的实例,这个方法返回的是对象列表
loadFactoryNames 根据接口获取其接口类的名称,这个方法返回的是类名的列表。
上面两个方法的关键都是从指定的ClassLoader中获取spring.factories文件,并解析得到类名列表

Spring boot starter原理

利用starter实现自动化配置只需要两个条件——maven依赖、配置文件。引入maven实质上就是导入jar包,spring-boot启动的时候会找到starter jar包中的resources/META-INF/spring.factories文件,根据spring.factories文件中的配置,找到需要自动配置的类。
配置类上面包括以下注解

实现原理

@Configuration 表明是一个配置文件,被注解的类将成为一个bean配置类

@ConditionalOnClass 当classpath下发现该类的情况下进行自动配置

@ConditionalOnBean 当classpath下发现该类的情况下进行自动配置

@EnableConfigurationProperties 使@ConfigurationProperties注解生效

@AutoConfigureAfter 完成自动配置后实例化这个bean
在这里插入图片描述

getAutoConfigurationEntry()方法

private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();

AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
        //<1>.
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            //<2>.
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            //<3>.
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            //<4>.
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

第 1 步:
判断自动装配开关是否打开。默认spring.boot.enableautoconfiguration=true,可在 application.properties 或 application.yml 中设置

第 2 步 :
用于获取EnableAutoConfiguration注解中的 exclude 和 excludeName。

第 3 步
获取需要自动装配的所有配置类,读取META-INF/spring.factories,所有需要的spring.factories都会被读取,这一步会进行筛选,@ConditionalOnXXX 中的所有条件都满足,该类才会生效。

mica-auto基于 SpringBoot

mica-auto 基于 SpringBoot 配置注解自动生成 SpringBoot 部分配置文件,其原理是扫描引用了@Component注解或者包含@Component的组合注解的类,自动生成相应的配置

基于此特性,我们可以编写自定义Starter时不再需要autoconfigurer模块,因为mica-auto会自动为我们扫描引用了@Configuration的配置类,而该注解是一个包含了@Component的组合注解,并且自动创建META-INF/spring.factories文件,将配置类全路径名自动写入该文件。
具体的demo还没有试过,下周继续学习。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值