Spring学习笔记(六)

有些话、适合烂在心里 提交于 2020-02-03 17:19:29

处理自动装配的歧义性

仅有一个 bean 匹配所需的结果时,自动装配才是有效的。如果不仅有一个 bean 能够匹配结果的话,这种歧义性 Spring 自动装配。

例如下面案例

实体类

@Component
public class IceCream implements Dessert {
    @Override
    public void show() {
        System.out.println("获得冰淇淋");
    }
}
@Component
public class Cake implements Dessert {
    @Override
    public void show() {
        System.out.println("获得蛋糕");
    }
}

业务类

@Component
public class MyService {
    private Dessert dessert;

    public void show(){
        dessert.show();
    }

    @Autowired
    public void setDessert(Dessert dessert) {
        this.dessert = dessert;
    }
}

测试

    public static void main(String[] args) {

        ApplicationContext context = new AnnotationConfigApplicationContext(com.lt.ltconfig.class);
        MyService myService = (MyService) context.getBean("myService");
        myService.show();
    }

在这里,业务类根据接口匹配相应的 bean,但是继承了这个接口的 bean 有两个,Spring 不会帮我们选择,直接报错:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.lt.pojo.Dessert' available: expected single matching bean but found 2: cake,iceCream

此时,自动装配产生了歧义性。

要消除歧义性,Spring 提供了多种可选方案来解决这样的问题。可以将可选 bean 中的莫一个设为首选 (primary) 的 bean,或者使用限定符 (qualifier) 来帮助 Spring 将可选的 bean 的范围缩小到只有一个 bean。

1. 标识首选的 bean

通过将其中一个可选的 bean 设置为首选 (primary) bean 能够避免自动装配时的歧义性。当遇到歧义的时候,Spring 将会使用首选的 bean,而不是其他可选的 bean。当然,首选 bean 应该在一类 bean 中最多存在一个。设置首选 bean 的方法也很简单,在自动装配或者 java 配置中声明 @Primary 即可。xml 中将 bean 元素的 primary 属性设置为 true 即可。

2. 限定自动装配的 bean

2.1 使用限定符

@Qualifier 注解是使用限定符的主要方式,它可以与 @Autowired 和 @Inject 协同使用,在注入的时候指定想要注入进去的是哪个 bean。例如:

实体类

@Component
@Qualifier("iceCream")
public class IceCream implements Dessert {
    @Override
    public void show() {
        System.out.println("获得冰淇淋");
    }
}

业务类

@Component
public class MyService {
    private Dessert dessert;

    public void show(){
        dessert.show();
    }
    
    @Autowired
    @Qualifier("iceCream")
    public void setDessert(Dessert dessert) {
        this.dessert = dessert;
    }
}

当通过 Java 配置显示定义 bean 的时候,@Qualifier 也可以与 @Bean 注解一起使用:

@Bean
@Qualifier("iceCream")
public Dessert iceCream(){
    return new IceCream();
}

2.2 使用自定义的限定符注解

实体类

@Component
@Soft
public class Cake implements Dessert {
    @Override
    public void show() {
        System.out.println("获得蛋糕");
    }
}

业务类

    @Autowired
    @Soft
    public void setDessert(Dessert dessert) {
        this.dessert = dessert;
    }

自定义注解

@Target({ElementType.CONSTRUCTOR,ElementType.FIELD,
         ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Soft {
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!