共计 5494 个字符,预计需要花费 14 分钟才能阅读完成。
上期讲到,对于 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…