1. 程式人生 > >深入理解Spring原始碼之自動裝配

深入理解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