Spring学习 - 自动装配同一个接口的多个实现类

作者: followtry | 2019-12-03 | 阅读
「编辑」 「本文源码」

介绍

在平时使用 Spring 的 DI 机制时,几乎都是在某个类中引用接口的单个实现。但是Spring 如何将多个实现类同时注入进List<Interface> 中呢。好吧,不说废话了,直接上代码吧。

原来的引用方式

public interface HelloService {
    void sayHello();
}

@Service
public class TestServiceImpl implements TestService {
    @Autowired
    private HelloService  helloService;
}

Spring 高级功能

还是以HelloService接口为例,实现多个实例。

HelloService接口

public interface HelloService {

    void sayHello();
}

HelloService实现类

分别实例化的三个与世界打招呼的实现类。

@Service("Cat")
@Order(10)
public class CatHelloService implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("I'm a Cat,Hello world!");
    }
}

@Service
@Order(3)
public class DogHelloService implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("I'm a Dog,Hello world!");
    }
}

@Service
@Order(1)
public class PigHelloService implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("I'm a pig,Hello world!");
    }
}

通过@Service("Cat")指定实现类的 bean 名称,通过@Order(3)来指定实现类的顺序。

引用HelloService的测试类

public interface TestService {

    void sayHello();
}

@Service
public class TestServiceImpl implements TestService {

    @Autowired
    private List<HelloService> multiServiceList;

    @Autowired
    private Map<String, HelloService> multiServiceMap;

    @Override
    public void sayHello() {
        System.out.println("--------------list--------------");
        for (HelloService multiService : multiServiceList) {
            multiService.sayHello();
        }

        System.out.println("--------------map--------------");
        for (Map.Entry<String, HelloService> entry : multiServiceMap.entrySet()) {
            System.out.println("key=" + entry.getKey());
            entry.getValue().sayHello();
        }
    }
}

TestServiceImpl该类中,通过 List和 Map 两种方式引入了HelloService的实现类注入,期望是可以按照我们的预期将HelloService的所有类都注入。

测试主类

初始化 Spring 并调用TestService的方法

public class TestMain {
    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext("cn.followtry.boot");
        TestService testService = applicationContext.getBean(TestService.class);
        testService.sayHello();
        System.out.println("结束");
    }
}

执行结果

--------------list--------------
I'm a pig,Hello world!
I'm a Dog,Hello world!
I'm a Cat,Hello world!
--------------map--------------
key=Cat
I'm a Cat,Hello world!
key=dogHelloService
I'm a Dog,Hello world!
key=pigHelloService
I'm a pig,Hello world!
结束

通过打印结果可以发现,

  1. Spring帮我们将接口的所有实现类都注入进了TestServiceList<HelloService>,并且是按照我们通过@Order指定的顺序,如果不指定Service 名称,会以默认名称的首字母排序。
  2. Spring 也将接口的所有实现类都注入进了TestServiceMap<String, HelloService>,Key为 Bean 的名称,value 为对应的实现类。因为Map具体类型为LinkedHashMap,没有按照我们指定的顺序执行。

版权声明:本文由 followtry 在 2019年12月03日发表。本文采用CC BY-NC-SA 4.0许可协议,非商业转载请注明出处,不得用于商业目的。
文章题目及链接:《Spring学习 - 自动装配同一个接口的多个实现类》




  相关文章:

「游客及非Github用户留言」:

「Github登录用户留言」:

TOP