• 笔记4 解决自动装配时的歧义性


    当多个bean实现同一接口时,如何装配指定的bean?

    1.定义Dessert接口:Dessert.java

    1 package Desserts;
    2 
    3 public interface Dessert {
    4     public void alert();
    5 
    6 }

    2.创建三个实现Dessert接口的类:Cookies.java、IceCream.java、Cake.java,并分别添加@Component注解,表明是一个bean。

    Cookies.java

     1 package Desserts;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 @Component()
     6 public class Cookies implements Dessert {
     7 
     8     @Override
     9     public void alert() {
    10         // TODO Auto-generated method stub
    11         System.out.println("我是Cold、Creamy的Cookies!");
    12     }
    13 
    14 }

    IceCream.java

     1 package Desserts;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 @Component
     6 public class IceCream implements Dessert {
     7 
     8     @Override
     9     public void alert() {
    10         // TODO Auto-generated method stub
    11         System.out.println("我是Cold、Soft的IceCream!");
    12     }
    13 
    14 }

    Cake.java

     1 package Desserts;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 @Component
     6 public class Cake implements Dessert {
     7 
     8     @Override
     9     public void alert() {
    10         // TODO Auto-generated method stub
    11         System.out.println("我是Cake!");
    12     }
    13 
    14 }

    3.创建Java配置文件(自动化装配)。

    DessertConfig.java

     1 package Desserts;
     2 
     3 import org.springframework.context.annotation.ComponentScan;
     4 import org.springframework.context.annotation.Configuration;
     5 
     6 @Configuration
     7 @ComponentScan
     8 public class DessertConfig {
     9 
    10 }

    4.测试

    DessertTest.java

     1 package Desserts;
     2 
     3 import org.junit.Test;
     4 import org.junit.runner.RunWith;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.test.context.ContextConfiguration;
     7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     8 
     9 @RunWith(SpringJUnit4ClassRunner.class)
    10 @ContextConfiguration(classes = Desserts.DessertConfig.class)
    11 public class DessertTest {
    12     @Autowired
    13     private Dessert d;
    14 
    15     @Test
    16     public void test() {
    17         d.alert();
    18 
    19     }
    20 
    21 }

    5.结果分析

    由于有三个Dessert接口的实现,所以在加载的时候就出现错误:

    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [Desserts.Dessert] is defined: expected single matching bean but found 3: cake,cookies,iceCream
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1079)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:967)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:543)
    ... 28 more

    6.进行限定

    方法一:

      在使用@Component注解时直接指定bean的ID(或者使用@Qualifier来指定),在测试时用@Qualifier注解进行指定装配。

        <1>在Cake.java中进行指定

     1 package Desserts;
     2 
     3 import org.springframework.stereotype.Component;
     4 //@Qualifier("Cake")
     5 @Component("Cake")
     6 public class Cake implements Dessert {
     7 
     8     @Override
     9     public void alert() {
    10         // TODO Auto-generated method stub
    11         System.out.println("我是Cake!");
    12     }
    13 
    14 }

        <2>测试

    package Desserts;
    
    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;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = Desserts.DessertConfig.class)
    public class DessertTest {
        @Autowired
        @Qualifier("Cake")
        private Dessert d;
    
    
        @Test
        public void test() {
            d.alert();
    
        }
    
    }

        <3>结果:

    方法二:

      使用@Primary注解进行标识,表明此bean的重要性,首先加载。

        <1>在IceCream.java中进行指定

     1 package Desserts;
     2 
     3 import org.springframework.context.annotation.Primary;
     4 import org.springframework.stereotype.Component;
     5 
     6 @Component
     7 @Primary
     8 public class IceCream implements Dessert {
     9 
    10     @Override
    11     public void alert() {
    12         // TODO Auto-generated method stub
    13         System.out.println("我是IceCream!");
    14     }
    15 
    16

        <2>测试

     1 package Desserts;
     2 
     3 import org.junit.Test;
     4 import org.junit.runner.RunWith;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.test.context.ContextConfiguration;
     7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     8 
     9 @RunWith(SpringJUnit4ClassRunner.class)
    10 @ContextConfiguration(classes = Desserts.DessertConfig.class)
    11 public class DessertTest {
    12     @Autowired
    13     private Dessert d;
    14 
    15     @Test
    16     public void test() {
    17         d.alert();
    18 
    19     }
    20 
    21 }

        <3>结果

    方法三:

      使用自定义的限定符进行注释。

      当实现类既具有相同的特征、又有不同的特征时,这时就需要自定义限定符进行注释,因为Java不允许在同一个条目上重复出现相同类型 的多个注解。

        <1>创建自定义注解

          假设描述Dessert有三个关键字:Cold、Creamy、Soft,分别创建三个注解,只是类名不一样,在此给出Cold的代码。

          Cold.java    

     1 package Desserts;
     2 
     3 import java.lang.annotation.ElementType;
     4 import java.lang.annotation.Retention;
     5 import java.lang.annotation.RetentionPolicy;
     6 import java.lang.annotation.Target;
     7 
     8 import org.springframework.beans.factory.annotation.Qualifier;
     9 
    10 @Target({ ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
    11 @Retention(RetentionPolicy.RUNTIME)
    12 @Qualifier
    13 public @interface Cold {
    14 
    15 }

        <2>对不同的类进行注解

          IceCream.java

     1 package Desserts;
     2 
     3 import org.springframework.context.annotation.Primary;
     4 import org.springframework.stereotype.Component;
     5 
     6 @Component
     7 @Primary
     8 @Cold
     9 @Soft
    10 public class IceCream implements Dessert {
    11 
    12     @Override
    13     public void alert() {
    14         // TODO Auto-generated method stub
    15         System.out.println("我是Cold、Soft的IceCream!");
    16     }
    17 
    18 }

          Cookies.java

     1 package Desserts;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 @Component
     6 @Cold
     7 @Creamy
     8 public class Cookies implements Dessert {
     9 
    10     @Override
    11     public void alert() {
    12         // TODO Auto-generated method stub
    13         System.out.println("我是Cold、Creamy的Cookies!");
    14     }
    15 
    16 }

        <3>测试

     1 package Desserts;
     2 
     3 import org.junit.Test;
     4 import org.junit.runner.RunWith;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.test.context.ContextConfiguration;
     7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     8 
     9 @RunWith(SpringJUnit4ClassRunner.class)
    10 @ContextConfiguration(classes = Desserts.DessertConfig.class)
    11 public class DessertTest {
    12     @Autowired
    13     @Cold
    14     @Creamy
    15     private Dessert d;
    16 
    17     @Autowired
    18     @Cold
    19     @Soft
    20     private Dessert d2;
    21 
    22     @Test
    23     public void test() {
    24         d.alert();
    25         d2.alert();
    26 
    27     }
    28 
    29 }

        <4>结果

  • 相关阅读:
    javascript删除JSON元素
    State ,Getter , Mutation , Action , Module
    mutation和action区别
    图片懒加载
    git命令合并分支代码
    vue 项目生产环境下去重console
    rem px pt em (区别)
    npm 安装依赖 以及dependencies 和 devDependencies的区别
    仿百度搜索
    h5页面在移动端需要注意的一些事情
  • 原文地址:https://www.cnblogs.com/lyj-gyq/p/8872646.html
Copyright © 2020-2023  润新知