在学习Spring Boot的过程中,接触最多的就是starter。使用者可以把starter当成是一种服务——使得使用某个功能时不需要关注各种依赖库的处理,不需要具体的配置信息,由Spring Boot自动通过classpath路径下的类发现需要的Bean,并织入bean。而自动装配就是Springboot最大的特性。
举个例子,spring-boot-starter-jdbc这个starter的存在,使得我们只需要在Application下用@Autowired引入DataSource的bean就可以,Spring Boot会自动创建DataSource的实例。

下面我们用一个不是特别标准的方式定制一个我们自己的Starter。

首先先定义一下我们这个starter要干什么,我们的目的时演练构建Starter的过程,具体逻辑不重要,这里只是封装一个控制台打印类。

第一步:初始化项目

在一个spring-boot项目中新建一个子模块,这里使用的时maven,使用maven创建一个普通的Java项目即可。完成后在src/main/目录下面建立resource文件夹。
在pom.xml文件中引入依赖如下:

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

第二步:初始化项目结构

按下图结构创建完成包和类(熟悉后,不用按这里的步骤进行)。
定制自己的Springboot Starter

第三步:编码Starter的核心类

首先是执行类,其实就是一个普通的Java Bean

public class LogCollector {
    public void info(String info) {
        System.out.println("Info: " + info);
    }
    public void error(String errorInfo) {
        System.out.println("Error: " + errorInfo);
    }
}

下面就是springboot-starter的核心之一了,自动装配的配置类

import com.leon.collector.LogCollector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LogCollectorAutoConfig {

    @Bean(name = "logCollector")
    public LogCollector logCollector() {
        return new LogCollector();
    }
}

配置类的类注解@Configuration是为了让springboot扫描识别用的,@Bean是让spring扫描到后把bean的实例放到Spring容器中进行管理。

最重要的一步来了,编写spring.factories文件。
src/main/resources 目录下新建 META-INF 文件夹,然后新建 spring.factories 文件,这个文件用于告诉Spring Boot有那些自动配置类需要处理,因此它的内容是

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.biz.LogCollectorAutoConfig    -- 这个类就是上面????的配置类的全路径

第四步:使用

在某个模块的pom.xml引入上面的Starter

<dependency>
	<groupId>com.biz</groupId>
	<artifactId>log-collector-starter</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>

然后注入使用

	@Autowired
	private LogCollector logCollector;

	@Test
	public void testLogCollector() {
		logCollector.info("Running .......");
	}

运行这个测试类,就可以在控制台发现 Running … 的输出了。
有具体模块化过程后,就可以按以上过程实现具体有意义的Starter了。

第五步:分析

常见的starter会包括下面几个方面的内容:

自动配置文件,根据classpath是否存在指定的类来决定是否要执行该功能的自动配置。

  • spring.factories,非常重要,指引Spring Boot找到指定的自动配置文件。
  • endpoint:可以理解为一个admin,包含对服务的描述、界面、交互(业务信息的查询)
  • health indicator:该starter提供的服务的健康指标

在应用程序启动过程中,Spring Boot使用SpringFactoriesLoader类加载器查找org.springframework.boot.autoconfigure.EnableAutoConfiguration关键字对应的Java配置Bean(多个配置Bean用逗号分隔)。Spring Boot会遍历在各个jar包种META-INF目录下的spring.factories文件,构建成一个配置文件链表。除了EnableAutoConfiguration关键字对应的配置文件,还有其他类型的配置文件:

org.springframework.context.ApplicationContextInitializer
org.springframework.context.ApplicationListener
org.springframework.boot.SpringApplicationRunListener
org.springframework.boot.env.PropertySourceLoader
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider
org.springframework.test.contex.TestExecutionListener

PS:Spring Boot的starter在编译时不需要依赖Spring Boot的库。但需要依赖spring-context的库,因为要用spring的注解,不是Java自带的注解。本例子中用了spring-boot的库是因为顺手了。

另外一种方式让spring boot识别我们的自动配置Bean

从上面的结果,我们指定Spring Boot 是通过spring.factories找到自动配置文件(xxxxAutoConfiguration之类的文件),其实还有一种方式,不使用spring.factories,而使用注解的方式来实现。

接着上面的例子,首先将spring.factories中的内容注释掉。
创建元注解(meta-annotation),即在src/main/java/com/biz/目录下新建EnableLogCollector.java文件。

import org.springframework.context.annotation.Import;
import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(LogCollectorAutoConfig.class)
@Documented
public @interface EnableLogCollector {
}

在应用模块的用@EnableDbCounting注解修饰Application启动类。

@SpringBootApplication
@EnableLogCollector
public class XxxApplication {
    public static void main(String[] args) {
        SpringApplication.run(XxxApplication.class, args);
    }
}

启动应用程序,设置日志级别为DEBUG
由starter的用户手动触发配置,查看启动过程日志可以看出我们自己定义的注解起作用了。

如果没有spring.factories,那么在程序启动的时候Spring Boot的自动配置机制不会试图解析其他jar包下的XxxAutoConfiguration类。一般来说,@Component注解的作用范围就是在我们自己的业务模块下的Application启动类所在的目录以及各个子目录,我们自定义的Configuration类很可能不在这个包结构下,因此不会被扫描到。

@EnableLogCollector注解通过@Import(LogCollectorAutoConfig.class)找到对应的配置类,因此通过用@EnableLogCollector修饰XxxApplication,就是告诉Spring Boot在启动过程中要把LogCollectorAutoConfig加入到应用上下文中。

继续阅读之关联文章

创建带触发条件的Starter

相关文章:

  • 2020-01-02
  • 2018-11-23
  • 2020-10-15
  • 2021-08-20
  • 2019-09-04
  • 2019-03-18
  • 2021-12-29
  • 2017-12-17
猜你喜欢
  • 2020-01-01
  • 2019-05-27
  • 2019-11-01
  • 2019-11-07
  • 2019-05-15
  • 2019-06-20
  • 2021-10-30
  • 2021-09-18
相关资源
相似解决方案