配置动态刷新RefreshScope注解使用局限性(一)
在 Spring Cloud 体系的项目中,配置中心主要用于提供分布式的配置管理,其中有一个重要的注解:@RefreshScope,如果代码中需要动态刷新配置,在需要的类上加上该注解就行。本文分享一下笔者遇到与 @ConditionalOnSingleCandidate 注解冲突的问题
问题背景
项目再引入 RabbitMQ,在自定义 connectionFactory 时,手滑加上了 @RefreshScope
@Bean
@RefreshScope
public CachingConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("172.17.0.111");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setVirtualHost("/");
return connectionFactory;
}
系统报错无法注入 RabbitTemplate
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.pig4cloud.course.refresh.bug.RefreshBugApplicationTest':
Unsatisfied dependency expressed through field 'rabbitTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'org.springframework.amqp.rabbit.core.RabbitTemplate' available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
排查
- 默认情况下 spring-boot-starter-amqp 会默认给我们注入 rabbitTemplate 实现
RabbitAutoConfiguration#rabbitTemplate
@Bean
@ConditionalOnSingleCandidate(ConnectionFactory.class)
@ConditionalOnMissingBean(RabbitOperations.class)
public RabbitTemplate rabbitTemplate(RabbitTemplateConfigurer configurer, ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate();
configurer.configure(template, connectionFactory);
return template;
}
- 开启 Spring Boot 启动 debugger 日志,查看注入信息
RabbitAutoConfiguration.RabbitTemplateConfiguration#rabbitTemplate:
Did not match:
- @ConditionalOnSingleCandidate (types: org.springframework.amqp.rabbit.connection.ConnectionFactory; SearchStrategy: all)
did not find a primary bean from beans 'connectionFactory', 'scopedTarget.connectionFactory' (OnBeanCondition)
提示 ConditionalOnSingleCandidate
注解的方法不能查找到唯一 ConnectionFactory
实现
- 使用 @RefreshScope 注解的 bean,默认情况下同时会生成
scopedTarget.beanName
的 bean
- 使用 @RefreshScope 注解的 bean,默认情况下同时会生成
@Autowired
private ApplicationContext context;
@Test
public void testRabbitTemplate() {
String[] beanNames = context.getBeanNamesForType(ConnectionFactory.class);
for (String beanName : beanNames) {
System.out.println(beanName);
}
Assert.isTrue(beanNames.length == 2);
}
scopedTarget.connectionFactory
connectionFactory
- 由于 ConditionalOnSingleCandidate 成立的条件是全局只能有一个此类型的 bean 所以 默认的 RabbitTemplate 无法注入
常见被 ConditionalOnSingleCandidate 注解的 bean
- 使用 JdbcTemplate 无法在自定义 DataSource 添加 @RefreshScope
@ConditionalOnSingleCandidate(DataSource.class)
public class JdbcTemplateAutoConfiguration {}
- MailSenderValidator 邮件发送校验器无法添加 @RefreshScope
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(MailSenderAutoConfiguration.class)
@ConditionalOnProperty(prefix = "spring.mail", value = "test-connection")
@ConditionalOnSingleCandidate(JavaMailSenderImpl.class)
public class MailSenderValidatorAutoConfiguration {}
- 由于默认情况下涉及的 bean 很多,所以使用 RefreshScope 时一定要避免这些 bean
配置动态刷新RefreshScope注解使用局限性(一)的更多相关文章
- SpringCloud04 服务配置中心、消息总线、远程配置动态刷新
1 环境说明 JDK:1.8 MAVENT:3.5 SpringBoot:2.0.5.RELEASE SpringCloud:Finchley.SR1 2 创建服务注册中心(Eureka服务端) 说明 ...
- spring boot 配置动态刷新
本文测试使用的spring cloud版本为: Dalston.SR1 很多朋友只知道spring cloud config可以刷新远程git的配置到内存中, 却不知道spring cloud con ...
- spring,mybatis事务管理配置与@Transactional注解使用[转]
spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...
- spring的配置模式与注解模式基础
“依赖注入”是spring的核心特征,在Web服务器(如Tomcat)加载时,它会根据Spring的配置文件中配置的bean或者是通过注解模式而扫描并装载的bean实例自动注入到Application ...
- 关于什么是SpringMVC,和SpringMVC基于xml配置、注解配置、纯注解配置
首先我们先要了解一下,什么是SpringMVC? SpringMVC是Spring框架内置的MVC的实现.SpringMVC就是一个Spring内置的MVC子框架,也就是说SpringMVC的相关包都 ...
- 事务管理配置与@Transactional注解使用
spring,mybatis事务管理配置与@Transactional注解使用 概述 事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性. Spring Framewor ...
- spring,mybatis事务管理配置与@Transactional注解使用
spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是 ...
- spring启动,spring mvc ,要不要xml配置,基于注解配置
老项目是09-11年搞的,用的是spring+struts2,没有用注解,全xml配置.web.xml中也配置了一大堆. 现在启动新项目,在项目中用spring+springmvc ,主要用注解,也用 ...
- springmvc-02(配置版与注解版区别)
首先,我们来看配置版和注解版的相同步骤: 1.新建一个Moudle , springmvc-02-hello , 添加web的支持! 2.确定导入了SpringMVC 的依赖! 3.配置web.xml ...
随机推荐
- 谁能成为数据储存领域领头羊?永久数据存储--NGK的终极使命!
区块链的目的是永远存储交易网络的历史.NGK技术团队能够永久存储其去中心化账本的副本.这是其日后能进行审计关键.一些著名的团队,如Solana和SKALE,现在正在为此与NGK进行最后的集成,我们预计 ...
- linux DRM 之 GEM 笔记
原文链接:https://www.cnblogs.com/yaongtime/p/14418357.html 在GPU上的各类操作中涉及到多种.多个buffer的使用. 通常我们GPU是通过图像API ...
- CMD 中运行 xx 命令提示 不是内部或外部命令,也不是可运行的程序或批处理文件的问题
出现这个问题的原因一般有2个 这个命令依赖某个软件,而你又没有安装 这里你只需要去下载安装好对应的软件,基本上就可以解决上面的问题了. 软件安装好了,但是需要配置环境变量 第二个原因就按照下图,去设置 ...
- Python学习笔记_类
class Animal(object): # 定义父类animal def __init__(self,name,sound): # 初始化属性 name sound self.name = nam ...
- Laravel Queues 队列应用实战
队列,顾名思义,排着队等着做事情.在生活场景中,凡是排队的人,都是带有目的性的.要完成某件事情,才去排队的,要不没有谁会闲到排队玩儿.而在软件应用层面,队列是什么,队列有什么优点,我们什么时候需要用队 ...
- idea将文件push之后如何回退
- 基于ros2 dashing的建图导航探索
基于ros2 dashing的建图导航探索 1. 环境准备 安装ros2 dashing, 参考链接: https://index.ros.org/doc/ros2/Installation/Dash ...
- css3自动换行排列
如果一行放不下就会自动换行 display: flex; flex-wrap: wrap; 示例 : html <div class="container"> < ...
- 【Saas-export项目】--项目整合(spring整合MVC)
转: [Saas-export项目]--项目整合(spring整合MVC) 文章目录 Spring整合SpringMVC(export_web_manager子工程) (1)log4j.propert ...
- springboot整合jsp,完成公交车站路线图
转: springboot整合jsp,完成公交车站路线图 点赞再看,养成习惯 开发环境: jdk 8 intellij idea tomcat 8 mysql 5.7 maven 3.6 所用技术: ...