Springboot conditional和starter原理解析

615 阅读2分钟

conditional注解解析

介绍

含义:基于条件的注解

作用:根据是否满足某一个特定条件来决定是否创建某个特定的Bean

意义:Springboot实现自动配置的关键基础能力

创建的conditional注解

//当某个bean存在时才会生效
@ConditionalOnBean
//当某个bean不存在时才会生效
@ConditionalOnMissingBean
//当某个class存在时才会生效
@ConditionalOnClass
//当某个class不存在时才会生效
@ConditionalOnMissingClass
//当前是否处于web环境
@ConditionalOnWebApplication
@ConditionalOnNotWebApplication
//是否包含特定属性
@ConditionalOnProperty
//包含特定版本Java
@ConditionalOnJava

自定义conditional注解实现 实现一个自定义注解并引入Conditional注解

/**
 * @author Y2M
 * @createTime 2021/7/31
 * @comment
 */
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MyCondition.class)
public @interface MyConditionAnnotation {

    String[] value() default {};

}

实现Condition接口重写matches方法,符合条件返回true

/**
 * @author Y2M
 * @createTime 2021/7/31
 * @comment
 */
public class MyCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Object[] properties = metadata.getAllAnnotationAttributes("com.ecit.learn.condi.MyConditionAnnotation").get("value").toArray();
        for (Object property : properties) {
            if (StringUtils.isEmpty(context.getEnvironment().getProperty(property.toString()))){
                return false;
            }
        }
        return true;
    }

}

自定义注解引入Condition接口实现类

动手搭建starter

介绍:可插拔插件,与jar不同的是,starter能实现自动配置,大幅度提升开发效率。

常用starter

image.png

搭建starter

  1. 新建SpringBoot项目
  2. 引入spring-boot-autoconfigure依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
  1. 编写属性源及配置类
@ConfigurationProperties(prefix = "weather")
public class WeatherSource {

    private String type;

    private String rate;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getRate() {
        return rate;
    }

    public void setRate(String rate) {
        this.rate = rate;
    }
}
public class WeatherService {

    private WeatherSource weatherSource;

    public WeatherService(WeatherSource weatherSource) {
        this.weatherSource = weatherSource;
    }

    public String getType(){
        return weatherSource.getType();
    }
    public String getRate(){
        return weatherSource.getRate();
    }
}
@Configuration
@EnableConfigurationProperties(WeatherSource.class)
@ConditionalOnProperty(name = "weather.enable",havingValue = "enable")
public class WeatherAutoConfiguration {

    @Autowired
    private WeatherSource weatherSource;

    @Bean
    @ConditionalOnMissingBean(WeatherService.class)
    public WeatherService weatherService(){
        return new WeatherService(weatherSource);
    }

}
  1. 在spring.factories中添加自动配置类实现
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ecit.weather.WeatherAutoConfiguration

使用starter步骤

在pom引入依赖

<dependency>
    <groupId>com.ecit</groupId>
    <artifactId>weather-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

配置文件配置相关starter自定义的属性

weather.type=rain
weather.rate=serious
weather.enable=enable

类中引用服务

服务调用能力

starter原理解析

  1. 启动类上@SpringBootApplication
  2. 引入AutoConfigurationImportSelector
  3. ConfigurationClassParser中处理
  4. 获取spring.factories中EnableAutoConfiguration实现

image.png

starter自动配置类过滤

image.png