十四、处理自动装配的歧义性

来源:互联网 发布:java中字符串转json 编辑:程序博客网 时间:2024/06/05 14:24

自动装配能够提供很大的帮助,她会减少应用程序组件的所需要的显式配置的数量。

不过,仅有一个bean匹配所需的结果式,自动装配才是有效的。如果不仅有一个bean能够匹配结果的话,这种歧义性会阻碍Spring自动装配属性、构造参数或方法参数。

产生歧义的代码示例

一个服务的接口:

package com.lf.service;/** * Created by LF on 2017/5/2. */public interface Person {    void  say();}

接口的三个实现:

package com.lf.service.impl;import com.lf.service.Person;import org.springframework.stereotype.Service;/** * Created by LF on 2017/5/2. */@Servicepublic class Teacher implements Person {    @Override    public void say() {        System.err.println("老师===================");    }}
package com.lf.service.impl;import com.lf.service.Person;import org.springframework.stereotype.Service;/** * Created by LF on 2017/5/2. */@Servicepublic class Student implements Person {    @Override    public void say() {        System.err.println("学生===========");    }}
package com.lf.service.impl;import com.lf.service.Person;import org.springframework.stereotype.Service;/** * Created by LF on 2017/5/2. */@Servicepublic class Father implements Person {    @Override    public void say() {        System.err.println("父亲===============");    }}

配置类

package com.lf;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;/** * Created by LF on 2017/5/2. */@Configuration@ComponentScanpublic class Config {}

工程结构:
这里写图片描述

测试代码:

package com.lf;import com.lf.service.Person;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * Unit test for simple App. */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = {Config.class})public class AppTest {    @Autowired    private Person person;    @Test    public void t1() {        person.say();    }}

因为这三个类都使用了@Service注解,在组件扫描的时候,能够发现他们并将他们注入到spring的上下文中。当spring进行自动装配的时候,它并没有唯一。无歧义的参数可选。

标志首选的bean

在Spring中可以使用@Primary来表示首选的bean,@Primary可以和@Service组合使用在组件扫描上,也可以和@bean组合在Java配置的bean声明中。

package com.lf.service.impl;import com.lf.service.Person;import org.springframework.context.annotation.Primary;import org.springframework.stereotype.Service;/** * Created by LF on 2017/5/2. */@Service@Primarypublic class Student implements Person {    @Override    public void say() {        System.err.println("学生===========");    }}
package com.lf;import com.lf.service.Person;import com.lf.service.impl.Student;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;/** * Created by LF on 2017/5/2. */@Configuration@ComponentScanpublic class Config {    @Bean    @Primary    public Person student(){        return new Student();    }}

限定自动装配的bean

@Primary无法将可选的方案,限定到一个唯一的歧义选项中。它只能代表一个最优的可选方案。
spring的限定符注解@Qualifier可以在所有的的bean上进行小范围的操作。
它可以和@Autowired协同使用,在注入的时候,指定要注入的是哪个bean。

package com.lf;import com.lf.service.Person;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * Unit test for simple App. */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = {Config.class})public class AppTest {    @Autowired    @Qualifier("student")    private Person person;    @Test    public void t1() {        person.say();    }}

#创建自定义的限定符
我们可以为bean设置自己的限定符,而不是依赖bean的ID作为限定符。

package com.lf.service.impl;import com.lf.service.Person;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;/** * Created by LF on 2017/5/2. */@Service@Qualifier("student1")public class Teacher implements Person {    @Override    public void say() {        System.err.println("老师===================");    }}

当使用Java代码显式定义bean的时候,也可以使用@Qualifier

   @Bean    @Qualifier("student2")    public Person student() {        return new Student();    }
0 0
原创粉丝点击