深入理解Spring原始碼之自動裝配
自動裝配;
Spring利用依賴注入(DI),完成對IOC容器中中各個元件的依賴關係賦值;
1)、@Autowired:自動注入:
1)、預設優先按照型別去容器中找對應的元件:applicationContext.getBean(BookDao.class);找到就賦值
2)、如果找到多個相同型別的元件,再將屬性的名稱作為元件的id去容器中查詢
applicationContext.getBean("bookDao")
3)、@Qualifier("bookDao"):使用@Qualifier指定需要裝配的元件的id,而不是使用屬性名
4)、自動裝配預設一定要將屬性賦值好,沒有就會報錯;
可以使用@Autowired(required=false);
5)、@Primary:讓Spring進行自動裝配的時候,預設使用首選的bean;
也可以繼續使用@Qualifier指定需要裝配的bean的名字
BookService{
@Autowired
BookDao bookDao;
}
2)、Spring還支援使用@Resource(JSR250)和@Inject(JSR330)[java規範的註解]
@Resource:
可以和@Autowired一樣實現自動裝配功能;預設是按照元件名稱進行裝配的;
沒有能支援@Primary功能沒有支援@Autowired(reqiured=false);
@Inject:
需要匯入javax.inject的包,和Autowired的功能一樣。沒有required=false的功能;
@Autowired:Spring定義的; @Resource、@Inject都是java規範
AutowiredAnnotationBeanPostProcessor:解析完成自動裝配功能;
3)、 @Autowired:構造器,引數,方法,屬性;都是從容器中獲取引數元件的值
1)、[標註在方法位置]:@Bean+方法引數;引數從容器中獲取;預設不寫@Autowired效果是一樣的;都能自動裝配
2)、[標在構造器上]:如果元件只有一個有參構造器,這個有參構造器的@Autowired可以省略,引數位置的元件還是可以自動從容器中獲取
3)、放在引數位置:
4)、自定義元件想要使用Spring容器底層的一些元件(ApplicationContext,BeanFactory,xxx);
自定義元件實現xxxAware;在建立物件的時候,會呼叫介面規定的方法注入相關元件;Aware;
把Spring底層一些元件注入到自定義的Bean中;
xxxAware:功能使用xxxProcessor;
ApplicationContextAware==》ApplicationContextAwareProcessor;
舉例檢視ApplicationContextAware的完整初始化過程:
public class IOCTest_Autowired {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(MainConifgOfAutowired.class);
}
}
package com.atguigu.bean; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanNameAware; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.stereotype.Component; import org.springframework.util.StringValueResolver; @Component public class AwareBean implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub System.out.println("傳入的ioc:"+applicationContext); this.applicationContext = applicationContext; } @Override public void setBeanName(String name) { // TODO Auto-generated method stub System.out.println("當前bean的名字:"+name); } @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { // TODO Auto-generated method stub String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}"); System.out.println("解析的字串:"+resolveStringValue); } }
斷點檢視呼叫棧如下:
-->AnnotationConfigApplicationContext refresh(); -->finishBeanFactoryInitialization(beanFactory); -->beanFactory.preInstantiateSingletons() -->DefaultListableBeanFactory getBean(beanName) -->AbstractBeanFactory doGetBean(name, null, null, false); -->AbstractBeanFactory getSingleton(beanName, new ObjectFactory<Object>() --> DefaultSingletonBeanRegistry singletonFactory.getObject() -->AbstractBeanFactory createBean(beanName, mbd, args) -->AbstractAutowireCapableBeanFactory doCreateBean(beanName, mbdToUse, args) -->AbstractAutowireCapableBeanFactory initializeBean(beanName, exposedObject, mbd) -->AbstractAutowireCapableBeanFactory applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) -->AbstractAutowireCapableBeanFactory beanProcessor.postProcessBeforeInitialization(result, beanName); -->ApplicationContextAwareProcessor invokeAwareInterfaces(bean); -->ApplicationContextAwareProcessor ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); -->AwareBean setApplicationContext
開啟ApplicationContextAwareProcessor的原始碼發現它實現了BeanPostProcessor前置類在postProcessBeforeInitialization方法裡呼叫invokeAwareInterfaces最後一步時設定spring容器
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
相關推薦
深入理解Spring原始碼之自動裝配
自動裝配; Spring利用依賴注入(DI),完成對IOC容器中中各個元件的依賴關係賦值; 1)、@Autowired:自動注入: 1)、預設優先按照型別去容器中找對應的元件:applicationContext.getBean(Bo
深入理解Spring原始碼之bean的生命週期控制器BeanPostProcessor
spring是藉助ioc容器進行bean的初始化的,ioc的概念如下: bean的生命週期: bean建立---初始化----銷燬的過程 容器管理bean的生命週期; 我們可以自定義初始化和銷燬方法;容器在bean進行到當前生命週期
Spring原始碼之自動裝配
引言 我們使用Spring開發過程中經常會用到Autowired註解注入依賴的bean,這部分也是面試的熱點問題之一。今天咱們一起來深入研究下自動注入的背後實現原理。首先上一個例子,如下所示: @RestController public class TestController { @Autowi
spring boot 系列之六:深入理解spring boot的自動配置
我們知道,spring boot自動配置功能可以根據不同情況來決定spring配置應該用哪個,不應該用哪個,舉個例子: Spring的JdbcTemplate是不是在Classpath裡面?如果是,並且DataSource也存在,就自動配置一個JdbcTemplate的Bean Thymeleaf是不
深入理解Spring AOP之二代理對象生成
gets code 網上 none work class als post 產生 深入理解Spring AOP之二代理對象生成 spring代理對象 上一篇博客中講到了Spring的一些基本概念和初步講了實現方
手把手教你深入理解Spring原始碼-spring開篇(中)
授人以魚不如授人以漁,《手把手教你深入理解Spring原始碼》專欄教你如何學習、思考、閱讀Spring框架,並應對其它開源框架不再畏懼。 接著上篇的文章講,上篇的文章講述了什麼是IOC,這篇講述什麼又是AOP? 一樣的在看這篇文章之前,大家不妨先花點時間思考一下。 1、AOP的設計原理
深入理解spring註解之@ComponentScan註解
原創 深入理解spring註解之@ComponentScan註解 知了123 0人評論 149062人閱讀 2018-05-20 10:02:23
深入理解spring註解之@Bean註解
本文主要從以下幾個方面來學習一下spring的註解@Bean: 基於xml方式bean使用回顧 註解@Bean詳細使用說明 註解@Bean的原始碼解析 1,基於xml方式bean使用回顧 新建一個maven專案增加spring-con
spring boot 之自動裝配
前言 在最初接觸spring 的時候,還是使用xml進行裝配,我記得很清楚,當時分別配置了spring-dao.xml , spring-service.xml , spring-controller.xml。然後把所有需要用到的掃包,注入bean,以及配置,全都一股腦的塞進xml中,雖然出發點很好,不用在
深入理解Spring系列之八:常用的擴充套件介面
Spring不僅提供了一個進行快速開發的基礎框架,而且還提供了很多可擴充套件的介面,用於滿足一些額外的開發需求,本篇將對常用的可擴充套件介面進行歸納總結。 1.InitializingBean介面 InitializingBean介面中只有一個afterPr
深入理解Spring系列之十二:@Transactional是如何工作的
結合Spring框架,在進行資料庫操作的時候,經常使用@Transactional註解,工作經歷中看到很多開發者使用方式都是錯誤的,沒有深入理解過其原理,這是很危險的!!本篇將深入Spring原始碼,分析@Transactional註解的工作原理。相信,看完你會
從簡單開始深入理解Spring 原始碼
知識點:A類實現B介面,那麼A類的所有子類 都可轉型為B,並且具有A類父類的所有型別。 程式碼如下: 此類為A子類: public class F extends A{ } public class A extends C implements B{ } p
Spring框架之自動裝配
Spring的IoC容器通過Java反射機制瞭解了容器中所存在Bean的配置資訊,這包括構造方法的結構,屬性的資訊,而正是由於這個原因,Spring容器才能通過某種規則來對Bean進行自動裝配,而無須通過顯式的方法進行配置。 一.自動裝配型別:Spring
spring註解之自動裝配和屬性賦值
${} throws 定義類 on() wired 成對 功能 inter setter 1.自動裝配 1.1什麽是自動裝配? Spring利用依賴註入(DI),完成對IOC容器中各個組件的依賴關系賦值; [email protected]/@Quali
Dubbo(三):深入理解Dubbo原始碼之如何將服務釋出到註冊中心
一、前言 前面有說到Dubbo的服務發現機制,也就是SPI,那既然Dubbo內部實現了更加強大的服務發現機制,現在我們就來一起看看Dubbo在發現服務後需要做什麼才能將服務註冊到註冊中心中。 二、Dubbo服務註冊簡介 首先需要明白的是Dubbo是依賴於Spring容器的(至於為什麼在上篇部落格中有介
Java程式設計師從笨鳥到菜鳥之(八十二)細談Spring(十一)深入理解spring+struts2整合(附原始碼)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Spring原始碼解讀之——自動裝配(隨筆)
Spring利用依賴注入(DI),完成對IOC容器中中各個元件的依賴關係賦值; 1、@Autowired:自動注入: 1)、預設優先按照型別去容器中找對應的元件:applicationContext.getBean(BookDao.class);找到就賦值
深入理解SpringBoot之自動裝配
SpringBoot的自動裝配是拆箱即用的基礎,也是微服務化的前提。其實它並不那麼神祕,我在這之前已經寫過最基本的實現了,大家可以參考這篇文章。這次主要的議題是,來看看它是怎麼樣實現的,我們透過原始碼來把握自動裝配的來龍去脈。 一、自動裝配過程分析 1.1、關於@SpringBootApplicati
深入理解Spring cloud原始碼篇之Eureka原始碼
1.eureka功能分析 首先,eureka在springcloud中充當服務註冊功能,相當於dubbo+zk裡面得zk,但是比zk要簡單得多,zk可以做得東西太多了,包括分散式鎖,分散式佇列都是基於zk裡面得四種節點加watch機制通過長連線來
【死磕 Spring】----- IOC 之深入理解 Spring IoC
在一開始學習 Spring 的時候,我們就接觸 IoC 了,作為 Spring 第一個最核心的概念,我們在解讀它原始碼之前一定需要對其有深入的認識,本篇為【死磕 Spring】系列部落格的第一篇博文,主要介紹 IoC 基本概念和各個元件。 IOC 理論 Io