🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
案例代码:https://gitee.com/flymini/codes01/tree/master/springboot_/starter_ **** **1. 为什么要自定义场景启动器** * 可能官方提供的场景启动器不满足你的要求。 * 可能是你想开发一个被 SpringBoot 兼容的框架。比如 Mybatis 想要被 SpringBoot 兼容,则 Mybatis 团队自己开发了一个 mybatis 的场景启动器。 ```xml <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> ``` * 可能你想要在项目启动时自动加载一下依赖组件。 **2. 自定义场景启动器需考虑如下因素** * 场景启动器需要引入哪些依赖。 * 自动配置类需要用到哪些注解。 [TOC] # 1. WebMvcAutoConfiguration源码 1. 通过看 WebMvcAutoConfiguration 来了解一下编写一个场景启动器可能需要用到哪些注解。 ```java package org.springframework.boot.autoconfigure.web.servlet; // 指定类为配置类 @Configuration( proxyBeanMethods = false ) // 当应用是Web应用时让该配置类生效 @ConditionalOnWebApplication( type = Type.SERVLET ) // 当存在Servlet、DispatcherServlet,WebMvcConfigurer时才让配置类生效 @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) // 当不存在WebMvcConfigurationSupport才让这个配置类生效 @ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) // 指定该配置类生效的顺序,当大于0时,数字越小越先被执行 @AutoConfigureOrder(-2147483638) // 指定在这三个类被执行后才能执行该配置类 @AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}) public class WebMvcAutoConfiguration { @Bean // 将方法的返回值注入到IoC容器中,<bean class="方法返回值"/>,方法名作为<bean id="方法名"/> @ConditionalOnMissingBean({HiddenHttpMethodFilter.class}) @ConditionalOnProperty( prefix = "spring.mvc.hiddenmethod.filter", name = {"enabled"}, matchIfMissing = false ) public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() { return new OrderedHiddenHttpMethodFilter(); } @Configuration( proxyBeanMethods = false ) @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) // 结合对应的XXXProperties来绑定相关的配置,这些配置就是在application.properties中可以配置的属性 // EnableConfigurationProperties让XXXProperties这些配置生效 @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class}) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer { ... } ``` 2. 需要将该类配置在 META-INF/spring.factories 文件中才能使它生效。 ![](https://img.kancloud.cn/87/75/8775fdd46a422f4f7c65fa332d3622d1_1305x298.jpg) ```xml # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ ``` <br/> # 2. 自定义场景启动器 ## 2.1 创建自动配置类模块 **1. 创建模块:learn-custom-autoconfig** ```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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.learn.example</groupId> <artifactId>learn-custom-autoconfig</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> </dependencies> </project> ``` **2. 当前模块的properties类** ```java @Data @ConfigurationProperties(prefix = "custom.config.account") public class AccountProperties { private String username; private String password; } ``` **3. 在当前模块提供一个获取properties类的API** ```java @Data public class AccountService { private AccountProperties properties; } ``` **4. 将AccountService注册到IoC容器中** ```java @Configuration //标注该类为配置类 @ConditionalOnWebApplication //当前项目是Web应用时这个配置类生效 @EnableConfigurationProperties(AccountProperties.class) //将属性类加载到当前配置类中 public class CustomAutoConfiguration { @Autowired private AccountProperties properties; @Bean public AccountService getAccountService() { AccountService impl = new AccountService(); impl.setProperties(properties); return impl; } } ``` **5. 将配置类CustomAutoConfiguration添加到`resources/META-INF/spring.factories`** ```factories org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ learn.custom.autoconfig.config.CustomAutoConfiguration ``` >[info]提醒:不要给当前模块添加启动类。 <br/> ## 2.2 创建场景启动器模块 **1. 创建启动器模块:custom-spring-boot-starter** ![](https://img.kancloud.cn/a7/4f/a74fe2a5102fd1cb5ffe0869749b0134_1522x924.jpg) ![](https://img.kancloud.cn/6d/cb/6dcb120d6529abef1e385249f6cd88f3_1521x919.jpg) ``` /*********************启动器命名规范***************************/ ------------ 官方命名空间 ------------ 前缀:spring-boot-starter 模式:spring-boot-starter-模块名 举例:spring-boot-starter-web、spring-boot-starter-jdbc ------------ 自定义命名空间 ------------ 后缀:spring-boot-starter 模式:模块名-spring-boot-starter 举例:mybatis-spring-boot-starter ``` **2. 在当前模块引入自动配置类模块** ```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>com.learn.example</groupId> <artifactId>custom-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.learn.example</groupId> <artifactId>learn-custom-autoconfig</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project> ``` <br/> ## 2.3 创建项目来做测试 **1. 创建一个SpringBoot项目来做测试:com-custom-test** ```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>com.learn.example</groupId> <artifactId>com-custom-test</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <!-- 当前模块引入自定义场景启动器 --> <dependency> <groupId>com.learn.example</groupId> <artifactId>custom-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project> ``` **2. 在当前模块的配置文件中给自动配置模块的properties赋值** *`application.yml`* ```yml custom: config: account: username: zhangsan password: 123456 ``` **3. controller层调用自动配置类中的API** ```java @RestController public class IndexController { @Autowired private AccountService accountService; @RequestMapping("/v1/auto/properties") public AccountProperties getProperties() { AccountProperties properties = accountService.getProperties(); System.out.println(properties); //AccountProperties(username=zhangsan, password=123456) return properties; } } ``` <br/> 通过上面的演示可以看出,com-custom-test 模块引入了场景启动模块,而场景启动器模块又引入了自动配置模块,所以可以在测试模块中可以调用到自动配置类的 API。