在我的默认SpringBoot应用程序中,它具有spring-boot-starter-执行器
依赖项,调用/执行器/健康
(带有show-细节:true
)返回以下信息
{
"status": "UP",
"components": { ... },
"diskSpace": {
"status": "UP",
"details": {
"total": 2000396742656,
"free": 581706977280,
"threshold": 10485760,
"exists": true
}
},
"ping": { "status": "UP" }
}
}
但是,我的机器上有两个驱动器,所以我想查看它们的磁盘空间详细信息。所以我添加了一个配置文件:
@Configuration
public class DiskSpaceConfig {
@Bean
public AbstractHealthIndicator driveC() {
return new DiskSpaceHealthIndicator(new File("C:/"), DataSize.ofMegabytes(100));
}
@Bean
public AbstractHealthIndicator driveD() {
return new DiskSpaceHealthIndicator(new File("D:/"), DataSize.ofMegabytes(100));
}
}
现在,我的健康endpoint返回以下数据
{
"status": "UP",
"components": { ... },
"diskSpace": { "status": "UP", "details": { ... } },
"driveC": { "status": "UP", "details": { ... } },
"driveD": { "status": "UP", "details": { ... } },
"ping": { "status": "UP" }
}
}
(稍后我将考虑如何抑制默认的“diskSpace”条目)
然而,由于我可能想在不同的机器上运行我的应用程序,我想配置磁盘驱动器,以便在我的应用程序中进行动态检查。yml
文件。
media:
health:
drives:
- name: driveC
path: "C:/"
- name: driveD
path: "D:/"
还加上
@Slf4j
@Component
@ConfigurationProperties(prefix = "media.health")
@Data
public class MediaHealthConfigLoader {
private List<DriveConfig> drives;
@PostConstruct
public void postProcessBeanFactory() {
log.info("Found {} configured drives", drives.size());
}
}
@Data
public class DriveConfig {
private String name;
private String path;
}
@Configuration
@EnableConfigurationProperties
public class DiskSpaceConfig {
}
配置在启动期间加载并记录到控制台。
然而,我的问题是,如何动态创建这些bean并将它们添加到bean上下文中?我想我需要去豆工厂。我试过以下方法:
@Slf4j
@Configuration
@EnableConfigurationProperties
@RequiredArgsConstructor
public class DiskSpaceConfig {
private final MediaHealthConfigLoader mediaHealthConfigLoader;
private final BeanFactory beanFactory;
@PostConstruct
public void createDiskSpaceHealthIndicators() {
ArrayList<AbstractHealthIndicator> beans = new ArrayList<>();
if (mediaHealthConfigLoader.getDrives() != null) {
log.info("Creating {} dynamic DiskSpaceHealthIndicators", mediaHealthConfigLoader.getDrives().size());
mediaHealthConfigLoader.getDrives().forEach(drive -> {
DiskSpaceHealthIndicator indicator = new DiskSpaceHealthIndicator(new File(drive.getPath()), DataSize.ofMegabytes(100));
log.info("Created indicator with name={} for path={}: bean={}", drive.getName(), drive.getPath(), indicator);
// -> I would like to do something like: beanFactory.addBean(drive.getName(), indicator)
});
}
}
}
然而,我的beanFactory
只有getter,因此无法添加新创建的bean。
我还尝试使用BeanFactoryPostProcessor
连接到bean创建中,但是,在执行回调时,配置属性(或加载它们的类)似乎还没有准备好。
@Slf4j
@Component
@RequiredArgsConstructor
public class DynamicHealthIndicatorFactory implements BeanFactoryPostProcessor {
private final MediaHealthConfigLoader mediaHealthConfigLoader;
@Override
public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
// mediaHealthConfigLoader is null here :-(
mediaHealthConfigLoader.getDrives().forEach(drive -> {
DiskSpaceHealthIndicator newBean = new DiskSpaceHealthIndicator(new File(drive.getPath()), DataSize.ofMegabytes(100));
beanFactory.initializeBean(newBean, drive.getName());
beanFactory.registerSingleton(drive.getName(), newBean);
});
}
}
或者
@Slf4j
@Component
@ConfigurationProperties(prefix = "media.health") // commenting out the same annotation on MediaHealthConfigLoader
public class DynamicHealthIndicatorFactory implements BeanFactoryPostProcessor {
private List<DriveConfig> drives;
@Override
public void postProcessBeanFactory(final ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
// drives is null here :-(
drives.forEach(drive -> {
DiskSpaceHealthIndicator newBean = new DiskSpaceHealthIndicator(new File(drive.getPath()), DataSize.ofMegabytes(100));
beanFactory.initializeBean(newBean, drive.getName());
beanFactory.registerSingleton(drive.getName(), newBean);
});
}
}
但是,这两种方法都会导致NullPointerExceptions,因为在生命周期的这个点上,属性和自动构建的bean都准备好了。
我肯定我不是第一个尝试这样做的人,但我似乎没有找到正确的搜索词来找到解决方案。
这应该适用于ref:gist应用程序
@Configuration
@EnableConfigurationProperties
@AllArgsConstructor
class DiskSpaceConfig {
private final MediaHealthConfigLoader mediaHealthConfigLoader;
private final ConfigurableListableBeanFactory beanFactory;
@PostConstruct
public void registerBeans(){
mediaHealthConfigLoader.getDrives().forEach(drive -> {
DiskSpaceHealthIndicator newBean = new DiskSpaceHealthIndicator(new File(drive.getPath()), DataSize.ofMegabytes(100));
beanFactory.initializeBean(newBean, drive.getName());
beanFactory.registerSingleton(drive.getName(), newBean);
});
}
}
如果需要,可以禁用默认磁盘空间
management:
health:
diskspace:
enabled: false
我想覆盖应用程序中定义的属性。属性通过cmd与应用程序中现有的其他属性。属性,但仅允许提供预定义值。 我需要的是通过应用程序中已经存在的命令行传递调度的参数。属性,它将更改在调度中定义的默认值。 我的问题是,当我从cmd执行jar文件时,它正在获取构建时存在于中的值。它没有覆盖现有值值。我想根据用户需要覆盖值。 Spring代码 应用属性 在cmd中
我在src/main/resources下创建了2个文件: 应用程序。属性 第一个具有从env变量中获取值的属性,而后者具有固定值。 根据这里的具体情况,我以这样的方式推出了Spring靴: 然而,不会产生任何影响,并且应用程序是局部的。属性似乎被忽略。 有什么提示吗?
我正在使用springfox swagger 2.8.0。我想根据我的需求定制我的Swagger文档和API版本路径。能够使用应用程序修改版本路径。属性,并且它正在正常运行: 斯普林福克斯。文档大摇大摆路径=/v2/可用性服务 http://localhost:8080/context-path/v2/availability-service 但是想要我的留档URL如下,如何使用applicati
Ember CLI,Ember的命令行界面提供了一个标准的项目结构,一组开发工具和一个插件系统。这允许Ember开发人员专注于构建应用程序,而不是构建使它们运行的支持结构。可通过ember --help显示Ember CLI提供的命令,或通过ember help <command-name>查看特定命令的信息。 创建应用程序 $ ember new super-rentals 上述ember
我有一个移动的ios应用程序,它可以动态生成元素,我很难点击一些复选框,因为它们没有像web应用程序中常见的复选框那样有id或值,请看下面的图片。(很抱歉我不能展示所有图像,但app正在开发中) Appium inspector给了我xpath,但我不喜欢它,因为它会根据屏幕上看到的元素而改变,因为我必须向下滚动页面,这取决于设备,有时显示一些复选框有时不显示,因此例如[4]元素会改变。 我想知道
我将使用ADFS作为身份提供者(IDP)实现对java应用程序的单点登录。通过OneLogin找到了此解决方案SSO,并使用了其示例应用程序。除此之外,还有另一个解决方案Shibboleth。 我想知道与我的上下文匹配的最佳解决方案是什么。之间,这不是Spring应用程序。 谢谢