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
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