手把手教你开发SpringBoot starter


参考:
https://www.jianshu.com/p/fdb574e1f77c

前言:

SpringBoot在java中的地位简直是至尊的存在,非常的好用。Spring Boot有四大神器,分别是auto-configuration、starters、cli、actuator,我们用各种中间件的话就是各种starter 对应版本依赖引用,然后就是配置属性文件,就可以用了,其实工作当中,我们可以把一些通用的方法,服务来封装成starter,本文来交大家进行手动实现一个starter,满足我们以后工作的需要。

1.源码中的starter和自动配置:

Spring boot开发的时候我们不需要像Springmvc一样各种xml的各种配置写,开箱即用。看源码的话发现这个实现是基于:spring-boot-autoconfigure依赖。里面包含了很多其他的依赖包:
看图:
[外链图片转存中…(img-FzhzENHS-1623147296931)]
看源码里面都有个一个xxxxAAutoConfiguration的类:
rabbitmq:
[外链图片转存中…(img-mph3WCif-1623147296935)]
其中注解说明:

1.@Configuration注解表示这是一个配置类,用过Spring Boot的朋友都应该知道是什么东西,不多做解释了。

2.@ConditionalOnClass({RabbitTemplate.class, Channel.class}),该注解表示当KafkaTemplate.class被加载到JVM中,才会对配置类进行初始化,简单理解就是把他当做if语句来看。

3.@EnableConfigurationProperties({RabbitProperties.class}),加载属性配置类的注解,有这个注解,KafkaProperties才会作用于应用上下文中。

4.@Import({RabbitAnnotationDrivenConfiguration.class}),Spring 的基础注解,不多说了。
Spring boot是通过两个路径来确定自动配置类的,一个是@EnableAutoConfiguration注解,二是spring.factories配置文件,改文件在META-INF目录下面,里面配置了配置项:org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration。

@SpringBootApplication注解是包含@EnableAutoConfiguration注解的,注解里面的核心注解是:@Import(AutoConfigurationImportSelector.class)注解,里面涉及到代码:

 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

就是加载资源配置文件。

流程总结的话就是:应用配置类注解@EnableAutoConfiguration-》导入AutoConfigurationImportSelector-》启动应用加载spring.factories里的配置信息(通过AutoConfigurationImportSelector 、getCandidateConfigurations)-》如果缺少相关依赖类存在,就不会触发执行,触发成功,就会执行。
其中spring.factories不仅仅包含自动配置相关信息,还包含其他的信息。

2.手动实现starter:

我们用springboot的时候加入spring-boot-starter-web依赖,不需要任何配置,就可以直接构建web应用,可见自动配置的厉害,spring是一个扩展性很强的框架,支持我们自定义符合需求的starter。

一个完整的starter包含两个部分:
1.提供自动配置功能的自动配置模块

2.做到开箱即用,提供依赖关系管理的组件模块

spring-boot-autoconfigure中包含的AutoConfiguration都是Spring家族的项目,自己封装的starter就需要自己写xxxAutoConfiguration。

添加依赖:

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

导入配置代码:

@ConfigurationProperties(prefix = "yeonon.car")
public class CarProperties {

    private static final String DEFAULT_NAME = "BWM";
    private static final String DEFAULT_COLOR = "white";
    private static final Integer DEFAULT_AGE = 1;


    private String name = DEFAULT_NAME;

    private String color = DEFAULT_COLOR;

    private Integer age = DEFAULT_AGE;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    //getter 和 setter必须要有,否则属性注入会有问题
}

service代码:

public class CarService {

    private Car car;

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }
}

自动配置类

@Configuration
@ConditionalOnClass(CarService.class)
@EnableConfigurationProperties(value = CarProperties.class)
public class CarAutoConfiguration {

    @Autowired
    private CarProperties carProperties;

    @Bean
    @ConditionalOnMissingBean(CarService.class)
//    @ConditionalOnProperty(value = "yeonon.car.server.configuration.auto.enabled", matchIfMissing = true)
    public CarService carService() {
        CarService carService = new CarService();
        Car car = new Car();
        car.setName(carProperties.getName());
        car.setColor(carProperties.getColor());
        car.setAge(carProperties.getAge());
        carService.setCar(car);
        return carService;
    }
}

注解说明:
@Configuration注解是要有的,否则无法生效。

@ConditionalOnClass(CarService.class),原则上可有可无,但作为一个健壮的starter,还是有的好,作为一个“防御措施”。

@EnableConfigurationProperties(value = CarProperties.class),要使用属性系统,就需要把属性类加入到应用上下文中。

@Bean就是定义一个Bean了,代码逻辑没什么可说的,无法就是创建对象,然后构建对象并返回而已。关键在于@ConditionalOnMissingBean注解和@ConditionalOnProperty注解。@ConditionalOnMissingBean注解的意思就是如果应用中不存在CarService的Bean,那么就执行下面的方法构建一个Bean,已经存在的话,就不会调用下面的方法了,这意味着用户可以自己创建Bean来覆盖系统默认配置的Bean。@ConditionalOnProperty就是当配置存在的时候,才会执行Bean的构建。

然后再资源文件夹下面创建META-INF文件夹,创建spring.factories,配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
top.yeonon.stater.test.CarAutoConfiguration

应用starter:

 @Autowired
    private CarService carService;
   
    @GetMapping("car")
    public Car getMyCar(@AutoLoginInfo LoginInfo loginInfo, @AutoUserInfo UserInfo userInfo) {
        System.out.println(loginInfo);
        System.out.println(userInfo);
        return carService.getCar();
    }

属性配置:

## 注意前缀是yeonon.car,也是在CarProperties类里配置好的
yeonon.car.name=MSLD
yeonon.car.age=2
yeonon.car.color=black

总结

上面的手动实现starter其实是一个标准的实现过程,但是呢,我们实际开发其实并不需要那么麻烦,两个注解搞定starter,第一个注解@EnableMonitor注解在springboot启动类上,然后里面的注解实现:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Import({MetricsConfig.class, MonitorConfig.class})
public @interface EnableMonitor {
}

这样分别在Import里面的类去实现业务逻辑就可以。如果你有问题换用留言,如果你喜欢欢迎点赞,转发,赞赏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值