天天看點

源碼解析:Spring源碼解析筆記(一)基本概念

本文由colodoo(紙傘)整理

QQ 425343603

Java學習交流群(717726984)

參考 https://www.bilibili.com/video/BV1dK4y127mH 1-10章節

BeanDefinition

BeanDefinition表示Bean定義,Spring根據BeanDefinition來建立Bean對象,BeanDefinition有很多的屬性用來描述Bean,BeanDefinition是Spring中非常核心的概念。

@Component、@Bean、都會被解析成BeanDefinition。

配置屬性包含

  • beanClass
  • scope
  • isLazy
  • dependsOn
  • primary
  • initMethodName

beanClass

表示一個bean的類型,比如UserService.class、OrderService.class,Spring在建立Bean 的過程中會根據此屬性來執行個體化得到對象。

scope

表示一個bean的作用域,比如:

scope等于singleton,該bean就是一個單例Bean;

scope等于prototype,該bean就是一個原型bean。

isLazy

表示一個bena是不是需要懶加載,原型bean的isLazy屬性不起作用,懶加載的單例bean,會在第一次getBean的時候生成該bean,非懶加載的單例bean,則會在Spring啟動過程中直接生成好。

dependsOn

表示一個bean在建立之前所依賴的其他bean,在一個bean建立之前,它錯依賴的這些bean得先全部建立好。

primary

表示一個bean是主bean,在Spring中一個類型可以有多個bean對象,在進行依賴注入時,如果根據類型找到了多個bean,此時會判斷這些bean中是否存在一個主bean,如果存在,則直接将這個bean注入給屬性。

initMethodName

表示一個bean得初始化方法,一個bean的生命周去過程中有一個步驟叫初始化,Spring會在這個步驟中取調用bean的初始化方法,初始化邏輯由程式員自己控制,表示程式員可以自定義邏輯對bean進行加工。

BeanFactory

BeanFactory是一種“Spring容器”,BeanFactory翻譯過來就是Bean工廠;它可以用來建立Bean、擷取Bean,BeanFactory是Spring中非常核心的元件。

BeanDefintion、BeanFactory、Bean 關系

BeanFactory将利用BeanDefinition來生成Bean對象,BeanDefinition相當于BeanFactory的原材料,Bean對象就相當于BeanFactory所生産出來的産品。

BeanFactory利用BeanDefinition産出Bean對象。

核心子接口和實作類

  • ListableBeanFactory
  • ConfigurableBeanFactory
  • AuwowireCapableBeanFactory
  • AbstractBeanFactory
  • DefaultListableBeanFactory

DefaultListableBeanFactory

支援單例Bean、支援Bean别名、支援父子BeanFactory、支援Bean類型轉化、支援Bean後置處理、支援FactoryBean、支援自動裝配,等等。

Bean生命周期

生命周期的幾個階段:

  • BeanDefinition -> Bean定義
  • 構造方法推斷 -> 選出構造方法
  • 執行個體化 -> 構造方法反射執行個體化對象
  • 屬性填充 -> 自動填充屬性
  • 初始化 -> 對其他屬性指派、校驗
  • 初始化後 -> AOP、生成代理對象

BeanDefinition

BeanDefinition表示Bean定義,它定義了某個Bean的類型,Spring就是利用BeanDefinition來建立Bean的,比如需要利用BeanDefinition中beanClass屬性确定Bean的類型,進而執行個體化出來對象。

構造方法推斷

一個Bean中可以有多個構造方法,此時就需要Spring來判斷到底使用哪個構造方法,這個過程是比較複雜的,篇幅有限,不展開介紹。通過構造方法推斷之後确定一個構造方法後,就可以利用構造方法執行個體化得到一個對象了。

執行個體化

通過構造方法反射得到一個執行個體化對象,在Spring中,可以通過BeanPostProcessor機制對執行個體化進行幹預。

屬性填充

執行個體化所得到的對象,是“不完整”的對象,“不完整”的意思是該對象中的某些屬性還沒有進行屬性填充,也就是Spring還沒有自動給某些屬性指派,屬性填充就是我們通常說的自動注入、依賴注入。

初始化

在一個對象的屬性填充之後,Spring提供了初始化機制,程式員可以利用初始化機制對Bean進行自定義加工,比如可以利用InitializingBean接口來對Bean中的其他屬性進行指派,或對Bean中的某些屬性進行校驗。

@Autowired

@Autowired表示某個屬性是否需要進行依賴注入,可以寫在屬性和方法上。注解中的required屬性預設為true,表示如果沒有對象可以注入給屬性則抛異常。

@Service
public class OrderService {
    
    @Autowired
    private UserService userService;
    
}
           

@Autowired加在某個屬性上,Spring在進行Bean的生命周期過程中,在屬性填充這一步,會基于執行個體化出來的對象,對該對象中加了@Autowired的屬性自動給屬性指派。

Tip:操作步驟是在屬性填充這一步。

構造方法

@Autowired加在構造方法上時,Spring會在推斷構造方法階段,選擇該構造方法來進行執行個體化,在反射調用構造方法之前,會先根據構造方法參數類型、參數名從Spring容器中找到Bean對象,當作構造方法入參。

@Resource

@resource如果name屬性有值,那麼Spring會直接根據所指定的name值取Spring容器找Bean對象,如果找到了則成功,沒有找到則報錯。

@Value

@Value注解和@Resource、@Autowired類似,也是用來對屬性進行依賴注入的,隻不過@Value是用來從Properties檔案中擷取值的,并且@Value可以解析SpEL(Spring表達式)。

FactoryBean

FactoryBean是Spring所提供的一種較靈活的建立Bean的方式,可以通過實作FactoryBean接口中的getObject()方法來傳回一個對象,這個對象就是最終的Bean對象。

接口方法:

  • Object getObject():傳回的是Bean對象
  • boolean isSingleton():傳回的是否是單例Bean對象
  • Class getObjectType():傳回的是Bean對象的類型

代碼:

@Component( "demo")
public class DemoFactoryBean implements FactoryBean {
    
	@Override
    public 0bject get0bject() throws Exception {
    	return new Demo();
    }
    @Override
    public class<?> get0bjectType() {
    	return Demo.class;
    }
	@Override
	//所定義的Bean是單例還是原型
	public boolean issingleton() {
		return true;
	}
}
           

FactoryBean機制被廣泛的應用在Spring内部和Spring與第三方架構或元件的整合過程中。

FactoryBean和BeanFactory

FactoryBean

FactoryBean對象本身也是一個Bean,同僚它相當于一個小型工廠,可以生産出另外的Bean。

BeanFactory

BeanFactory是一個Spring容器,是一個大型工廠,它可以生産出各種各樣的Bean。

ApplicationContext

ApplicationContext是比BeanFactory更加強大的Spring容器,它既可以建立bean、擷取bean,還支援國際化、事件廣播、擷取資源等BeanFactory不具備的功能。

繼承接口

  • EnvironmentCapable
  • ListableBeanFactory
  • HierarchicalBeanFactory
  • MessageSource
  • ApplicationEventPublisher

BeanPostProcessor

BeanPostProcessor在Spring中是一個接口,我們定義一個後置執行器,就是提供一個類實作該接口,在Spring中還存在一些接口繼承了BeanPostProcessor,這些接子接口是在BeanPostProcessor的基礎上增加了一些其他的功能。

BeanPostProcessor中的方法

postProcessBeforelnitialization():初始化前方法,表示可以利用這個方法來對Bean在初始化前進行自定義加工。

postProcessAfterlnitialization):初始化後方法,表示可以利用這個方法來對Bean在初始化後進行自定義加工。

InstantiationAwareBeanPostProcessor

BeanPostProcessor的一個子接口,

postProcessBeforelnstantiation():執行個體化前

postProcessAfterlnstantiation():執行個體化後postProcessProperties():屬性注入後

AOP

Aop就是面向切面程式設計,是一種非常适合在無需修改業務代碼的前提下,對某個或某些業務增加統一的功能,比如日志記錄、權限重置、事務管理等,能很好的使得代碼解耦,提高開發效率。

  • Advice
  • Pointcut
  • Advisor
  • Weaving
  • Target
  • Join Point

Advice

Advice可以了解為通知、建議,在Spring中通過定義Advice來定義代理邏輯。

Pointcut

Pointcut是切點,表示Advice對應的代理邏輯應用在哪個類、哪個方法上。

Advisor

Advisr等于Advice+Pointcut,表示代理邏輯和切點的一個整體,程式員可以通過定義或封裝一個Advisor,來定義切點和代理邏輯。

Weaving

Weaving表示織入,将Advicedialing邏輯在源代碼級别嵌入到切面得過程,就叫做織入。

Target

Target表示目标對象,也就是被代理對象,在AOP生成的代理對象中對持有目标對象。

Join Point

Join Point表示連接配接點,在Spring AOP中,就是方法的執行點。

AOP工作原理

AOP是發生在Bean的生命周期過程中的;

  • Spring生成bean對象時,先執行個體化出來一個對象,也就是target對象。
  • 再對target對象進行屬性填充。
  • 在初始化步驟中,會判斷target對象有沒有對應的切面。
  • 如果有切面,就表示目前target對象需要進行AOP。
  • 通過Cglib或JDK動态代理機制生成一個代理對象,作為最終的bean對象。
  • 代理對象中有一個target屬性隻想了target對象。