SpringBoot源码解析-自定义Starter

在SpringBoot学习的过程中,每当我们需要某个现有框架的功能时,都是通过引入对应的Starter,然后由SpringBoot帮我们完成自动装配。说白了,Starter就是个外部项目,就像项目A需要调用项目B,除了通过外部调用方式(比如远程调用),还可以直接内部集成B,直接本地调用。只是在SpringBoot项目中,需要遵循SpringBoot的规范而已。

Starter命名规范

Spring官方定义的Starter格式:

spring-boot-starter-{name}

非官方(自定义)定义的Starter格式:

{name}-spring-boot-starter

实现自定义Starter

需求

创建一个Starter,根据配置文件配置的name值,返回"Hello"+name。

创建Starter项目

创建一个名为javafamily-spring-boot-starter的SpringBoot项目

1.引入依赖

注意:spring-boot-configuration-processor并非加载xml或者properties配置啥的,该依赖是为了给自定义的配置类生成元数据信息的,在yml等配置文件中,比如server.port是可以直接点进去到配置类中的,如果没有该依赖,在配置文件直接书写是没有提示的,但是不影响项目运行。

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-configuration-processor</artifactId>
 <optional>true</optional>
</dependency>// 为简化开发引入 非必须<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <optional>true</optional>
</dependency>123456789101112复制代码类型:[java]

2.编写一个JavaFamilyService类

import lombok.AllArgsConstructor;@AllArgsConstructorpublic class JavaFamilyService { private String name; public String family() {  return "Hello " + name;
 }

}123456789101112复制代码类型:[java]

该类用于处理核心业务,这里的name由外部传入,family方法返回拼接后的字符串。

3.定义配置属性封装类

import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;@Data// 读取配置文件中以java.family为前缀的配置@ConfigurationProperties(prefix = "java.family")public class JavaFamilyServiceProperties { private String name;
}12345678910复制代码类型:[java]

4.定义自动配置类

import com.javafamily.service.JavaFamilyService;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;@Configuration// 当给定的类名在类路径上存在,则实例化当前Bean@ConditionalOnClass(JavaFamilyService.class)// 让使用@ConfigurationProperties注解的类生效,并且将该类注入到 IOC 容器中@EnableConfigurationProperties(JavaFamilyServiceProperties.class)public class JavaFamilyServiceAutoConfiguration { @Resource
 private JavaFamilyServiceProperties javaFamilyServiceProperties; @Bean
 // 被@ConditionalOnMissingBean注解修饰的同类型的Bean只能注册一个 注册多个时会报错
 @ConditionalOnMissingBean
 public JavaFamilyService javaFamilyService() {  // 传入从配置文件加载到的name属性
  return new JavaFamilyService(javaFamilyServiceProperties.getName());
 }
}123456789101112131415161718192021222324252627复制代码类型:[java]

5.创建spring.factories文件

在resources文件夹下创建META-INF文件夹,在META-INF文件夹下创建spring.factories文件。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=  com.javafamily.config.JavaFamilyServiceAutoConfiguration12复制代码类型:[java]

这块内容在前面的源码中讲过,就是通过SPI技术实现我们的自动装配。

整体效果图如下:

6.引入自定义Starter

创建一个任意的SpringBoot工程,引入javafamily-spring-boot-starter依赖。

<dependency>
 <groupId>com.javafamily</groupId>
 <artifactId>javafamily-spring-boot-starter</artifactId>
 <version>0.0.1-SNAPSHOT</version>
</dependency>12345复制代码类型:[java]

在application.yml添加java.family.name配置,将值设置为JavaFamily。

创建HelloController,注入JavaFamilyService测试效果。

import com.javafamily.service.JavaFamilyService;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestControllerpublic class HelloController { @Resource
 private JavaFamilyService javaFamilyService; @GetMapping("/test")
 public String test() {  return javaFamilyService.family();
 }
}12345678910111213141516复制代码类型:[java]

访问localhost:8080/test查看效果。

至此,自定义Starter入门就完成了,相信大家看完本篇文章,对Starter会有更深入的理解,我们下期再见。

(0)

相关推荐