
點關(guān)注,不迷路;持續(xù)更新Java架構(gòu)相關(guān)技術(shù)及資訊熱文?。?!
一、spring依賴注入使用方式
@Autowired是spring框架提供的實現(xiàn)依賴注入的注解,主要支持在set方法,field,構(gòu)造函數(shù)中完成bean注入,注入方式為通過類型查找bean,即byType的,如果存在多個同一類型的bean,則使用@Qualifier來指定注入哪個beanName的bean。
與JDK的@Resource的區(qū)別:@Resource是基于bean的名字,即beanName,來從spring的IOC容器查找bean注入的,而@Autowried是基于類型byType來查找bean注入的。
與JDK的@Inject的區(qū)別:@Inject也是基于類型來查找bean注入的,如果需要指定名稱beanName,則可以結(jié)合使用@Named注解,而@Autowired是結(jié)合@Qualifier注解來指定名稱beanName。
二、spring依賴注入注解的實現(xiàn)原理
注解處理器
在spring框架內(nèi)部實現(xiàn)當(dāng)中,注解實現(xiàn)注入主要是通過bean后置處理器BeanPostProcessor接口的實現(xiàn)類來生效的。BeanPostProcessor后置處理器是在spring容器啟動時,創(chuàng)建bean對象實例后,馬上執(zhí)行的,對bean對象實例進(jìn)行加工處理。
@Autowired是通過BeanPostProcessor接口的實現(xiàn)類AutowiredAnnotationBeanPostProcessor來實現(xiàn)對bean對象對其他bean對象的依賴注入的;
@Resource和@Inject是通過BeanPostProcessor接口的實現(xiàn)類CommonAnnotationBeanPostProcessor來實現(xiàn)的,其中如名字所述,即公共注解CommonAnotation,CommonAnnotationBeanPostProcessor是spring中統(tǒng)一處理JDK中定義的注解的一個BeanPostProcessor。該類會處理的注解還包括@PostConstruct,@PreDestroy等。
注解處理器的激活條件
- AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor添加到spring容器的BeanPostProcessor的條件,即激活這些處理器的條件如下:
1.基于xml的spring配置
在對應(yīng)的spring容器的配置xml文件中,如applicationContext.xml,添加<context:annotation-config />和<context:component-scan />,或者只使用<context:component-scan />。
兩者的區(qū)別是<context:annotation-config />只查找并激活已經(jīng)存在的bean,如通過xml文件的bean標(biāo)簽生成加載到spring容器的,而不會去掃描如@Controller等注解的bean,查找到之后進(jìn)行注入;而<context:component-scan />除了具有<context:annotation-config />的功能之外,還會去加載通過basePackages屬性指定的包下面的,默認(rèn)為掃描@Controller,@Service,@Component,@Repository注解的類。不指定basePackages則是類路徑下面,或者如果使用注解@ComponentScan方式,則是當(dāng)前類所在包及其子包下面。
2.基于配置類的spring配置
如果是基于配置類而不是基于applicationContext.xml來對spring進(jìn)行配置,如SpringBoot,則在內(nèi)部使用的IOC容器實現(xiàn)為AnnotationConfigApplicationContext或者其派生類,在AnnotationConfigApplicationContext內(nèi)部會自動創(chuàng)建和激活以上的BeanPostProcessor。
如果同時存在基于xml的配置和配置類的配置,而在注入時間方面,基于注解的注入先于基于XML的注入,所以基于XML的注入會覆蓋基于注解的注入。
總結(jié)
@Autowired是Spring自帶的,@Inject和@Resource都是JDK提供的,其中@Inject是JSR330規(guī)范實現(xiàn)的,@Resource是JSR250規(guī)范實現(xiàn)的,而Spring通過BeanPostProcessor來提供對JDK規(guī)范的支持。
@Autowired、@Inject用法基本一樣,不同之處為@Autowired有一個required屬性,表示該注入是否是必須的,即如果為必須的,則如果找不到對應(yīng)的bean,就無法注入,無法創(chuàng)建當(dāng)前bean。
@Autowired、@Inject是默認(rèn)按照類型匹配的,@Resource是按照名稱匹配的。如在spring-boot-data項目中自動生成的redisTemplate的bean,是需要通過byName來注入的。如果需要注入該默認(rèn)的,則需要使用@Resource來注入,而不是@Autowired。
對于@Autowire和@Inject,如果同一類型存在多個bean實例,則需要指定注入的beanName。@Autowired和@Qualifier一起使用,@Inject和@Name一起使用。
