spring查看自定义的bean

作者: 水煮鱼又失败了 | 来源:发表于2021-06-07 07:25 被阅读0次

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的实例,则返回空的字符串数组

相关文章

网友评论

    本文标题:spring查看自定义的bean

    本文链接:https://www.haomeiwen.com/subject/hdoqeltx.html