一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情
每天一题,一起进大厂,欢迎大家点击阅读。《一起进大厂系列》是我一直持续更新的,主要是针对大厂面试题进入针对性深入学习。欢迎大家关注该专栏,会进行不间断更新。一起加油,一起进大厂。话不多说,进入今天的正题。
写在前面
前情回顾,我们上一篇讲到Boot的自动装配原理,发现利用spi机制实现,不清楚的可以去看看。今天我们拿出一篇针对性的文章再细深入实践下。
SpringBoot 最强大的功能就是把我们常用的场景抽取成了一个个starter(场景启动器)
,我们通过引入springboot 为 我提供的这些场景启动器,我们再进行少量的配置就能使用相应的功能。即使是这样,springboot也不能囊括我们所有 的使用场景,往往我们需要自定义starter
,来简化
我们对springboot的使用。
什么是starter
我们照顾下基础比较弱的伙伴,简单聊下starter
,starter是一组方便的依赖描述符,当我们使用它时,可以获得所有需要的Spring和相关技术的一站式服务。典型的如spring-boot-starter-web
,引入之后,自动引入所有有关spring web项目相关的依赖。
还有各种的starter,比如上节讲到的redis starter。
说实话,用久了SpringBoot,都已经忘记被每个项目都需要引入spring-core,spring-context,spring-web等等所支配的恐惧了哈哈。
我们先提前总结下,一会儿根据这个规则实践下
-
启动器(starter)是一个空的jar文件,仅仅提供辅助性依赖管理,这些依赖可能用于自动装配或其他类库。
-
需要专门写一个类似spring-boot-autoconfigure的配置模块
-
用的时候只需要引入启动器starter,就可以使用自动配置了
官方命名空间
- 前缀:spring-boot-starter-
- 模式:spring-boot-starter-模块名
- 举例:spring-boot-starter-web、spring-boot-starter-jdbc
自定义命名空间
- 后缀:-spring-boot-starter
- 模式:模块-spring-boot-starter
- 举例:mybatis-spring-boot-starter
如何自定义starter
如何编写自动配置
我们参照@WebMvcAutoConfiguration
为例,我们看看们需要准备哪些东西,下面是WebMvcAutoConfiguration的 部分代码:
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
public static final String DEFAULT_PREFIX = "";
public static final String DEFAULT_SUFFIX = "";
private static final String[] SERVLET_LOCATIONS = { "/" };
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
@Bean
@ConditionalOnMissingBean(HttpPutFormContentFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.formcontent.putfilter", name = "enabled", matchIfMissing = true)
public OrderedHttpPutFormContentFilter httpPutFormContentFilter() {
return new OrderedHttpPutFormContentFilter();
}
//省略
我们可以抽取到我们自定义starter时同样需要的一些配置。
@Configuration
: 指定这个类是一个配置类
@ConditionalOnXXX
: 指定条件成立的情况下自动配置类生效
@AutoConfigureOrder
: 指定自动配置类的顺序
@Bean
: 向容器中添加组件
@ConfigurationProperties
: 结合相关xxxProperties来绑定相关的配置
@EnableConfigurationProperties
: 让xxxProperties生效加入到容器中
自动配置类要能加载需要将自动配置类,配置在META‐INF/spring.factories中
org.springframework.boot.autoconfigure.EnableAutoConfiguration org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
自定义starter 实例
我们需要先创建一个父maven项目:springboot_custome_starter
两个子Module:
1、shushi-spring-boot-starter
2、shushi-spring-boot-starter-sample
springboot_custome_starter
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.shushi</groupId>
<artifactId>springboot_custome_starter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<modules>
<!-- 自定义starter -->
<module>shushi-spring-boot-starter</module>
<!-- 用于测试自定义starter-->
<module>shushi-spring-boot-starter-sample</module>
</modules>
</project>
创建子模块shushi-spring-boot-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">
<parent>
<artifactId>springboot_custome_starter</artifactId>
<groupId>cn.shushi</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shushi-spring-boot-starter</artifactId>
<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</artifactId>
</dependency>
</dependencies>
</project>
创建测试用模块shushi-spring-boot-starter-sample
<?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">
<parent>
<artifactId>springboot_custome_starter</artifactId>
<groupId>cn.shushi</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shushi-spring-boot-starter-sample</artifactId>
<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</artifactId>
</dependency>
<!-- 自定义starter-->
<dependency>
<groupId>cn.shushi</groupId>
<artifactId>shushi-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
项目结构如下:
shushi-spring-boot-starter: 我们本次的主角,自定义starter
shushi-spring-boot-starter-sample: 测试模块,用于测试starter是否生效
编写starter代码
public class DemoHandler {
public DemoHandler(){
System.out.println("demo handler init!!");
}
}
编写自动配置类
public class DemoAutoConfiguration {
@Bean
public DemoHandler demoHandler(){
return new DemoHandler();
}
}
在resources
目录下新建META-INF/spring.factories
文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.shushi.starter.config.DemoAutoConfiguration
在测试模块中编写测试类
@SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args).close();
}
}
启动项目看控制台打印
demo handler成功的被自动配置类注入了,也就是说,我们的starter生效啦~
OK 我们的starter 今天就讲到这里,下面进行下总结
总结
本文基于上一期的SpringBoot自动装配原理介绍了如何自定义starter,不管是面试还是实战都是需要的,希望可以好好回顾下。
这一章的内容还是比较简单的,希望大家有所收获。
我们下期继续学习 加油
弦外之音
啰嗦一句,欢迎大家关注学习《一起进大厂系列》