上期讲到,对于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. 在测试模块中编写测试类
@SpringBootApplication
public 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…
发表回复