上期讲到,对于SpringBoot主动拆卸原理,置信小伙伴们曾经看明确啦,明天,咱们就来聊一聊如何依据主动拆卸原理,自定义一个starter吧
什么是starter
咱们玩了那么久的SpringBoot, 简直我的项目依赖中基本上全是各种各样的starter, 那么到底什么是starter?
starter是一组不便的依赖描述符,当咱们应用它时,能够取得所有须要的Spring和相干技术的一站式服务,典型的如spring-boot-starter-web
,引入之后,主动引入所有无关spring web我的项目相干的依赖。
说实话,用久了SpringBoot,阿鉴都曾经遗记被每个我的项目都须要引入spring-core
,spring-context
,spring-web
等等所摆布的恐怖了哈哈。
回顾SpringBoot主动拆卸的内容
在上一节,咱们是从探索redis的主动拆卸过程开始的,那么小伙伴们还记得它的过程吗?
阿鉴带大家回顾一下:
我的项目启动时,Spring通过@Import注解导入了AutoConfigurationImportSelector
, 而后调用该类selectImports
时,从classpath下的META-INF/spring.factories
文件中读取key为EnableAutoConfiguration
的配置类,而后Spring便会将这些类加载到Spring的容器中,变成一个个的Bean。
入手实际
流程曾经梳理完了,当初就开始实际吧,思路其实非常简单
- 写一个配置类
- 将该配置类放到资源文件夹中的
META-INF/spring.factories
中
先来创立一个我的项目
1. 创立spring-boot-starter-demo我的项目并编写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.3.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>cn.zijiancode</groupId> <artifactId>spring-boot-starter-demo</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <modules> <!-- 自定义starter --> <module>spring-boot-starter-demo-starter</module> <!-- 用于测试自定义starter--> <module>spring-boot-starter-demo-sample</module> </modules></project>
2. 创立子模块spring-boot-starter-demo-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> <parent> <groupId>cn.zijiancode</groupId> <artifactId>spring-boot-starter-demo</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>spring-boot-starter-demo-starter</artifactId> <version>1.0.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies></project>
3. 创立测试用模块spring-boot-starter-demo-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"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>cn.zijiancode</groupId> <artifactId>spring-boot-starter-demo</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>spring-boot-starter-demo-sample</artifactId> <version>1.0.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 自定义starter--> <dependency> <groupId>cn.zijiancode</groupId> <artifactId>spring-boot-starter-demo-starter</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> </dependencies></project>
我的项目构造如下:
spring-boot-starter-demo-starter: 咱们本次的配角,自定义starter
spring-boot-starter-demo-sample: 测试模块,用于测试starter是否失效
4. 编写starter中的代码
编写一个handler,用于做注入测试
public class DemoHandler { public DemoHandler(){ System.out.println("demo handler init!!"); }}
不须要加任何注解,因为等下应用@Bean的形式注入
编写主动配置类
public class DemoAutoConfiguration { @Bean public DemoHandler demoHandler(){ return new DemoHandler(); }}
主动配置类同样也能够不须要加任何注解,因为它实质上是应用@Import导入的
当然,如果不加@Configuration注解的话在特定的场景其实会引发一个小小的问题
这个小问题阿鉴决定卖个关子,放到下期和大家聊一聊,很快的,就这两天(其实是因为说起来还是有些内容的)
在resources
目录下新建META-INF/spring.factories
文件
编写配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\cn.zijiancode.starter.config.DemoAutoConfiguration
5. 在测试模块中编写测试类
@SpringBootApplicationpublic class SampleApplication { public static void main(String[] args) { SpringApplication.run(SampleApplication.class, args).close(); }}
6. 启动我的项目查看后果
demo handler胜利的被主动配置类注入了
也就是说,咱们的starter失效啦~
我晓得,到这个时候,必定有小伙伴说:就这?
阿鉴:的确,就这,哈哈,一个广泛的应用形式到这就完结了~
利用starter做一些额定的操作
在下面的例子中,咱们只是通过starter注入了bean,然而其实咱们能够利用这样的机制做更多的事件,比方spring-boot-starter-data-redis
就在我的项目启动时与redis建设了连贯,并初始化连接池。还有咱们之前学的nacos,在我的项目启动时,将服务注册到nacos等等。
那么,这样的操作应该怎么实现呢?
其实在例子中,咱们的DemoHandler
在构造方法里打印了一句demo hanlder init
,这就是个小小的思路,咱们齐全能够在初始化bean时做些别的事件,当然,这样的做法并不太好,因为spring中的bean是一个接一个初始化的,如果咱们在UserService的构造方法里写调用RoleService的逻辑,很可能会因为RoleService还没初始化而报错。
在Spring中,还有一个货色叫做监听器,咱们能够利用它在做一些事件,这也是阿鉴最喜爱的一种形式。
监听器必定是对应着一系列的事件的,有个事件叫做ContextRefreshedEvent
, 示意Spring的上下文刷新结束,所有的Bean都曾经初始化实现,Spring的启动流程行将完结。
试试
1. 在DemoHandler加个办法
public class DemoHandler { public DemoHandler(){ System.out.println("demo handler init!!"); } public void hello(){ System.out.println("hello world for demo starter!"); }}
2. 编辑监听器
public class DemoListener implements ApplicationListener<ContextRefreshedEvent> { @Resource private DemoHandler demoHandler; @Override public void onApplicationEvent(ContextRefreshedEvent event) { demoHandler.hello(); }}
3. 将监听器注入到容器中
public class DemoAutoConfiguration { @Bean public DemoHandler demoHandler(){ return new DemoHandler(); } @Bean public DemoListener demoListener(){ return new DemoListener(); }}
4. 应用测试模块测试
测试胜利,listern已失效
小结
本文基于上一期的SpringBoot主动拆卸原理介绍了如何自定义starter,并和小伙伴们聊了下怎么利用这个机制做一些额定的事件。
这一期的内容还是比较简单的,心愿大家有所播种。
咱们下期...完了,上一期还说了要和大家聊一聊如何查看组件的源码并进行扩大,我有罪,请容许我放到下一期吧「磕头.png」,咱们下期再见~
gitee: https://gitee.com/lzj960515/s...
想要理解更多精彩内容,欢送关注公众号:程序员阿鉴,阿鉴在公众号欢送你的到来~
集体博客空间:https://zijiancode.cn/archive...