如何从ConfigurableApplicationContext获取Bean所在包,区分Bean来源
解决方案:通过Bean元数据获取包名实现Bean过滤
核心逻辑
Spring容器中的BeanDefinition对象存储了Bean的完整元数据,其中包含Bean对应类的全限定名,解析这个全限定名就能提取包名,以此区分用户自定义Bean和Spring Boot框架自带Bean。
代码实现
修改原有代码,通过BeanDefinition获取类信息并按包名分类:
@TestConfiguration static class BeanInventoryConfiguration { record BeanInventory(List<String> userBeans, List<String> frameworkBeans) {} @Bean public BeanInventory getBeanInventory(ConfigurableApplicationContext applicationContext) { String[] allBeanNames = applicationContext.getBeanDefinitionNames(); // 替换为你的项目基础包路径 String userBasePackage = "ms.info.ms"; List<String> userBeans = new ArrayList<>(); List<String> frameworkBeans = new ArrayList<>(); for (String beanName : allBeanNames) { BeanDefinition beanDef = applicationContext.getBeanDefinition(beanName); String beanClassName = beanDef.getBeanClassName(); if (beanClassName != null) { // 从全限定类名中提取包名 String packageName = beanClassName.substring(0, beanClassName.lastIndexOf('.')); if (packageName.startsWith(userBasePackage)) { userBeans.add(beanName); } else { frameworkBeans.add(beanName); } } else { // 动态生成的代理类等无明确类名的Bean,默认归为框架Bean frameworkBeans.add(beanName); } } return new BeanInventory(userBeans, frameworkBeans); } }
额外说明
- 动态Bean处理:像AOP代理、Scoped代理这类Spring动态生成的Bean,
getBeanClassName()会返回null,可通过beanDef.getFactoryBeanName()或判断Bean定义类型进一步细化分类,通常这类Bean属于框架范畴。 - 多用户包适配:如果项目有多个基础包,可将
userBasePackage改为列表,循环判断包名是否匹配任意一个基础包前缀。 - 进阶区分方式:除了包名,还可以通过
BeanDefinition.getResourceDescription()查看Bean的来源文件,用户Bean一般来自项目内的注解类,框架Bean则来自依赖jar包中的配置。
内容的提问来源于stack exchange,提问作者jabrena
相关产品推荐
相关产品推荐

