如何根据指定RabbitTemplate对象获取对应的Spring Bean名称?
获取Spring注入Bean对应的Bean名称
问题场景
已定义两个RabbitTemplate类型的Bean:
@Bean("name1") public RabbitTemplate template1(RabbitProperties properties, ConnectionFactory factory) { return rabbitCreateOneTemplate(factory, properties.getTemplate()); } @Bean("name2") public RabbitTemplate template2(RabbitProperties properties, ConnectionFactory factory) { return rabbitCreateTwoTemplate(factory, properties.getTemplate()); }
通过@Qualifier注入指定Bean后,希望从已注入的template对象获取其对应的Bean名称(如"name1")。
实现方案
方案一:借助BeanFactory遍历匹配
注入BeanFactory后,遍历同类型Bean的名称,对比实例一致性来获取目标名称:
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.support.BeanFactoryUtils; import org.springframework.stereotype.Component; @Component public class Const { private final RabbitTemplate template; private final BeanFactory beanFactory; public Const(@Qualifier("name1") RabbitTemplate template, BeanFactory beanFactory) { this.template = template; this.beanFactory = beanFactory; } public String getTemplateBeanName() { String[] rabbitTemplateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, RabbitTemplate.class); for (String name : rabbitTemplateNames) { if (template.equals(beanFactory.getBean(name))) { return name; } } return null; } }
方案二:自定义BeanPostProcessor缓存实例与名称映射
通过BeanPostProcessor在Bean初始化时记录实例与名称的对应关系,后续直接查询:
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Component public class BeanInstanceNameCache implements BeanPostProcessor { private static final Map<Object, String> INSTANCE_TO_NAME = new ConcurrentHashMap<>(); @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { INSTANCE_TO_NAME.put(bean, beanName); return bean; } public static String getBeanName(Object bean) { return INSTANCE_TO_NAME.get(bean); } }
在需要获取名称的类中直接调用:
private final RabbitTemplate template; public Const(@Qualifier("name1") RabbitTemplate template) { this.template = template; } public String getTemplateBeanName() { return BeanInstanceNameCache.getBeanName(template); }
注意事项
- 方案一适合单例Bean场景,若使用原型Bean,每次获取的实例会不同,对比可能失效;
- 方案二若处理原型Bean,建议改用
WeakHashMap避免内存泄漏; - 两种方案均仅适用于Spring容器管理的Bean实例。
内容的提问来源于stack exchange,提问作者Kirill Zhurbin
相关产品推荐
相关产品推荐

