1 场景
spring的bean命名空间中,除了spring内部的bean,还有自己定义的bean
。有时候,我们需要确定自己定义的bean哪些生效
了。
2 步骤
使用spring的applicationContext.getBeanDefinitionNames()
,来获取命名空间内所有的bean的name,然后根据bean的name获取bean的class信息
,根据需要的bean的包路径
,来过滤
出自己需要的bean的信息。
需要的bean的信息,主要包括:bean的类路径,和bean的name。
其中同一个bean的类型下,有可能有多个name。如下:
public class UserServiceImplC implements UserService {
}
@Bean
public UserServiceImplC userServiceImplC1() {
return new UserServiceImplC();
}
@Bean
public UserServiceImplC userServiceImplC2() {
return new UserServiceImplC();
}
3 代码
3.1 准备
定义如下工具类,可以在非spring命名空间内
用来获取spring命名空间:
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* 获取spring命名空间
* @return
*/
public static ApplicationContext getSpringContext(){
return SpringContextUtil.applicationContext;
}
}
如在spring命名空间内
,通过如下方式注入ApplicationContext
即可:
@Autowired
private ApplicationContext applicationContext;
3.2 实现
// 过滤bean路径前缀
String beanClassPathPrefix = "com.sa.example.sp.service.impl";
// spring命名空间
ApplicationContext applicationContext = SpringContextUtil.getSpringContext();
// 过滤后结果
List<Map<String, String>> beanList = Arrays.stream(applicationContext.getBeanDefinitionNames())
// 转换流内容为"bean对象路径"、"bean名称"的对象
.map(beanName -> {
Map<String, String> map = new HashMap<>();
String className = applicationContext.getBean(beanName).getClass().getName();
map.put("beanName", beanName);
map.put("beanClassPath", className);
return map;
})
// 过滤非自定义bean(根据包路径过滤)
.filter(map -> map.get("beanClassPath").startsWith(beanClassPathPrefix))
// 按照bean类型排序
.sorted(Comparator.comparing(map -> map.get("beanClassPath")))
// 输出结果为List
.collect(Collectors.toList());
// --------------------测试,输出结果--------------------
beanList.stream().forEach(map -> {
System.out.println("bean类路径:" + map.get("beanClassPath") + ",bean名称:" + map.get("beanName"));
});
输出内容如下:
bean类路径:com.sa.example.sp.service.impl.UserServiceImplA,bean名称:userServiceImplA
bean类路径:com.sa.example.sp.service.impl.UserServiceImplB,bean名称:userServiceImplB
bean类路径:com.sa.example.sp.service.impl.UserServiceImplC,bean名称:userServiceImplC1
bean类路径:com.sa.example.sp.service.impl.UserServiceImplC,bean名称:userServiceImplC2
4 补充
如果想获取某个类,有哪些bean的实例
,可以通过如下方法:
applicationContext.getBeanNamesForType(UserServiceImplC.class)
返回的结果,为此java类对应的bean的name,如下:
[userServiceImplC1, userServiceImplC2]
如果,java类不存在对应的bean的实例,则返回空的字符串数组
网友评论