der*_*erM 4 java spring spring-boot
我们打算开发一个带有 Spring 组件的库,我们所有的 Spring 应用程序都应该具有这些组件,例如连接到我们的监控、管理和管理服务的 Bean。
这个想法是利用 Springs 的“自动配置”机制。
对于初学者,我编写了一个类com.mycorp.project.basic.startup-notification.StartupNotificationPublisher.class,当“ApplicationStartedEvent”发生时,它通过我们最喜欢的消息代理(例如,它是一个日志文件)发送一条消息,向世界问好。
应通过配置类创建此类的实例com.mycorp.project.basic.startup-notification.autoconfiguration.StartupNotificationAutoConfiguration.class
package com.mycorp.project.basic.startup-notification
// ... Imports
@RequiredArgsConstructor
public class StartupNotificationPublisher {
private final String topic;
private final Logger messagePublisher = LoggerFactory.getLogger(StartupNotificationPublisher.class);
@EventListener
public void onApplicationStartedEvent(ApplicationStartedEvent event) {
messagePublisher.info("{}: Hello, Attention, I am here!", topic);
}
}
package com.mycorp.project.basic.startup-notification.autoconfiguration
// ... Imports
@Configuration
public class StartupNotificationAutoConfiguration {
@ConditionalOnMissingBean
@Bean
StartupNotificationPublisher startupNotificationPublisher()
{
return new StartupNotificationPublisher("helloTopic");
}
}
Run Code Online (Sandbox Code Playgroud)
最后,为了使自动配置工作,我spring.factories在META-INFjar 的 -Folder 中放置了一个文件(是的,它就在那里!),其中包含:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.project.basic.startup-notification.autoconfiguration.StartupNotificationAutoConfiguration
Run Code Online (Sandbox Code Playgroud)
我想,这将使 spring 发挥其魔力,在添加依赖项时找到该文件,运行配置并创建该 bean 来发布消息。
然而,事实并非如此。只有当我将包添加到我的扫描路径时@SpringBootApplication,我才会收到消息。
我错过了什么?是否有更具体的要求,例如特殊的项目结构?我需要有一个名为 spring-boot-starter 的库或类似的库吗?
项目结构:
rootDirectory
|-src
| |-main
| |-java
| | |-com/mycorp/project/basic/startup-notification
| | |-autoconfiguration
| | | |-StartupNotificationAutoConfiguration.java
| | |-StartupNotificationPublisher.java
| |-resources
| |-META-INF
| |-spring.factories
|-build.gradle
|-...etc...
Run Code Online (Sandbox Code Playgroud)
生成的罐子结构:
.jar
|-META-INF
| |-spring.factories
|-com
|-mycorp
|-project
|-basic
|-startup-notification
|-autoconfiguration
| |-StartupNotificationAutoConfiguration.class
|-StartupNotificationPublisher.class
Run Code Online (Sandbox Code Playgroud)
Dav*_*vid 17
我在类似的问题上花了几天时间,这对我有用。如果你使用 Spring boot 3+,他们改变了这一切!您可以在此处找到 2.7 发行说明中记录的更改:2.7 发行说明#auto-configuration。在 2.7 版本中,他们支持新旧方式向后兼容,并将 spring.factories 标记为已弃用(弃用通知)。他们在 3.0 中完全取消了支持!您可以在此处的 2.7 -> 3.0 迁移指南中找到删除信息:spring boot 2.7 -> 3.0 迁移指南#自动配置文件。本质上,您现在需要使用注释您的顶级自动配置类,并将@AutoConfiguration完全限定名称添加到此位置的文件中;META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports; 是的,这是文件的名称。不同的自动配置类将用换行符分隔,而不是像 中那样用逗号分隔的字符串spring.factories。
我希望这有帮助。
Spring Factory 如果配置正确,则与组件扫描无关。
我可以确认您所做的一切都是正确的,相同的配置多次适用于我的项目。因此要跟踪发生的情况:
spring.factories在:abc/src/main/resources/META-INF/spring.factories
确保库 jar 确实包含此文件并且它确实驻留在工件(您的 Spring Boot 应用程序)中。为此,使用 WinRar(或类似工具)打开应用程序并导航BOOT-INF/lib- jar 应该在那里 - 打开 jar 并检查该META-INF/spring.factories文件夹是否在那里。如果这里有问题,请检查pom.xml自动配置模块中的依赖项是否应定义为 Spring Boot 应用程序的依赖项。
确保配置确实加载(这意味着自动配置模块被识别):
按以下方式重写配置:
@Configuration
public class StartupNotificationAutoConfiguration {
public StartupNotificationAutoConfiguration() {
System.out.println("Loading the configuration StartupNotificationAutoConfiguration"); // or use logging framework
}
@ConditionalOnMissingBean
@Bean
StartupNotificationPublisher startupNotificationPublisher()
{
return new StartupNotificationPublisher("helloTopic");
}
}
Run Code Online (Sandbox Code Playgroud)
如果您看到此消息,则说明自动配置模块已存在并由 spring 加载。
@ConditionalOnMissingBean注释。如果该 bean 是在您的应用程序中定义的,那么它将优先于自动配置模块中定义的 bean。它也可能是您问题的根源。| 归档时间: |
|
| 查看次数: |
7422 次 |
| 最近记录: |