Spring Boot 将 Bean 对象注入到 Map 和 List 中
Spring Boot Spring About 3,534 words解释
Spring支持将@Service、@Bean等Spring托管的类,注入到Map和List中。
案例
如登陆服务,有一个抽象类LoginService,分别有微信登录和QQ登陆都实现了这个抽象类。
那么在登陆Controller中可以注入Map<String, LoginService>,Spring会自动将微信登陆和QQ登陆的实现类按key等于类名,value等于实现类实例的方式注入。
List<LoginService>则是直接注入所有实现类。
代码
public interface LoginService {
void login(String username, String password);
}
@Service
public class QQLoginService implements LoginService {
@Override
public void login(String username, String password) {
System.out.println("QQLoginService login");
}
}
@Service
public class WXLoginService implements LoginService{
@Override
public void login(String username, String password) {
System.out.println("WXLoginService login");
}
}
@RestController
public class LoginController {
@Resource
Map<String, LoginService> loginServiceMap;
@Resource
List<LoginService> loginServiceList;
@GetMapping("/login")
public void login(@RequestParam String type) {
LoginService loginService = loginServiceMap.get(type);
loginService.login("username", "password");
System.out.println("loginServiceMap: " + loginServiceMap);
System.out.println("loginServiceList: " + loginServiceList);
}
}
输出
loginServiceMap: {QQLoginService=com.example.controller.QQLoginService@4c7e978c, WXLoginService=com.example.controller.WXLoginService@354e7004}
loginServiceList: [com.example.controller.QQLoginService@4c7e978c, com.example.controller.WXLoginService@354e7004]
源码
DefaultListableBeanFactory中的resolveMultipleBeans方法判断是Map的注入会调用resolveMultipleBeanMap方法。
package org.springframework.beans.factory.support;
public class DefaultListableBeanFactory ... {
@Nullable
public Object doResolveDependency(...) throws BeansException {
// Step 3a: multiple beans as stream / array / standard collection / plain map
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
}
@Nullable
private Object resolveMultipleBeans(...) {
Class<?> type = descriptor.getDependencyType();
if (descriptor instanceof StreamDependencyDescriptor streamDependencyDescriptor) {
// ...
} ...
else if (Map.class == type) {
return resolveMultipleBeanMap(descriptor, beanName, autowiredBeanNames, typeConverter);
}
}
@Nullable
private Object resolveMultipleBeanMap(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
if (String.class != keyType) {
return null;
}
Class<?> valueType = mapType.resolveGeneric(1);
if (valueType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return converter.convertIfNecessary(matchingBeans, descriptor.getDependencyType());
}
}
Views: 11 · Posted: 2026-01-19
———         Thanks for Reading         ———
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...