前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用@Autowired注入父类对象时会报错,找到多个bean对象处理

使用@Autowired注入父类对象时会报错,找到多个bean对象处理

原创
作者头像
bug专8
修改2021-01-11 11:01:20
3.8K0
修改2021-01-11 11:01:20
举报
文章被收录于专栏:Java菜鸡冲冲冲!

问题描述:

当一个父类拥有子类时,通过@Autowired注入父类对象时会报错,无法区分注入的对象是父对象还是子对象。

父类(部分代码):

代码语言:javascript
复制
public class RedisTemplate implements IRedisTemplate {
	private Log log = LogFactory.getLog(IRedisTemplate.class);

	private ShardedJedisPool shardedJedisPool;
	
	private static boolean isEnabled = true;
	
	/**
	 * @param shardedJedisPool the shardedJedisPool to set
	 */
	public void setShardedJedisPool(ShardedJedisPool shardedJedisPool) {
		this.shardedJedisPool = shardedJedisPool;
	}
	
	@PostConstruct
	private void checkConnect() {
		try {
			log.info("系统启动,检查Redis服务是否启动!");
			ShardedJedis jedis = shardedJedisPool.getResource();
			isEnabled = jedis!=null?true:false;
			log.info("Redis服务已启动!");
		}catch (Exception e) {
			log.error("redis 连接失败:"+e.getMessage());
			isEnabled = false;
		}
	}
	
	public static boolean isEnable() {
		return isEnabled;
	}
	
	public boolean valiEnable() {
		//如果启用状态为false,主动尝试一次连接,更新状态
		if(!isEnabled) {
			try {
				log.info("系统启动,检查Redis服务是否启动!");
				ShardedJedis jedis = shardedJedisPool.getResource();
				isEnabled = (jedis!=null?true:false);
				log.info("Redis服务已启动!");
			}catch (Exception e) {
				log.error("redis 连接失败:"+e.getMessage());
				isEnabled = false;
			}
		}
		
		return isEnabled;
	}
	
	/* (non-Javadoc)
	 * @see com.sf.redis.client.IRedisTemplate#set(java.lang.String, java.lang.String)
	 */
	public void set(String key, String value) {
		if(!valiEnable()) {
			return;
		}
		try {
			ShardedJedis jedis = shardedJedisPool.getResource();
			jedis.set(SerializationUtils.serialize(key), SerializationUtils.serialize(value));
			jedis.close();
		} catch (Exception e) {
			e.printStackTrace();
			isEnabled = false;
			log.error("redis 连接失败:"+e.getMessage());
		}
	}

子类:

代码语言:javascript
复制
@Component
public class RedisUtil extends RedisTemplate {

	private Log log = LogFactory.getLog(RedisUtil.class);

	@Autowired
	private ShardedJedisPool shardedJedisPool;

	private static boolean isEnabled = true;

	public Long setnx(String key, int seconds, String value) {
		if(!valiEnable()) {
			return null;
		}
		try {
			ShardedJedis jedis = shardedJedisPool.getResource();
			Long result = jedis.setnx(SerializationUtils.serialize(key),SerializationUtils.serialize(value));
			jedis.expire(SerializationUtils.serialize(key),seconds);
			jedis.close();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			isEnabled = false;
			log.error("redis 连接失败:"+e.getMessage());
		}
		return null;
	}
}

当有地方注入父类对象时:

代码语言:javascript
复制
@Autowired
private IRedisTemplate redisService;

启动报错如下:

代码语言:javascript
复制
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.sf.redis.client.IRedisTemplate] is defined: expected single matching bean but found 2: redisUtil,redisTemplate
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:508)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:486)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:615)
	at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:308)
	... 189 more

处理办法:

1、将@Autowired换成@Resource(name = "指定注入Bean的名称")

  • 这里@Autowired注解的意思就是,当Spring发现@Autowired注解时,将自动在代码上下文中找到和其匹配(默认是类型匹配)的Bean,并自动注入到相应的地方去。
  • @Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
  • 指定了name或者type则根据指定的类型去匹配bean
  • 指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错
代码语言:javascript
复制
@Resource(name = "redisService",type = IRedisTemplate.class)
private IRedisTemplate redisService;

2、使用@Qualifier("指定注入Bean的名称")

代码语言:javascript
复制
@Autowired
@Qualifier("redisService")
private IRedisTemplate redisService;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述:
  • 父类(部分代码):
  • 子类:
  • 当有地方注入父类对象时:
  • 启动报错如下:
  • 处理办法:
    • 1、将@Autowired换成@Resource(name = "指定注入Bean的名称")
      • 2、使用@Qualifier("指定注入Bean的名称")
      相关产品与服务
      云数据库 Redis
      腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档