依赖注入(一个接口多个实现类)

问题描述

Exception in thread “main” org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘com.wcf.demo08.IAService’ available: expected single matching bean but found 2: AServiceImpl1,AServiceImpl2
预期单个bean匹配,但是发现了两个

案例代码

服务接口

package com.wcf.demo08;
public interface IAService {
    void show();
}

服务接口实现类

package com.wcf.demo08;
import org.springframework.stereotype.Service;

@Service
public class AServiceImpl1 implements IAService {
    @Override
    public void show() {
        System.out.println("调用了AServiceImpl1的show方法");
    }
}
package com.wcf.demo08;
import org.springframework.stereotype.Service;

@Service
public class AServiceImpl2 implements IAService {
    @Override
    public void show() {
        System.out.println("调用了AServiceImpl2的show方法");
    }
}

Java配置类

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {"com.wcf.demo08"})
public class JavaConfig {

}

测试

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig.class);
        IAService bean = applicationContext.getBean(IAService.class);
        bean.show();
    }
}

问题出现的原因

以上同一类型的对象在IOC容器当中有两个,这个时候如果我们仅仅只是通过类型来查找,那么就会报错

解决方案

方案一

通过组合条件查找,通过类型+bean名字的方式

代码

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig.class);
        IAService bean = applicationContext.getBean("AServiceImpl1", IAService.class);
        bean.show();
    }
}

测试

运行结果:

调用了AServiceImpl1的show方法

补充

在AServiceImpl1和AServiceImpl2实现类上,我们只是添加了@Service注解,并没有显示的指定实现类在IOC容器中的bean的名称(被IOC容器管理的类就称之为是一个bean),默认的名字就是类名

也可以查看被IOC容器管理的类型叫啥玩意

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig.class);
        String[] beanNamesForType = applicationContext.getBeanNamesForType(IAService.class);
        Arrays.stream(beanNamesForType).forEach(System.out::println);
    }
}

运行结果:

AServiceImpl1
AServiceImpl2

方案二

使用@Primary,当自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者

代码

在AServiceImpl1类上加@Primary注解

package com.wcf.demo08;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

@Service
@Primary
public class AServiceImpl1 implements IAService {
    @Override
    public void show() {
        System.out.println("调用了AServiceImpl1的show方法");
    }
}

测试

package com.wcf.demo08;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig.class);
        IAService bean = applicationContext.getBean(IAService.class);
        bean.show();
    }
}

运行结果

调用了AServiceImpl2的show方法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值