日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JavaSpring各種依賴注入注解的區(qū)別

Spring對于Bean的依賴注入,支持多種注解方式:

 
 
  1. @Resource
  2. javax.annotation
  3. JSR250 (Common Annotations for Java)
  4. @Inject
  5. javax.inject
  6. JSR330 (Dependency Injection for Java)
  7. @Autowired
  8. org.springframework.bean.factory
  9. Spring

直觀上看起來,@Autowired是Spring提供的注解,其他幾個都是JDK本身內(nèi)建的注解,Spring對這些注解也進(jìn)行了支持。但是使用起來這三者到底有什么區(qū)別呢?筆者經(jīng)過方法的測試,發(fā)現(xiàn)一些有意思的特性。

區(qū)別總結(jié)如下:

一、@Autowired有個required屬性,可以配置為false,這種情況下如果沒有找到對應(yīng)的bean是不會拋異常的。@Inject和@Resource沒有提供對應(yīng)的配置,所以必須找到否則會拋異常。

二、 @Autowired和@Inject基本是一樣的,因?yàn)閮烧叨际鞘褂肁utowiredAnnotationBeanPostProcessor來處理 依賴注入。但是@Resource是個例外,它使用的是CommonAnnotationBeanPostProcessor來處理依賴注入。當(dāng)然,兩者 都是BeanPostProcessor。

 
 
  1. @Autowired和@Inject
  2. - 默認(rèn) autowired by type
  3. - 可以 通過@Qualifier 顯式指定 autowired by qualifier name。
  4. - 如果 autowired by type 失?。ㄕ也坏交蛘哒业蕉鄠€實(shí)現(xiàn)),則退化為autowired by field name
  5. @Resource
  6. - 默認(rèn) autowired by field name
  7. - 如果 autowired by field name失敗,會退化為 autowired by type
  8. - 可以 通過@Qualifier 顯式指定 autowired by qualifier name
  9. - 如果 autowired by qualifier name失敗,會退化為 autowired by field name。但是這時候如果 autowired by field name失敗,就不會再退化為autowired by type了。

TIPS Qualified name VS Bean name

在Spring設(shè)計中,Qualified name并不等同于Bean name,后者必須是***的,但是前者類似于tag或者group的作用,對特定的bean進(jìn)行分類??梢赃_(dá)到getByTag(group)的效果。對 于XML配置的bean,可以通過id屬性指定bean name(如果沒有指定,默認(rèn)使用類名首字母小寫),通過標(biāo)簽指定qualifier name:

 
 
  1.     
  2.     

如果是通過注解方式,那么可以通過@Qualifier注解指定qualifier name,通過@Named或者@Component(@Service,@Repository等)的value值指定bean name:

 
 
  1. @Component("lamborghini")
  2. @Qualifier("luxury")
  3. public class Lamborghini implements Car {
  4. }

或者

 
 
  1. @Component
  2. @Named("lamborghini")
  3. @Qualifier("luxury")
  4. public class Lamborghini implements Car {
  5. }

同樣,如果沒有指定bean name,那么Spring會默認(rèn)是用類名首字母小寫(Lamborghini=>lamborghini)。

三、 通過Anotation注入依賴的方式在XML注入方式之前進(jìn)行。如果對同一個bean的依賴同時使用了兩種注入方式,那么XML的優(yōu)先。但是不同擔(dān)心通過Anotation注入的依賴沒法注入XML中配置的bean,依賴注入是在bean的注冊之后進(jìn)行的。

四、目前的autowired by type方式(筆者用的是3.2.3.RELEASE版本),Spring的AutowiredAnnotationBeanPostProcessor 實(shí)現(xiàn)都是有”bug”的,也就是說@Autowired和@Inject都是有坑的(稱之為坑,不稱之為bug是因?yàn)槊菜剖枪室獾?。。)。這是來源于線上 的一個bug,也是這邊文章的寫作原因?,F(xiàn)場如下:

application-context.xml中有如下定義:

 
 
  1.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
  2.     xmlns:context="http://www.springframework.org/schema/context"
  3.     xmlns:util="http://www.springframework.org/schema/util"
  4.     xsi:schemaLocation="
  5.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  7.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  8.         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
  9.     
  10.     
  11.     
  12.         static-field="me.arganzheng.study.spring.autowired.Constants.Language.EN" />
  13.     
  14.         static-field="me.arganzheng.study.spring.autowired.Constants.Language.JP" />
  15.     
  16.         static-field="me.arganzheng.study.spring.autowired.Constants.Language.IND" />
  17.     
  18.         static-field="me.arganzheng.study.spring.autowired.Constants.Language.PT" />
  19.     
  20.         static-field="me.arganzheng.study.spring.autowired.Constants.Language.TH" />
  21.     
  22.         static-field="me.arganzheng.study.spring.autowired.Constants.Language.AR" />
  23.     
  24.         static-field="me.arganzheng.study.spring.autowired.Constants.Language.EN_RIN" />
  25.     
  26.         value-type="java.lang.String">
  27.         
  28.         
  29.         
  30.         
  31.         
  32.         
  33.         
  34.         
  35.         
  36.         
  37.         
  38.         
  39.         
  40.     

其中static-field應(yīng)用的常量定義在如下類中:

 
 
  1. package me.arganzheng.study.spring.autowired;
  2. public interface Constants {
  3.     public interface Language {
  4.         public static final String EN = "CommonConstants.LANG_ENGLISH";
  5.         public static final String JP = "CommonConstants.LANG_JAPANESE";
  6.         public static final String IND = "CommonConstants.LANG_INDONESIAN";
  7.         public static final String PT = "CommonConstants.LANG_PORTUGUESE";
  8.         public static final String TH = "CommonConstants.LANG_THAI";
  9.         public static final String EN_RIN = "CommonConstants.LANG_ENGLISH_INDIA";
  10.         public static final String AR = "CommonConstants.LANG_Arabic";
  11.     }
  12. }

然后如果我們在代碼中如下聲明依賴:

 
 
  1. public class AutowiredTest extends BaseSpringTestCase {
  2.     @Autowired
  3.     private Map languageChangesMap;
  4.     @Test
  5.     public void testAutowired() {
  6.         notNull(languageChangesMap);
  7.         System.out.println(languageChangesMap.getClass().getSimpleName());
  8.         System.out.println(languageChangesMap);
  9.     }
  10. }

Guess what,詭異的事情發(fā)生了!

運(yùn)行結(jié)果如下:

 
 
  1. LinkedHashMap
  2. {en=CommonConstants.LANG_ENGLISH, ja=CommonConstants.LANG_JAPANESE, ind=CommonConstants.LANG_INDONESIAN, pt=CommonConstants.LANG_PORTUGUESE, th=CommonConstants.LANG_THAI, ar=CommonConstants.LANG_Arabic, en-rIn=CommonConstants.LANG_ENGLISH_INDIA}

也就是說Map

 
 
  1. 嚴(yán)重: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@5c51ee0a] to prepare test instance [me.arganzheng.study.spring.autowired.AutowiredTest@6e301e0]
  2. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'me.arganzheng.study.spring.autowired.AutowiredTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.Map me.arganzheng.study.spring.autowired.AutowiredTest.languageChangesMap; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
 
 
  1. ...
  2. ed by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
  3. at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986)
  4. at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:843)
  5. at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)
  6. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
  7. ... 28 more

debug了一下,發(fā)現(xiàn)確實(shí)是Spring的一個bug。在DefaultListableBeanFactory的這個方法出問題了:

 
 
  1. protected Object doResolveDependency(DependencyDescriptor descriptor, Class type, String beanName,
  2.             Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
  3.         ...    
  4.         else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
  5.             Class keyType = descriptor.getMapKeyType();
  6.             if (keyType == null || !String.class.isAssignableFrom(keyType)) {
  7.                 if (descriptor.isRequired()) {
  8.                     throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
  9.                             "] must be assignable to [java.lang.String]");
  10.                 }
  11.                 return null;
  12.             }
  13.             Class valueType = descriptor.getMapValueType();
  14.             if (valueType == null) {
  15.                 if (descriptor.isRequired()) {
  16.                     throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
  17.                 }
  18.                 return null;
  19.             }
  20.             Map matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);
  21.             if (matchingBeans.isEmpty()) {
  22.                 if (descriptor.isRequired()) {
  23.                     raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
  24.                 }
  25.                 return null;
  26.             }
  27.             if (autowiredBeanNames != null) {
  28.                 autowiredBeanNames.addAll(matchingBeans.keySet());
  29.             }
  30.             return matchingBeans;
  31.         }
  32.         ...
  33.     }

關(guān)鍵在這一句:Map

 
 
  1. 嚴(yán)重: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@9476189] to prepare test instance [me.arganzheng.study.spring.autowired.AutowiredTest@2d546e21]
  2. ...
  3. Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=languageChangesMap)}
  4.     at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986)
  5.     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:843)
  6.     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)
  7.     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
  8.     ... 28 more

debug了一下,發(fā)現(xiàn)跟沒有指定qualifie name是一樣的執(zhí)行路徑。不是指定了bean name了嗎?為什么還是autowired by type呢?仔細(xì)查看了一下才發(fā)現(xiàn)。DefaultListableBeanFactory的doResolveDependency方法對首先對類型做 了區(qū)別:

 
 
  1. protected Object doResolveDependency(DependencyDescriptor descriptor, Class type, String beanName,
  2.             Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
  3.         Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
  4.         if (value != null) {
  5.             if (value instanceof String) {
  6.                 String strVal = resolveEmbeddedValue((String) value);
  7.                 BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
  8.                 value = evaluateBeanDefinitionString(strVal, bd);
  9.             }
  10.             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
  11.             return (descriptor.getField() != null ?
  12.                     converter.convertIfNecessary(value, type, descriptor.getField()) :
  13.                     converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
  14.         }
  15.         if (type.isArray()) {
  16.             Class componentType = type.getComponentType();
  17.             Map matchingBeans = findAutowireCandidates(beanName, componentType, descriptor);
  18.             if (matchingBeans.isEmpty()) {
  19.                 if (descriptor.isRequired()) {
  20.                     raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);
  21.                 }
  22.                 return null;
  23.             }
  24.             if (autowiredBeanNames != null) {
  25.                 autowiredBeanNames.addAll(matchingBeans.keySet());
  26.             }
  27.             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
  28.             return converter.convertIfNecessary(matchingBeans.values(), type);
  29.         }
  30.         else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
  31.             Class elementType = descriptor.getCollectionType();
  32.             if (elementType == null) {
  33.                 if (descriptor.isRequired()) {
  34.                     throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");
  35.                 }
  36.                 return null;
  37.             }
  38.             Map matchingBeans = findAutowireCandidates(beanName, elementType, descriptor);
  39.             if (matchingBeans.isEmpty()) {
  40.                 if (descriptor.isRequired()) {
  41.                     raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);
  42.                 }
  43.                 return null;
  44.             }
  45.             if (autowiredBeanNames != null) {
  46.                 autowiredBeanNames.addAll(matchingBeans.keySet());
  47.             }
  48.             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
  49.             return converter.convertIfNecessary(matchingBeans.values(), type);
  50.         }
  51.         else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
  52.             Class keyType = descriptor.getMapKeyType();
  53.             if (keyType == null || !String.class.isAssignableFrom(keyType)) {
  54.                 if (descriptor.isRequired()) {
  55.                     throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
  56.                             "] must be assignable to [java.lang.String]");
  57.                 }
  58.                 return null;
  59.             }
  60.             Class valueType = descriptor.getMapValueType();
  61.             if (valueType == null) {
  62.                 if (descriptor.isRequired()) {
  63.                     throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
  64.                 }
  65.                 return null;
  66.             }
  67.             Map matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);
  68.             if (matchingBeans.isEmpty()) {
  69.                 if (descriptor.isRequired()) {
  70.                     raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
  71.                 }
  72.                 return null;
  73.             }
  74.             if (autowiredBeanNames != null) {
  75.                 autowiredBeanNames.addAll(matchingBeans.keySet());
  76.             }
  77.             return matchingBeans;
  78.         }
  79.         else {
  80.             Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
  81.             if (matchingBeans.isEmpty()) {
  82.                 if (descriptor.isRequired()) {
  83.                     raiseNoSuchBeanDefinitionException(type, "", descriptor);
  84.                 }
  85.                 return null;
  86.             }
  87.             if (matchingBeans.size() > 1) {
  88.                 String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor);
  89.                 if (primaryBeanName == null) {
  90.                     throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
  91.                 }
  92.                 if (autowiredBeanNames != null) {
  93.                     autowiredBeanNames.add(primaryBeanName);
  94.                 }
  95.                 return matchingBeans.get(primaryBeanName);
  96.             }
  97.             // We have exactly one match.
  98.             Map.Entry entry = matchingBeans.entrySet().iterator().next();
  99.             if (autowiredBeanNames != null) {
  100.                 autowiredBeanNames.add(entry.getKey());
  101.             }
  102.             return entry.getValue();
  103.         }
  104.     }

如果是Array,Collection或者M(jìn)ap,則根據(jù)集合類中元素的類型來進(jìn)行autowired by type(Map使用value的類型)。為什么這么特殊處理呢?原來,Spring是為了達(dá)到這樣的目的:讓你可以一次注入所有符合類型的實(shí)現(xiàn),也就是 說可以這樣子注入:

 
 
  1. @Autowired
  2. private List cars;

如果你的car有多個實(shí)現(xiàn),那么都會注入進(jìn)來,不會再報

 
 
  1. org.springframework.beans.factory.NoSuchBeanDefinitionException:
  2. No unique bean of type [me.arganzheng.study.spring.autowired.Car] is defined:
  3. expected single matching bean but found 2: [audi, toyota].
  4. 然而,上面的情況如果你用@Resource則不會有這個問題:
  5. public class AutowiredTest extends BaseSpringTestCase {
  6.     @Resource
  7.     @Qualifier("languageChangesMap")
  8.     private Map languageChangesMap;
  9.     @Test
  10.     public void testAutowired() {
  11.         assertNotNull(languageChangesMap);
  12.         System.out.println(languageChangesMap.getClass().getSimpleName());
  13.         System.out.println(languageChangesMap);
  14.     }
  15. }

正常運(yùn)行:

 
 
  1. LinkedHashMap
  2. {pt=pt, br=pt, jp=ja, ja=ja, ind=ind, id=ind, en-rin=en-rIn, in=en-rIn, en=en, gb=en, th=th, ar=ar, eg=ar}

當(dāng)然,你如果不指定@Qualifier(“l(fā)anguageChangesMap”),同時field name不是languageChangesMap,那么還是一樣報錯的。

 
 
  1. Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)}
  2. at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986)
  3. at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:843)
  4. at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)
  5. at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:438)
  6. at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416)
  7. at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:550)
  8. at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
  9. at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
  10. at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
  11. ... 26 more

而且,@Resource也可以實(shí)現(xiàn)上面的List接收所有實(shí)現(xiàn):

 
 
  1. public class AutowiredTest extends BaseSpringTestCase {
  2.     @Resource
  3.     @Qualifier("languageChangesMap")
  4.     private Map languageChangesMap;
  5.     @Resource
  6.     private List cars;
  7.     @Test
  8.     public void testAutowired() {
  9.         assertNotNull(languageChangesMap);
  10.         System.out.println(languageChangesMap.getClass().getSimpleName());
  11.         System.out.println(languageChangesMap);
  12.         assertNotNull(cars);
  13.         System.out.println(cars.getClass().getSimpleName());
  14.         System.out.println(cars);
  15.     }
  16. }

運(yùn)行的妥妥的:

 
 
  1. LinkedHashMap
  2. {pt=pt, br=pt, jp=ja, ja=ja, ind=ind, id=ind, en-rin=en-rIn, in=en-rIn, en=en, gb=en, th=th, ar=ar, eg=ar}
  3. ArrayList
  4. [me.arganzheng.study.spring.autowired.Audi@579584da, me.arganzheng.study.spring.autowired.Toyota@19453122]

這是因?yàn)锧Resource注解使用的是CommonAnnotationBeanPostProcessor處理器,跟 AutowiredAnnotationBeanPostProcessor不是同一個作者[/偷笑]。這里就不分析了,感興趣的同學(xué)可以自己看代碼研究 一下。

最終結(jié)論如下:

1、@Autowired和@Inject

autowired by type 可以 通過@Qualifier 顯式指定 autowired by qualifier name(非集合類。注意:不是autowired by bean name?。?br /> 如果 autowired by type 失?。ㄕ也坏交蛘哒业蕉鄠€實(shí)現(xiàn)),則退化為autowired by field name(非集合類)

2、@Resource

默認(rèn) autowired by field name
如果 autowired by field name失敗,會退化為 autowired by type
可以 通過@Qualifier 顯式指定 autowired by qualifier name
如果 autowired by qualifier name失敗,會退化為 autowired by field name。但是這時候如果 autowired by field name失敗,就不會再退化為autowired by type了

測試工程保存在GitHub上,是標(biāo)準(zhǔn)的maven工程,感興趣的同學(xué)可以clone到本地運(yùn)行測試一下。

補(bǔ)充

有同事指出Spring官方文檔上有這么一句話跟我的結(jié)有點(diǎn)沖突:

However, although you can use this convention to refer to specific beans by name, @Autowired is fundamentally about type-driven injection with optional semantic qualifiers. This means that qualifier values, even with the bean name fallback, always have narrowing semantics within the set of type matches; they do not semantically express a reference to a unique bean id.

也就是說@Autowired即使加了@Qualifier注解,其實(shí)也是autowired by type。@Qualifier只是一個限定詞,過濾條件而已。重新跟進(jìn)了一下代碼,發(fā)現(xiàn)確實(shí)是這樣子的。Spring設(shè)計的這個 @Qualifier name 并不等同于 bean name。他有點(diǎn)類似于一個tag。不過如果這個tag是***的化,那么其實(shí)效果上等同于bean name。實(shí)現(xiàn)上,Spring是先getByType,得到list candicates,然后再根據(jù)qualifier name進(jìn)行過濾。

再定義一個蘭博基尼,這里使用@Qualifier指定:

 
 
  1. package me.arganzheng.study.spring.autowired;
  2. import org.springframework.beans.factory.annotation.Qualifier;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. @Qualifier("luxury")
  6. public class Lamborghini implements Car {
  7. }

再定義一個勞斯萊斯,這里故意用@Named指定:

 
 
  1. package me.arganzheng.study.spring.autowired;
  2. import javax.inject.Named;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. @Named("luxury")
  6. public class RollsRoyce implements Car {
  7. }

測試一下注入定義的豪華車:

 
 
  1. package me.arganzheng.study.spring.autowired;
  2. import static junit.framework.Assert.assertNotNull;
  3. import java.util.List;
  4. import me.arganzheng.study.BaseSpringTestCase;
  5. import org.junit.Test;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.beans.factory.annotation.Qualifier;
  8. /**
  9. *
  10. * @author zhengzhibin
  11. *
  12. */
  13. public class AutowiredTest extends BaseSpringTestCase {
  14.     @Autowired
  15.     @Qualifier("luxury")
  16.     private List luxuryCars;
  17.     @Test
  18.     public void testAutowired() {
  19. 當(dāng)前標(biāo)題:JavaSpring各種依賴注入注解的區(qū)別
    URL鏈接:http://m.5511xx.com/article/ccejcei.html