Spring依賴注入:@Autowired,@Resource和@Inject區別與實現原理

點關注,不迷路;持續更新Java架構相關技術及資訊熱文!!!

1、spring依賴注入使用方式

  • @Autowired是spring框架提供的實現依賴注入的註解,主要支持在set方法,field,構造函數中完成bean注入,注入方式爲經過類型查找bean,即byType的,若是存在多個同一類型的bean,則使用@Qualifier來指定注入哪一個beanName的bean。
  • 與JDK的@Resource的區別:@Resource是基於bean的名字,即beanName,來從spring的IOC容器查找bean注入的,而@Autowried是基於類型byType來查找bean注入的。
  • 與JDK的@Inject的區別:@Inject也是基於類型來查找bean注入的,若是須要指定名稱beanName,則能夠結合使用@Named註解,而@Autowired是結合@Qualifier註解來指定名稱beanName。

2、spring依賴注入註解的實現原理

註解處理器

  • 在spring框架內部實現當中,註解實現注入主要是經過bean後置處理器BeanPostProcessor接口的實現類來生效的。BeanPostProcessor後置處理器是在spring容器啓動時,建立bean對象實例後,立刻執行的,對bean對象實例進行加工處理。
  • @Autowired是經過BeanPostProcessor接口的實現類AutowiredAnnotationBeanPostProcessor來實現對bean對象對其餘bean對象的依賴注入的;
  • @Resource和@Inject是經過BeanPostProcessor接口的實現類CommonAnnotationBeanPostProcessor來實現的,其中如名字所述,即公共註解CommonAnotation,CommonAnnotationBeanPostProcessor是spring中統一處理JDK中定義的註解的一個BeanPostProcessor。該類會處理的註解還包括@PostConstruct,@PreDestroy等。

註解處理器的激活條件

  • AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor添加到spring容器的BeanPostProcessor的條件,即激活這些處理器的條件以下:

1.基於xml的spring配置redis

  • 在對應的spring容器的配置xml文件中,如applicationContext.xml,添加<context:annotation-config />和<context:component-scan />,或者只使用<context:component-scan />。
  • 二者的區別是<context:annotation-config />只查找並激活已經存在的bean,如經過xml文件的bean標籤生成加載到spring容器的,而不會去掃描如@Controller等註解的bean,查找到以後進行注入;而<context:component-scan />除了具備<context:annotation-config />的功能以外,還會去加載經過basePackages屬性指定的包下面的,默認爲掃描@Controller,@Service,@Component,@Repository註解的類。不指定basePackages則是類路徑下面,或者若是使用註解@ComponentScan方式,則是當前類所在包及其子包下面。

2.基於配置類的spring配置spring

  • 若是是基於配置類而不是基於applicationContext.xml來對spring進行配置,如SpringBoot,則在內部使用的IOC容器實現爲AnnotationConfigApplicationContext或者其派生類,在AnnotationConfigApplicationContext內部會自動建立和激活以上的BeanPostProcessor。
  • 若是同時存在基於xml的配置和配置類的配置,而在注入時間方面,基於註解的注入先於基於XML的注入,因此基於XML的注入會覆蓋基於註解的注入。

總結

  1. @Autowired是Spring自帶的,@Inject和@Resource都是JDK提供的,其中@Inject是JSR330規範實現的,@Resource是JSR250規範實現的,而Spring經過BeanPostProcessor來提供對JDK規範的支持。
  2. @Autowired、@Inject用法基本同樣,不一樣之處爲@Autowired有一個required屬性,表示該注入是不是必須的,即若是爲必須的,則若是找不到對應的bean,就沒法注入,沒法建立當前bean。
  3. @Autowired、@Inject是默認按照類型匹配的,@Resource是按照名稱匹配的。如在spring-boot-data項目中自動生成的redisTemplate的bean,是須要經過byName來注入的。若是須要注入該默認的,則須要使用@Resource來注入,而不是@Autowired。
  4. 對於@Autowire和@Inject,若是同一類型存在多個bean實例,則須要指定注入的beanName。@Autowired和@Qualifier一塊兒使用,@Inject和@Name一塊兒使用。

寫在最後

最後,歡迎作Java的工程師朋友們加入Java高級架構進階Qqun:963944895sql

羣內有技術大咖指點難題,還提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)架構

比你優秀的對手在學習,你的仇人在磨刀,你的閨蜜在減肥,隔壁老王在練腰, 咱們必須不斷學習,不然咱們將被學習者超越!併發

趁年輕,使勁拼,給將來的本身一個交代!app

相關文章
相關標籤/搜索