@Autowired and @qualifier



当候选 Bean 数目不为  1  时的应对方法       在默认情况下使用  @Autowired  注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。我们可以来做一个实验:          清单  10 . 候选 Bean 数目为  0  时                        "1.0"  encoding= "UTF-8"  ?>    "http://www.springframework.org/schema/beans"         xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http: //www.springframework.org/schema/beans     http: //www.springframework.org/schema/beans/spring-beans-2.5.xsd ">             class ="org.springframework.beans.factory.annotation.             AutowiredAnnotationBeanPostProcessor"/>            "boss"   class = "com.baobaotao.Boss" />                               "car"   class = "com.baobaotao.Car"  scope= "singleton" >             "brand"  value= " 红旗 CA72" />             "price"  value= "2000" />                        由于 office Bean 被注释掉了,所以 Spring 容器中将没有类型为 Office 的 Bean 了,而 Boss 的 office 属性标注了  @Autowired ,当启动 Spring 容器时,异常就产生了。       当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用  @Autowired (required =  false ),这等于告诉 Spring:在找不到匹配 Bean 时也不报错。来看一下具体的例子:          清单  11 . 使用  @Autowired (required =  false )                        package  com.baobaotao;       import  org.springframework.beans.factory.annotation.Autowired;    import  org.springframework.beans.factory.annotation.Required;       public   class  Boss {            private  Car car;         private  Office office;            @Autowired         public   void  setCar(Car car) {             this .car = car;         }         @Autowired (required =  false )         public   void  setOffice(Office office) {             this .office = office;         }         …    }             当然,一般情况下,使用  @Autowired  的地方都是需要注入 Bean 的,使用了自动注入而又允许不注入的情况一般仅会在开发期或测试期碰到(如为了快速启动 Spring 容器,仅引入一些模块的 Spring 配置文件),所以  @Autowired (required =  false ) 会很少用到。       和找不到一个类型匹配 Bean 相反的一个错误是:如果 Spring 容器中拥有多个候选 Bean,Spring 容器在启动时也会抛出 BeanCreationException 异常。来看下面的例子:          清单  12 . 在 beans.xml 中配置两个 Office 类型的 Bean                        …    "office"   class = "com.baobaotao.Office" >         "officeNo"  value= "001" />       "office2"   class = "com.baobaotao.Office" >         "officeNo"  value= "001" />       …             我们在 Spring 容器中配置了两个类型为 Office 类型的 Bean,当对 Boss 的 office 成员变量进行自动注入时,Spring 容器将无法确定到底要用哪一个 Bean,因此异常发生了。       Spring 允许我们通过  @Qualifier  注释指定注入 Bean 的名称,这样歧义就消除了,可以通过下面的方法解决异常:          清单  13 . 使用  @Qualifier  注释指定注入 Bean 的名称                        @Autowired    public   void  setOffice( @Qualifier ( "office" )Office office) {         this .office = office;    }             @Qualifier ( "office" ) 中的 office 是 Bean 的名称,所以  @Autowired  和  @Qualifier  结合使用时,自动注入的策略就从 byType 转变成 byName 了。 @Autowired  可以对成员变量、方法以及构造函数进行注释,而  @Qualifier  的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同,所以 Spring 不将  @Autowired  和  @Qualifier  统一成一个注释类。下面是对成员变量和构造函数入参进行注释的代码:       对成员变量进行注释:          清单  14 . 对成员变量使用  @Qualifier  注释                        public   class  Boss {         @Autowired         private  Car car;            @Autowired         @Qualifier ( "office" )         private  Office office;         …    }             对构造函数入参进行注释:          清单  15 . 对构造函数变量使用  @Qualifier  注释                        public   class  Boss {         private  Car car;         private  Office office;            @Autowired         public  Boss(Car car ,  @Qualifier ( "office" )Office office){             this .car = car;             this .office = office ;         }    }             @Qualifier  只能和  @Autowired  结合使用,是对  @Autowired  有益的补充。一般来讲, @Qualifier  对方法签名中入参进行注释会降低代码的可读性,而对成员变量注释则相对好一些。   
当候选 Bean 数目不为  1  时的应对方法       在默认情况下使用  @Autowired  注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。我们可以来做一个实验:          清单  10 . 候选 Bean 数目为  0  时                        "1.0"  encoding= "UTF-8"  ?>    "http://www.springframework.org/schema/beans"         xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http: //www.springframework.org/schema/beans     http: //www.springframework.org/schema/beans/spring-beans-2.5.xsd ">             class ="org.springframework.beans.factory.annotation.             AutowiredAnnotationBeanPostProcessor"/>            "boss"   class = "com.baobaotao.Boss" />                               "car"   class = "com.baobaotao.Car"  scope= "singleton" >             "brand"  value= " 红旗 CA72" />             "price"  value= "2000" />                        由于 office Bean 被注释掉了,所以 Spring 容器中将没有类型为 Office 的 Bean 了,而 Boss 的 office 属性标注了  @Autowired ,当启动 Spring 容器时,异常就产生了。       当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用  @Autowired (required =  false ),这等于告诉 Spring:在找不到匹配 Bean 时也不报错。来看一下具体的例子:          清单  11 . 使用  @Autowired (required =  false )                        package  com.baobaotao;       import  org.springframework.beans.factory.annotation.Autowired;    import  org.springframework.beans.factory.annotation.Required;       public   class  Boss {            private  Car car;         private  Office office;            @Autowired         public   void  setCar(Car car) {             this .car = car;         }         @Autowired (required =  false )         public   void  setOffice(Office office) {             this .office = office;         }         …    }             当然,一般情况下,使用  @Autowired  的地方都是需要注入 Bean 的,使用了自动注入而又允许不注入的情况一般仅会在开发期或测试期碰到(如为了快速启动 Spring 容器,仅引入一些模块的 Spring 配置文件),所以  @Autowired (required =  false ) 会很少用到。       和找不到一个类型匹配 Bean 相反的一个错误是:如果 Spring 容器中拥有多个候选 Bean,Spring 容器在启动时也会抛出 BeanCreationException 异常。来看下面的例子:          清单  12 . 在 beans.xml 中配置两个 Office 类型的 Bean                        …    "office"   class = "com.baobaotao.Office" >         "officeNo"  value= "001" />       "office2"   class = "com.baobaotao.Office" >         "officeNo"  value= "001" />       …             我们在 Spring 容器中配置了两个类型为 Office 类型的 Bean,当对 Boss 的 office 成员变量进行自动注入时,Spring 容器将无法确定到底要用哪一个 Bean,因此异常发生了。       Spring 允许我们通过  @Qualifier  注释指定注入 Bean 的名称,这样歧义就消除了,可以通过下面的方法解决异常:          清单  13 . 使用  @Qualifier  注释指定注入 Bean 的名称                        @Autowired    public   void  setOffice( @Qualifier ( "office" )Office office) {         this .office = office;    }             @Qualifier ( "office" ) 中的 office 是 Bean 的名称,所以  @Autowired  和  @Qualifier  结合使用时,自动注入的策略就从 byType 转变成 byName 了。 @Autowired  可以对成员变量、方法以及构造函数进行注释,而  @Qualifier  的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同,所以 Spring 不将  @Autowired  和  @Qualifier  统一成一个注释类。下面是对成员变量和构造函数入参进行注释的代码:       对成员变量进行注释:          清单  14 . 对成员变量使用  @Qualifier  注释                        public   class  Boss {         @Autowired         private  Car car;            @Autowired         @Qualifier ( "office" )         private  Office office;         …    }             对构造函数入参进行注释:          清单  15 . 对构造函数变量使用  @Qualifier  注释                        public   class  Boss {         private  Car car;         private  Office office;            @Autowired         public  Boss(Car car ,  @Qualifier ( "office" )Office office){             this .car = car;             this .office = office ;         }    }             @Qualifier  只能和  @Autowired  结合使用,是对  @Autowired  有益的补充。一般来讲, @Qualifier  对方法签名中入参进行注释会降低代码的可读性,而对成员变量注释则相对好一些。   

你可能感兴趣的:(@Autowired and @qualifier)