美文网首页
自定义starter

自定义starter

作者: 68公园 | 来源:发表于2019-12-09 19:49 被阅读0次

    SpringBoot 自定义starter

    SpringBoot 自定义starter 被加载机制简介

    SpringBoot 初始化的时候会通过扫描classpath下所有META-INF文件夹下的spring.factories文件,获取文件中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的值,将其解析后加入SpringIoC容器中。

    自定义starter常用注解解释

    • @Configuration

      此注解用来定义一个配置类,可以替换xml配置;被注解的内部包含一个或者多个被@Bean注解的方法,这些方法将被加载到SpringIOC容器中,被注解@Bean的方法,默认情况下方法名将作为容器中bean的id。

    • @Conditional

      此注解可以注解到类上也可以注解到方法上,来决定是否需要执行;此注解需要配合一个或者多个实现Condition接口的类来使用,该类需要重写一个matches()方法,方法返回true则表示执行,返回false表示不执行。

      注意 此类需要通过SpringBoot自动装配的机制将其加载到SpringIoC容器中才会生效

    @Slf4j
    public class BeforeGirlCondition implements Condition {
      /**
       * @param conditionContext      上下文信息
       * @param annotatedTypeMetadata 注解的元信息
       * @return
       */
      @Override
      public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
          // 获取上下文环境中的配置文件信息
          String threeBoy = conditionContext.getEnvironment().getProperty("girl.info.threeBoy");
          log.info("BeforeGirlCondition --> threeBoy:{}",threeBoy);
          if (threeBoy != null) {
              return true;
          }
          return false;
      }
    
    }
    

    推荐使用方式实在方法上使用,如果TestCondition返回true则执行这个Bean,如果返回false则不执行。

    @Bean
    @Conditional({BeforeGirlCondition.class})
    public BeforeGirlFriend beforeGirlFriend() {
        return new BeforeGirlFriend();
    }
    
    • @ConditionalOnProperty

    当上下文环境中存在girl.info.threeBoy=aaron的时候,会触发此配置的执行

    @ConditionalOnProperty(prefix = "girl.info", name = {"threeBoy"}, havingValue = "aaron")
    public BeforeGirlFriend beforeGirlFriend() {
        return new BeforeGirlFriend();
    }
    
    • @ConditionalOnBean

    当上下文中存在配置的名称为“threeBoy”bean的时候,才会触发加载。

    注意: 因为Spring加载bean的顺序是最后才加载@Configuration下的bean,所以如果@ConditionalOnBean配置在@Configuration下的某一个方法,会有可能加载不到配置的bean

    @Bean
    @ConditionalOnBean(name = {"threeBoy"})
    public Poet poet() {
        return new Poet();
    }
    
    • @ConditionalOnMissingBean

    当上下文中不存在配置的“threeBoy”bean的时候,才会触发

    注意: 因为Spring加载bean的顺序是最后才加载@Configuration下的bean,所以如果@ConditionalOnBean配置在@Configuration下的某一个方法,会有可能加载不到配置的bean

    @Bean
    @ConditionalOnMissingBean(name = {"threeBoy"})
    public Program program() {
        return new Program();
    }
    
    • @ConditionalOnClass

    当上下文中存在配置的class的时候才会触发

     @Bean
     @ConditionalOnClass({Poet.class})
     public Poet poet() {
        return new Poet();
     }
    
    • @ConditionalOnMissingClass

      当上下文中不存在配置的class的时候才会触发,这里不多做解释了

    • @ConfigurationProperties

      将上下文配置文件中的属性封装到一个实体类中

    @ConfigurationProperties(prefix = "girl.info")
    @Data
    public class GirlProperties {
        /**
         * 男孩名称
         */
        private String boyName;
        /**
         * 第三者
         */
        private String threeBoy;
    
    }
    
    • @EnableConfigurationProperties

      此注解的作用是使 @ConfigurationProperties 注解注释的类生效

    官方命名规范

    • 前缀:spring-boot-starter-
    • 模式:spring-boot-starter-模块名
    • 举例:spring-boot-starter-web、spring-boot-starter-testaaa

    自定义starter命名规范

    • 前缀:-spring-boot-starter
    • 模式:模块名-spring-boot-starter
    • 举例:girl-spring-boot-starter

    自定义starter具体实现

    项目结构

    image

    推荐是用上述结构,girl-spring-boot-starter 是一个空项目,pom.xml中仅仅是引用了girl-spring-boot-starter-autoconfigurer

    girl-spring-boot-starter

    此模块中只修改了pom.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.park</groupId>
        <artifactId>girl-spring-boot-starter</artifactId>
        <version>1.0.0</version>
    
        <name>girl-spring-boot-starter</name>
        <url>http://www.example.com</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <!--引入自动装配模块-->
            <dependency>
                <groupId>com.park</groupId>
                <artifactId>girl-spring-boot-starter-autoconfigurer</artifactId>
                <version>1.0.0</version>
            </dependency>
        </dependencies>
    
    </project>
    

    girl-spring-boot-starter-autoconfigurer

    image

    如上图所示:我们将分析这几个目录的具体作用

    GirAutoConfiguration

    @Configuration
    @EnableConfigurationProperties(GirlProperties.class)
    public class GirlAutoConfiguration {
    
            @Bean
        public BeforeGirlFriend beforeGirlFriend() {
            return new BeforeGirlFriend();
        }
    
        @Bean
        public GirlFriend girlFriend() {
            return new GirlFriend();
        }
    }
    
    // -----------------------------------------//
    
    @Slf4j
    public class BeforeGirlFriend implements Girl {
        @Resource
        private GirlProperties girlProperties;
    
        @Override
        public void expression() {
            log.info("{},我已经喜欢上了{},我们分手吧!", girlProperties.getBoyName(), girlProperties.getThreeBoy());
        }
    }
    
    
    // -----------------------------------------//
    @Slf4j
    public class GirlFriend implements Girl {
        @Resource
        private GirlProperties girlProperties;
    
        @Override
        public void expression() {
            log.info("{},你为什么对我这么好,我做你的女朋友吧!", girlProperties.getBoyName());
        }
    }
    

    看这个类的结构我们应该不会陌生,它是Spring中定义的配置类;在这个类中我们初始化两个bean,一个是beforeGirlFriend,一个是girlFriend。

    GirlProperties

    @ConfigurationProperties(prefix = "girl.info")
    @Data
    public class GirlProperties {
        /**
         * 男孩名称
         */
        private String boyName;
        /**
         * 第三者
         */
        private String threeBoy;
    
    }
    

    这个类是将上下文中的配置文件映射到实体类中

    spring.factories

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.park.config.GirlAutoConfiguration
    

    将我们写好的配置类添加到这个配置文件中即可,key值不能写错!!!

    至此,我们自定义的starter就可以让别的项目引用了。

    Condition

    这个是条件判断机制,也就是说,我们可以按照我们想要的规则去初始化starter,具体的操作就不在这里详细说了。

    相关文章

      网友评论

          本文标题:自定义starter

          本文链接:https://www.haomeiwen.com/subject/ggeigctx.html