pom.xml
文件如下:
<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”>
4.0.0
com.heiz123
spring-boot-starter-eventmessage
1.0.0
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
org.springframework.boot
spring-boot-starter
2.4.2
复制代码
让starter自动装配
接下来我们需要对我们的Starter功能提供一个入口,我们需要提供一个@Configuration
类:
@Configuration
public class EventAutoConfiguration {
@Bean
public EventPublisher eventPublisher(List listeners) {
return new EventPublisher(listeners);
}
复制代码
EventAutoConfiguration
包括我们提供Starter功能所需的所有@Bean定义。因为我们的Starter只需要提供一个事件发布的功能,所以这里主需要往ApplicationContext
中添加一个EventPublisher
对象。
我们的EventPublisher
需要知道所有的EventListener
,这样它才能将事件传递给它们,所以我们让Spring注入ApplicationContext
中所有可用的EventListener
的列表。
接下来到了重要环节,如何让我们的Starter能够自动配置呢,需要在META-INF/
目录中创建一个spring.factories
文件。
在该文件中配置我们的Configuration
类:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.heiz123.event.EventAutoConfiguration
复制代码
Spring Boot会搜索classpath下的所有spring.Factories
文件,并加载其中声明的配置。
有了EventAutoConfiguration
类之后,我们现在就有了一个可以自动装配spring-boot-starter的入口点。
让Starter支持可选
在实际开发场景中,可能我们对某一功能需要关闭,等到测试环境和线上环境时才会打开,那么我们的starter应该支持功能的关闭或者禁用。
我们可以使用Spring Boot的Conditional
注解使我们的Configuration
成为可选的:
@Configuration
@ConditionalOnProperty(value = “eventstarter.enabled”, havingValue = “true”)
@ConditionalOnClass(name = “com.heiz123.RabbitConnector”)
@Slf4j
public class EventAutoConfiguration {
@Bean
public EventPublisher eventPublisher(List listeners) {
log.info(“event-message 自动装配中…”);
return new EventPublisher(listeners);
}
}
复制代码
@ConditionalOnProperty
注解的作用是只有eventstarter.enabled
属性设置为true
,才会将EventAutoConfiguration
添加到ApplicationContext
中。这样在使用了我们starter的应用中就可以通过eventstarter.enabled
属性来动态控制我们的starter是否启用。
@ConditionalOnClass
注解的作用是仅在classpath
上有com.heiz123.RabbitConnector
类时才激活自动配置。
让Starter可配置
在我们的EventAutoConfiguration
中,需要注入应用中所有的EventListener
到我们的EventPublisher
中,但是有可能使用我们Starter的应用并不想让所有的EventListener
都处理,可能只对一部分Event关注,那么我们就应该支持使用方能够便捷地进行配置。
比如在application.properties文件或者application.yml文件中可以进行如下配置:
eventstarter.listener.enabled-events:foo,bar
复制代码
yml文件:
eventstarter:
listener:
enabled-events:
-
foo
-
bar
复制代码
为了在我们的Starter的代码中能轻松访问这些属性,我们可以提供一个@ConfigurationProperties
类:
@ConfigurationProperties(prefix = “eventstarter.listener”)
class EventListenerProperties {
/**
-
会被传递给EventListener中的所有Event的类型。
-
其他Event将会被忽略
*/
private List enabledEvents = Collections.emptyList();
public List getEnabledEvents() {
return enabledEvents;
}
public void setEnabledEvents(List enabledEvents) {
this.enabledEvents = enabledEvents;
}
}
复制代码
然后我们通过使用@EnableConfigurationProperties
注解我们的入口点配置来启用EventListenerProperties
类:
@Configuration
@EnableConfigurationProperties(EventListenerProperties.class)
@Slf4j
public class EventAutoConfiguration {
@Bean
public EventPublisher eventPublisher(List listeners) {
log.info(“event-message 自动装配中…”);
return new EventPublisher(listeners);
}
}
复制代码
最后,我们可以在需要的地方注入EventListenerProperties
对象,例如在抽象的EventListener
类中过滤掉不关注的事件:
public abstract class EventListener {
private final EventListenerProperties properties;
public EventListener(EventListenerProperties properties) {
this.properties = properties;
}
public void receive(Event event) {
// 如果事件是Eanbled并且订阅了。
if (isEnabled(event) && isSubscribed(event)) {
onEvent(event);
}
}
private boolean isSubscribed(Event event) {
return event.getType().equals(getSubscribedEventType());
}
private boolean isEnabled(Event event) {
return properties.getEnabledEvents().contains(event.getType());
}
protected abstract String getSubscribedEventType();
protected abstract void onEvent(Event event);
}
复制代码
到这里我们的Starter基本就可以提供给别人使用了。
开始使用
实践是检验真理的唯一标准。我们来在一个新项目中引入一下我们的spring-boot-starter-eventmessage
。
首先创建一个spring-boot项目,我们就叫test-starter
。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

Java高频面试专题合集解析:
当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!
更多Java架构进阶资料展示
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!
[外链图片转存中…(img-w1l7aALV-1713735396045)]
更多Java架构进阶资料展示
[外链图片转存中…(img-UAhX407a-1713735396045)]
[外链图片转存中…(img-LUc6BOdk-1713735396045)]
[外链图片转存中…(img-iHL3G4y5-1713735396046)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!