在上一篇文章中, 我们已经了解了一个 starter 实现自动配置的基本流程, 在这一小结我们将复现上一过程, 实现一个自定义的 starter.
先来分析 starter 的需求:
在项目中添加自定义的 starter 依赖, 自动在 Spring 中加载 starter 中的 Bean;
从 application.properties 中加载指定配置
创建项目
先创建一个名为 starter 的项目.
- <?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>top.ninwoo</groupId>
- <artifactId>demo-starter</artifactId>
- <version>1.0.0</version>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot</artifactId>
- <version>2.1.6.RELEASE</version>
- </dependency>
- </dependencies>
- </project>
在 resources 中创建一个 META-INF 的目录, 并在目录中创建一个 spring.factories. 在这个配置中, 我们只设置一个 EnableAutoConfiguration 项, 并且对应只设置一个 DemoAutoConfig 配置类.
org.springframework.boot.autoconfigure.EnableAutoConfiguration=top.ninwoo.config.DemoAutoConfig
创建 DemoAutoConfig 配置类
- package top.ninwoo.config;
- import org.springframework.boot.context.properties.EnableConfigurationProperties;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- @Configuration
- @EnableConfigurationProperties(DemoStarterProperties.class)
- public class DemoAutoConfig {
- @Bean
- DemoBean demoBean() {
- return new DemoBean();
- }
- }
这个配置类, 我们主要使用了 @Configuration 和 @EnableConfigurationProperties 两个注解.@EnableConfigurationProperties 启用一个 ConfigurationProperties.
创建 ConfigurationProperties 对应的 DemoStarterProperties
- package top.ninwoo.config;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- @ConfigurationProperties(prefix = "top.ninwoo.demo")
- public class DemoStarterProperties {
- private String name = "default";
- private int age = 0;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
创建一个 ConfigurationProperties 类. 这个类主要用来从 application.properties 中读取配置项, 并自动设置到相对应的字段上.
创建一个测试用 Bean, 并使用 ConfigurationProperties 类中的信息.
起初这里有个疑惑, 不知道如何使用这个 ConfigurationProperties 类. 不过在 spring 中最常见的就是 Bean, 我们可以大胆的猜测通过 @ConfigurationProperties 注释的类, 将自动在 Spring 容器中自动创建一个 Bean. 而我们在使用的时候, 就通过普通的 bean 注入方式便可以使用 ConfigurationProperties 类中的信息. 所以, 我们这样创建一个测试 Bean
- package top.ninwoo;
- import javax.annotation.Resource;
- public class DemoBean {
- @Resource
- DemoStarterProperties properties;
- public String getName() {
- return properties.getName();
- }
- public String getAge() {
- return getAge();
- }
- }
同时在 DemoAutoConfig 中使用 @Bean 注解创建一个 Bean.
到这里, 我们的 starter 就创建完成了. 通过 mvn 打包, 或者创建同一个父项目的不同子 Module 的方式, 我们可以进行测试这个 starter 是否生效.
创建测试类
测试类使用一个 spring boot web 项目来完成, 主要创建了一个 RestController, 并通过 RestController 获取 Spring 上下文中注册的 bean names 和 starter 中的测试 Bean.
pom.xml
- <?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>top.ninwoo</groupId>
- <artifactId>springboot-demo</artifactId>
- <version>1.0.0</version>
- <parent>
- <artifactId>spring-boot-starter-parent</artifactId>
- <groupId>org.springframework.boot</groupId>
- <version>2.1.6.RELEASE</version>
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-Web</artifactId>
- </dependency>
- <dependency>
- <groupId>top.ninwoo</groupId>
- <artifactId>demo-starter</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
- </project>
在 pom 文件中, 我们添加了刚刚实现的 starter.
- RestController:
- @RestController
- public class IndexController implements ApplicationContextAware {
- ApplicationContext ctx = null;
- @Resource
- DemoBean demoBean;
- @RequestMapping("/getList")
- public String[] getBeanNames() {
- return ctx.getBeanDefinitionNames();
- }
- @RequestMapping("/getDemoBean")
- public String demoBean() {
- return demoBean.getName();
- }
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- ctx = applicationContext;
- }
- }
SpringBoot 启动类 MainApp:
- package top.ninwoo;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- @SpringBootApplication
- public class MainApp {
- public static void main(String[] args) {
- SpringApplication.run(MainApp.class, args);
- }
- }
我们可以看到, 与正常的一个 Web 项目相比, 我们只是添加了一个依赖, 而并没有修改启动类.
测试
访问 127.0.0.1:8080/getList 接口, 我们可以看到最后的几个 bean Names 是:
...,"top.ninwoo.config.DemoAutoConfig","demoBean","top.ninwoo.demo-top.ninwoo.config.DemoStarterProperties"]
这证明, 通过注入我们 starter 依赖, 已经在 Spring 的上下文创建了 starter 配置类中的 Bean.
在没有设置 application.properties 时, 直接访问 http://127.0.0.1:8080/getDemoBean, 可以获取到测试用的 Bean 实例中默认的参数配置 default.
添加 application.properties:
top.ninwoo.demo.name=joliu
重启项目, 再次访问该接口, 发现测试用的 Bean 实例对应的属性已经安装配置类中的参数进行设置, 返回了 joliu.
小结
到这里, 我们可以说已经了解了开发一个 SpringBoot Starter 最基本的流程, 我们可以尝试在我们日常的项目中开发这样的 starter.
来源: https://www.cnblogs.com/NinWoo/p/11305650.html