英文:
How to get the Bean package from ConfigurableApplicationContext
问题
使用类似于ConfigurableApplicationContext的接口,可以检索在Spring DI容器中运行的Bean列表,但我想知道哪些Bean来自用户空间,哪些Bean来自Spring Boot / Spring Boot Starters。
@TestConfiguration
static class BeanInventoryConfiguration {
@Autowired
private ConfigurableApplicationContext applicationContext;
record BeanInventory(List<String> beans) {}
@Bean
public BeanInventory getBeanInventory(ConfigurableApplicationContext applicationContext) {
String[] allBeanNames = applicationContext.getBeanDefinitionNames();
return new BeanInventory(Arrays.stream(allBeanNames).toList());
}
}
是否存在一种方法可以返回Bean所在的包?
如果我知道包,我可以轻松地进行筛选。
在Spring的Javadoc中,我没有找到一种方法:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ConfigurableApplicationContext.html
非常感谢您的提前帮助。
英文:
Using a interface like ConfigurableApplicationContext, it is possible to retrieve the list of Beans running in the Spring DI container, but I would like to know what Beans come from the User Space and what Beans comes from the Spring Boot / Spring Boot Starters.
@TestConfiguration
static class BeanInventoryConfiguration {
@Autowired
private ConfigurableApplicationContext applicationContext;
record BeanInventory(List<String> beans) {}
@Bean
public BeanInventory getBeanInventory(ConfigurableApplicationContext applicationContext) {
String[] allBeanNames = applicationContext.getBeanDefinitionNames();
return new BeanInventory(Arrays.stream(allBeanNames).toList());
}
}
Does exist a way to return the package where the Bean is located?
If I know the package, I could filter in a easy way.
Reviewing the Javadoc from Spring, I didnt find a way:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ConfigurableApplicationContext.html
Many thanks in advance
答案1
得分: 0
我找到了一个解决方案:
@TestConfiguration
public class BeanInventory {
@Autowired
private ConfigurableApplicationContext applicationContext;
public record BeanInfo(String name, String pkg) {}
private final List<BeanInfo> beans = new ArrayList<>();
@PostConstruct
private void after() {
final String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String beanName : beanNames) {
final Object beanObject = applicationContext.getBean(beanName);
Class<?> targetClass = AopUtils.getTargetClass(beanObject);
if (AopUtils.isJdkDynamicProxy(beanObject)) {
Class<?>[] proxiedInterfaces = AopProxyUtils.proxiedUserInterfaces(beanObject);
Assert.isTrue(proxiedInterfaces.length == 1, "Only one proxied interface expected");
targetClass = proxiedInterfaces[0];
}
beans.add(new BeanInfo(beanName, targetClass.getPackageName()));
}
}
public List<BeanInfo> getBeans() {
return beans;
}
}
更多信息请参阅:
https://github.com/spring-projects/spring-framework/issues/29973#event-8527246281
注:非常感谢Simon Basle。
英文:
I found a solution for it:
@TestConfiguration
public class BeanInventory {
@Autowired
private ConfigurableApplicationContext applicationContext;
public record BeanInfo(String name, String pkg) {}
private final List<BeanInfo> beans = new ArrayList<>();
@PostConstruct
private void after() {
final String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String beanName : beanNames) {
final Object beanObject = applicationContext.getBean(beanName);
Class<?> targetClass = AopUtils.getTargetClass(beanObject);
if (AopUtils.isJdkDynamicProxy(beanObject)) {
Class<?>[] proxiedInterfaces = AopProxyUtils.proxiedUserInterfaces(beanObject);
Assert.isTrue(proxiedInterfaces.length == 1, "Only one proxied interface expected");
targetClass = proxiedInterfaces[0];
}
beans.add(new BeanInfo(beanName, targetClass.getPackageName()));
}
}
public List<BeanInfo> getBeans() {
return beans;
}
}
Further information here:
https://github.com/spring-projects/spring-framework/issues/29973#event-8527246281
Note: Many thanks to Simon Basle
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论