1 場(chǎng)景
spring的bean命名空間中,除了spring內(nèi)部的bean乎芳,還有自己定義的bean
。有時(shí)候帖池,我們需要確定自己定義的bean哪些生效
了奈惑。
2 步驟
使用spring的applicationContext.getBeanDefinitionNames()
,來(lái)獲取命名空間內(nèi)所有的bean的name睡汹,然后根據(jù)bean的name獲取bean的class信息
肴甸,根據(jù)需要的bean的包路徑
,來(lái)過(guò)濾
出自己需要的bean的信息囚巴。
需要的bean的信息原在,主要包括:bean的類路徑,和bean的name彤叉。
其中同一個(gè)bean的類型下庶柿,有可能有多個(gè)name。如下:
public class UserServiceImplC implements UserService {
}
@Bean
public UserServiceImplC userServiceImplC1() {
return new UserServiceImplC();
}
@Bean
public UserServiceImplC userServiceImplC2() {
return new UserServiceImplC();
}
3 代碼
3.1 準(zhǔn)備
定義如下工具類秽浇,可以在非spring命名空間內(nèi)
用來(lái)獲取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命名空間內(nèi)
浮庐,通過(guò)如下方式注入ApplicationContext
即可:
@Autowired
private ApplicationContext applicationContext;
3.2 實(shí)現(xiàn)
// 過(guò)濾bean路徑前綴
String beanClassPathPrefix = "com.sa.example.sp.service.impl";
// spring命名空間
ApplicationContext applicationContext = SpringContextUtil.getSpringContext();
// 過(guò)濾后結(jié)果
List<Map<String, String>> beanList = Arrays.stream(applicationContext.getBeanDefinitionNames())
// 轉(zhuǎn)換流內(nèi)容為"bean對(duì)象路徑"、"bean名稱"的對(duì)象
.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;
})
// 過(guò)濾非自定義bean(根據(jù)包路徑過(guò)濾)
.filter(map -> map.get("beanClassPath").startsWith(beanClassPathPrefix))
// 按照bean類型排序
.sorted(Comparator.comparing(map -> map.get("beanClassPath")))
// 輸出結(jié)果為L(zhǎng)ist
.collect(Collectors.toList());
// --------------------測(cè)試柬焕,輸出結(jié)果--------------------
beanList.stream().forEach(map -> {
System.out.println("bean類路徑:" + map.get("beanClassPath") + "审残,bean名稱:" + map.get("beanName"));
});
輸出內(nèi)容如下:
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 補(bǔ)充
如果想獲取某個(gè)類富玷,有哪些bean的實(shí)例
璧坟,可以通過(guò)如下方法:
applicationContext.getBeanNamesForType(UserServiceImplC.class)
返回的結(jié)果没宾,為此java類對(duì)應(yīng)的bean的name,如下:
[userServiceImplC1, userServiceImplC2]
如果沸柔,java類不存在對(duì)應(yīng)的bean的實(shí)例,則返回空的字符串?dāng)?shù)組