亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

大綱

  • 容器的基本用法
  • spring啟動過程分析(spring生命周期)
  • bean 的生命周期
  • IOC核心類總結(jié)
  • 常用擴展點

容器的基本用法

spring 是企業(yè)級開發(fā)框架, 主要功能有 IOC,AOP,Web,ORM等

spring IOC專門用于管理bean對象, 管理對象的創(chuàng)建,屬性注入等

spring AOP 給予動態(tài)代理,實現(xiàn)了切面編程,動態(tài)實現(xiàn)對象功能擴展

 

spring 與其他框架整合,通過 spring 提供的擴展點,把其他框架的對象交給 spring 管理, 對象交給 spring 管理是想要避免手動創(chuàng)建對象,也可以通過@Autowired 等注解實現(xiàn)屬性注入,讓我們使用對象起來更加方便

  • spring xml 方式配置示例
//1 xml 方式配置spring  bean<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans        https://www.springframework.org/schema/beans/spring-beans.xsd">    <!-- 配置spring  bean -->    <bean id="petStore" class="cn.JAVAbus.PetStoreService.class">   </bean></beans>//2  初始化 IOC容器ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");PetStoreService service = context.getBean("petStore", PetStoreService.class);

spring啟動過程分析(spring生命周期)

spring生命周期與bean生命周期

  • spring啟動過程描述

1 BeanDefinition 解析注冊

->多種配置方式配置Bean(xml,注解Component,java config)

->各種配置抽象為Resource資源

->通過BeanDefinitionReader 解析BeanDefinition 注冊到 BeanDefinitionRegistry

 

2 PostProcessor 各種處理器注冊調(diào)用

->獲取BeanFactory

->注冊和調(diào)用BeanFactoryPostProcessor(bean工廠后置處理器)

->注冊BeanFactoryPostProcessors

 

3 bean 生命周期處理

->實例化對象

->依賴注入

->bean 初始化

-> 存放到SpringContext容器

  • 以AbstractApplicationContext中的refresh()方法為起點進行源碼分析
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {  this(); //創(chuàng)建BeanDefinitionReader,BeanDefinitionScanner對象  //BeanDefinition解析和注冊 (DefaultListableBeanFactory.beanDefinitionMap)  register(componentClasses);  refresh();}public void refresh() throws BeansException, IllegalStateException {  synchronized(this.startupShutdownMonitor) {    StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");    //記錄容器開始時間startupDate,設(shè)置活躍狀態(tài)為true,設(shè)置environment對象    this.prepareRefresh();    //1 創(chuàng)建beanFactory實例對象, 一般是DefaultListableBeanFactory    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();    // Prepare the bean factory for use in this context.    prepareBeanFactory(beanFactory);    try {      // 空實現(xiàn)留給子類擴展 Allows post-processing of the bean factory in context subclasses.      postProcessBeanFactory(beanFactory);      StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");      // Invoke factory processors registered as beans in the context.      //2 按照順序注冊BeanFactoryPostProcessors,并且按照順序調(diào)用      invokeBeanFactoryPostProcessors(beanFactory);      // Register bean processors that intercept bean creation.      //3  按照順序注冊BeanPostProcessors      registerBeanPostProcessors(beanFactory);      beanPostProcess.end();      // 注冊國際化相關(guān)內(nèi)容 Initialize message source for this context.      initMessageSource();      // 初始化事件廣播 Initialize event multicaster for this context.      initApplicationEventMulticaster();      // 空實現(xiàn)留給子類擴展 Initialize other special beans in specific context subclasses.      onRefresh();      // 注冊監(jiān)聽器并且廣播早期事件 Check for listener beans and register them.      registerListeners();      // Instantiate all remaining (non-lazy-init) singletons.      //4 調(diào)用getBean()方法對非延遲加載的bean進行實例化 (最重要,涉及bean生命周期)      finishBeanFactoryInitialization(beanFactory);      // Last step: publish corresponding event.      finishRefresh();    }  }}

spring bean的生命周期

Spring中每個Bean的生命周期如下:

圖片來源于網(wǎng)絡(luò)

  • spring bean 生命周期 (Bean 解析和注冊)

實例化 -> 屬性賦值 -> 初始化 -> 銷毀

實例化 Instantiation

屬性賦值 Populate

初始化 Initialization

銷毀 Destruction

 

class

->構(gòu)造器->反射創(chuàng)建對象

-> 依賴注入(@Autowired)

-> 初始化前(@PostConstruct)->初始化(InitializingBean)->初始化后(AOP)

-> 代理對象->bean

  • spring bean生命周期代碼入口 finishBeanFactoryInitialization(beanFactory)
//真正邏輯在 AbstractAutowireCapableBeanFactory.doCreateBean()finishBeanFactoryInitialization()DefaultListableBeanFactory#preInstantiateSingletons()getBean(beanName)AbstractBeanFactory.doGetBean()AbstractAutowireCapableBeanFactory#createBean()//1 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //2 對象實例化 AbstractAutowireCapableBeanFactory.doCreateBean() Object beanInstance = doCreateBean(beanName, mbdToUse, args);BeanWrapper instanceWrapper = null;//doCreateBean-1 通過反射創(chuàng)建對象實例 (調(diào)用構(gòu)造器創(chuàng)建對象)instanceWrapper = createBeanInstance(beanName, mbd, args);//doCreateBean-2 給后置BDpost-processors 一個修改 BeanDefinition的機會applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);    //doCreateBean-3 通過提前暴露一個單例工廠方法,從而使得其他 bean 能夠引用到該 bean (解決單例 bean循環(huán)依賴)addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//doCreateBean-4 DI 依賴注入 (對象屬性初始化,各個屬性值注入,其中可能注入其他 bean 的屬性,這時候會遞歸初始化依賴 bean)populateBean(beanName, mbd, instanceWrapper);//doCreateBean-5 調(diào)用初始化方法,比如 init-methodexposedObject = initializeBean(beanName, exposedObject, mbd);//initializeBean-1 調(diào)用 Aware接口實現(xiàn)類invokeAwareMethods(beanName, bean);//initializeBean-2 bean前置處理 beanProcessor.postProcessBeforeInitialization();wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//initializeBean-3 調(diào)用初始化方法((InitializingBean) bean).afterPropertiesSet();invokeInitMethods(beanName, wrappedBean, mbd);//initializeBean-4 bean后置處理 beanProcessor.postProcessAfterInitialization()wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);return exposedObject;//3return beanInstance;  //然后回到AbstractBeanFactory.doGetBean(),執(zhí)行g(shù)etSingleton(),注冊 bean到容器sharedInstance = getSingleton(beanName, () -> {//todo  2.2 創(chuàng)建 單實例bean (ctrl+T)return createBean(beanName, mbd, args);}     
  • spring bean 生命周期核心代碼邏輯
// AbstractBeanFactory.doGetBean()protected <T> T doGetBean(final String name, ...) {  // 1 提取對應(yīng)的 beanName (傳入的 name 可能是別名,FactoryBean(name="&aa"))  final String beanName = transformedBeanName(name);  Object bean;  // 2 嘗試直接從緩存獲取,或者singletonFactories 中的 objectFactory中獲取  Object sharedInstance = getSingleton(beanName);  if (sharedInstance != null && args == null) {    //該條件一般為二次獲取 bean 才會進入  }else {    //lambda 方式調(diào)用 DefaultSingletonBeanRegistry.getSingleton(beanName, ObjectFactory<?>)    //獲取createBean()創(chuàng)建的bean對象后,走getSingleton()邏輯添加bean 到bean容器(DefaultSingletonBeanRegistry.singletonObjects    sharedInstance = getSingleton(beanName, () -> {      //todo  2.2 調(diào)用createBean()方法創(chuàng)建對象      return createBean(beanName, mbd, args);    }    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  }}//...return (T) bean;}  //AbstractAutowireCapableBeanFactory.doCreateBean()//spring bean 生命周期核心代碼邏輯 (bean 實例化,依賴注入,以及初始化)protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args){  // Instantiate the bean. (裝飾模式)  BeanWrapper instanceWrapper = null;  if (instanceWrapper == null) {    //todo 1 根據(jù)指定的 bean 使用對應(yīng)的策略來創(chuàng)建 bean,如:工廠方法,構(gòu)造函數(shù)注入,簡單初始化    instanceWrapper = createBeanInstance(beanName, mbd, args);  }  // Initialize the bean instance.  try {    //todo 2 DI 依賴注入 (對象屬性初始化,各個屬性值注入,其中可能注入其他 bean 的屬性,這時候會遞歸初始化依賴 bean)    populateBean(beanName, mbd, instanceWrapper);    //todo 3 調(diào)用初始化方法,比如 init-method    exposedObject = initializeBean(beanName, exposedObject, mbd);  }  // ...Register bean as disposable.   return exposedObject;} 

Bean生命周期-常用擴展點

  • 第一大類:容器級生命周期接口方法(影響多個Bean的接口)

容器級生命周期接口方法:包含了
InstantiationAwareBeanPostProcessor和BeanProcessor這兩個接口實現(xiàn),稱他們的實現(xiàn)類為“后處理器”。

實現(xiàn)了這些接口的Bean會切入到多個Bean的生命周期中。因此,這些接口的功能非常強大,Spring內(nèi)部擴展也經(jīng)常使用這些接口,例如自動注入以及AOP的實現(xiàn)都和他們有關(guān)。

 

1 BeanPostProcessor 作用于初始化階段的前后

2
InstantiationAwareBeanPostProcessor 作用于實例化階段的前后,

 

這兩兄弟可能是Spring擴展中最重要的兩個接口!

工廠后處理器接口方法:包含了AspectJWeavingEnabler、
ConfigurationClassPostProcessor、CustomAutowreConfigure等非常有用的工廠后處理器接口的方法,會在應(yīng)用上下文裝配配置文件后立即調(diào)用。

  • 第二大類:Bean級別生命周期接口方法(每個 bean調(diào)用一次的接口)

1 Aware類型的接口

2 Bean生命周期接口 包含了BeanNameAware、BeanFactoryAware、initialzingBean和DiposableBean這些接口的方法

3 Bean的自身方法: 這個包括了init-method和destory-method方法

 

Aware類型的接口的作用就是讓我們能夠拿到Spring容器中的一些資源。

基本都能夠見名知意,Aware之前的名字就是可以拿到什么資源,例如BeanNameAware可以拿到BeanName,以此類推。

調(diào)用時機需要注意:所有的Aware方法都是在初始化階段之前調(diào)用的!

  • 各個接口調(diào)用時機演示
//1 BeanFactoryPostProcessor 工廠后處理器接口@Componentpublic class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {  public CustomBeanFactoryPostProcessor() {    System.out.println("==[BeanFactoryPostProcessor 接口]調(diào)用了 CustomBeanFactoryPostProcessor 構(gòu)造器");  }  @Override  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {    System.out.println("==[BeanFactoryPostProcessor 接口]調(diào)用了 CustomBeanFactoryPostProcessor.postProcessBeanFactory() 修改bean定義");    //BeanDefinition beanDefinition = beanFactory.getBeanDefinition("person");    //beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);    beanFactory.registerSingleton("newobjr",new Object());  }}// 2 BeanPostProcessor bean處理器  @Componentpublic class CustomBeanPostProcessor implements BeanPostProcessor {  public CustomBeanPostProcessor() {    System.out.println("==[BeanPostProcessor 接口]調(diào)用了 CustomBeanPostProcessor 構(gòu)造器");  }  @Override  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {    System.out.println("==4 [BeanPostProcessor 接口]調(diào)用了 "+beanName+".postProcessBeforeInitialization()");    return bean;  }@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  System.out.println("==6 [BeanPostProcessor 接口]調(diào)用了 "+beanName+".postProcessAfterInitialization()");  return bean;}}// 3Bean級別生命周期接口方法  @Componentpublic class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {  public Person() {    System.out.println("==1 [Person]調(diào)用了構(gòu)造器,進行對象實例化");  }  @Override  public void setBeanName(String s) {    System.out.println("==2 [BeanNameAware 接口]調(diào)用了 BeanNameAware.setBeanName()");  }  @Override  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {    System.out.println("==3 [BeanFactoryAware 接口]調(diào)用了 BeanFactoryAware.setBeanFactory()");  }//==4 BeanPostProcessor.postProcessBeforeInitialization()...@PostConstruct//@PostConstruct是一種 BeanPostProcessorpublic void demo() {  System.out.println("==5.1 [@PostConstruct]調(diào)用了 Person.demo()");}@Overridepublic void afterPropertiesSet() throws Exception {  System.out.println("==5.2 [InitializingBean 接口]調(diào)用了 InitializingBean.afterPropertiesSet()");}//==6 BeanPostProcessor.postProcessAfterInitialization()...@Overridepublic void destroy() throws Exception {  System.out.println("==7 [DisposableBean 接口]調(diào)用了 DisposableBean.destroy()");}}  @ComponentScan(basePackages = "spring")public class SpringTest {  public static void main(String[] args) {    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);    System.out.println("spring 容器初始化成功");    Person person1 = context.getBean(Person.class);    //Person person2 = context.getBean(Person.class);    //boolean r = person1 == person2;    //System.out.println("person1 == person2 結(jié)果為:" + r); //結(jié)果為:false, 在BeanFactoryPostProcessor 中修改了bean scope    context.registerShutdownHook();    System.out.println("main結(jié)束");  }}
==[BeanFactoryPostProcessor 接口]調(diào)用了 CustomBeanFactoryPostProcessor 構(gòu)造器==[BeanFactoryPostProcessor 接口]調(diào)用了 CustomBeanFactoryPostProcessor.postProcessBeanFactory() 修改bean定義==[BeanPostProcessor 接口]調(diào)用了 CustomBeanPostProcessor 構(gòu)造器==4 [BeanPostProcessor 接口]調(diào)用了 springTest.postProcessBeforeInitialization()==6 [BeanPostProcessor 接口]調(diào)用了 springTest.postProcessAfterInitialization()//通過以下輸出可以觀察到person對象,生命周期接口方法調(diào)用順序==1 [Person]調(diào)用了構(gòu)造器,進行對象實例化==2 [BeanNameAware 接口]調(diào)用了 BeanNameAware.setBeanName()==3 [BeanFactoryAware 接口]調(diào)用了 BeanFactoryAware.setBeanFactory()==4 [BeanPostProcessor 接口]調(diào)用了 person.postProcessBeforeInitialization()==5.1 [@PostConstruct]調(diào)用了 Person.demo()==5.2 [InitializingBean 接口]調(diào)用了 InitializingBean.afterPropertiesSet()==6 [BeanPostProcessor 接口]調(diào)用了 person.postProcessAfterInitialization()spring 容器初始化成功person1 == person2 結(jié)果為:truemain結(jié)束==7 [DisposableBean 接口]調(diào)用了 DisposableBean.destroy()

Spring IOC核心類總結(jié)

1 BeanDefinition 用于封裝 spring bean 的配置信息

2 BeanDefinitionRegistry 用于存放解析后的BeanDefinition對象,spring 提供了擴展機制,允許用戶在 spring 框架啟動時動態(tài)的往BeanDefinitionRegistry容器中注冊對象

 

3 BeanFactory 是 Spring 的Bean 工廠,負(fù)責(zé) Bean 創(chuàng)建和屬性注入(
DefaultListableBeanFactory)

4 BeanFactoryPostProcessor ,BeanFactory的后置處理器; 是 spring 提供的擴展機制;

允許在所有 BeanDefinition配置信息解析完成后,修改 BeanFactory(Bean工廠)信息.例如向BeanDefinitionRegistry注冊BeanDefinition對象

在BeanFactory創(chuàng)建完成后會調(diào)用BeanFactoryPostProcessor實現(xiàn)類的 postProcessBeanFactory() 方法

 

5
ImportBeanDefinitionRegistrar接口作用于 Spring 解析 Bean 的配置階段,當(dāng)解析@Configuration 注解時調(diào)用. 需要配合@Import 注解使用

 

6 BeanPostProcessor 是Bean的后置處理器.在 Bean 初始化方法(init-method 屬性指定的方法或者 afterPropertiesSet()方法)調(diào)用前后,會執(zhí)行 BeanPostProcessor的攔截邏輯

 

7
ClassPathBeanDefinitionScanner 是BeanDefinition掃描器,能夠?qū)ο笾付ò碌?Class 進行掃描,將 Class 轉(zhuǎn)換為BeanDefinition對象注冊到BeanDefinitionRegistry 容器中

 

8 FactoryBean 是 Spring 中的工廠 bean,通常用于處理 spring 中配置較為復(fù)雜或者由動態(tài)代理生成的 Bean 實例.

實現(xiàn)了該接口的 Bean 不能作為普通的 Spring bean 使用而是作為單個對象的工廠.

當(dāng)通過 Bean 名稱獲取 FactoryBean 實例時,獲取到的并不是FactoryBean對象本身,而是FactoryBean對象 getObject()方法返回的對象

BeanFactory:定義獲取bean及bean的各種屬性。

HierarchicalBeanFactory:繼承BeanFactory,也就是在BeanFactory定義的功能的基礎(chǔ)上增加了對parentFactory的支持。

SingletonBeanRegistry:定義對單例的注冊及獲取。


DefaultSingletonBeanRegistry:對接口SingletonBeanRegistry各函數(shù)的實現(xiàn)。


AutowireCapableBeanFactory:提供創(chuàng)建bean、自動注入、初始化以及應(yīng)用bean的后處理器。


spring IOC 常用類介紹

BeanPostProcessor 注冊時機與執(zhí)行順序

BeanPostProcessor有很多個,而且每個BeanPostProcessor都影響多個Bean,其執(zhí)行順序至關(guān)重要,必須能夠控制其執(zhí)行順序才行。關(guān)于執(zhí)行順序這里需要引入兩個排序相關(guān)的接口:PriorityOrdered、Ordered

 

PriorityOrdered、Ordered接口作為Spring整個框架通用的排序接口,在Spring中應(yīng)用廣泛,也是非常重要的接口。

 

1 PriorityOrdered是一等公民,首先被執(zhí)行,PriorityOrdered公民之間通過接口返回值排序

2 Ordered是二等公民,然后執(zhí)行,Ordered公民之間通過接口返回值排序

3 都沒有實現(xiàn)是三等公民,最后執(zhí)行

//在以下源碼中,可以很清晰的看到Spring注冊各種類型BeanPostProcessor的邏輯,//根據(jù)實現(xiàn)不同排序接口進行分組。優(yōu)先級高的先加入,優(yōu)先級低的后加入。// 首先,加入實現(xiàn)了PriorityOrdered接口的BeanPostProcessors,順便根據(jù)PriorityOrdered排了序String[] postProcessorNames =  beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {  if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));    processedBeans.add(ppName);  }}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 然后,加入實現(xiàn)了Ordered接口的BeanPostProcessors,順便根據(jù)Ordered排了序postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {  if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));    processedBeans.add(ppName);  }}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 最后加入其他常規(guī)的BeanPostProcessorsboolean reiterate = true;while (reiterate) {  reiterate = false;  postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);  for (String ppName : postProcessorNames) {    if (!processedBeans.contains(ppName)) {      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));      processedBeans.add(ppName);      reiterate = true;    }  }  sortPostProcessors(currentRegistryProcessors, beanFactory);  registryProcessors.addAll(currentRegistryProcessors);  invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);  currentRegistryProcessors.clear();}//根據(jù)排序接口返回值排序,默認(rèn)升序排序,返回值越低優(yōu)先級越高。PriorityOrdered、Ordered接口作為Spring整個框架通用的排序接口,在Spring中應(yīng)用廣泛,也是非常重要的接口。

 

 

分享到:
標(biāo)簽:容器 IOC
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定