英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论