<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      轉(zhuǎn)載和引用,請(qǐng)注明原文出處! Fork me on GitHub
      結(jié)局很美妙的事,開(kāi)頭并非如此!

      框架源碼系列八:Spring源碼學(xué)習(xí)之Spring核心工作原理(很重要)

      目錄:
      一、搞清楚ApplicationContext實(shí)例化Bean的過(guò)程
      二、搞清楚這個(gè)過(guò)程中涉及的核心類
      三、搞清楚IOC容器提供的擴(kuò)展點(diǎn)有哪些,學(xué)會(huì)擴(kuò)展
      四、學(xué)會(huì)IOC容器這里使用的設(shè)計(jì)模式
      五、搞清楚不同創(chuàng)建方式的bean的創(chuàng)建過(guò)程

      一、ApplicationContext實(shí)例化bean的過(guò)程

      1. 找入口,掃描注冊(cè)完beanDefinition后,要?jiǎng)?chuàng)建bean的實(shí)例,入口在哪里?

      AnnotationConfigApplicationContext context4 = new AnnotationConfigApplicationContext("com.study.leesmall.spring.service");
          /**
           * Create a new AnnotationConfigApplicationContext, scanning for bean definitions
           * in the given packages and automatically refreshing the context.
           * @param basePackages the packages to check for annotated classes
           */
          public AnnotationConfigApplicationContext(String... basePackages) {
              this();
              scan(basePackages);
              refresh();
          }

      org.springframework.context.support.AbstractApplicationContext.refresh()方法就是入口了

          @Override
          public void refresh() throws BeansException, IllegalStateException {
              synchronized (this.startupShutdownMonitor) {
                  // Prepare this context for refreshing.
                  prepareRefresh();
      
                  // Tell the subclass to refresh the internal bean factory.
                  ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      
                  // Prepare the bean factory for use in this context.
                  prepareBeanFactory(beanFactory);
      
                  try {
                      // Allows post-processing of the bean factory in context subclasses.
                      postProcessBeanFactory(beanFactory);
      
                      // Invoke factory processors registered as beans in the context.
                      invokeBeanFactoryPostProcessors(beanFactory);
      
                      // Register bean processors that intercept bean creation.
                      registerBeanPostProcessors(beanFactory);
      
                      // Initialize message source for this context.
                      initMessageSource();
      
                      // Initialize event multicaster for this context.
                      initApplicationEventMulticaster();
      
                      // Initialize other special beans in specific context subclasses.
                      onRefresh();
      
                      // Check for listener beans and register them.
                      registerListeners();
      
                      // Instantiate all remaining (non-lazy-init) singletons.
                      finishBeanFactoryInitialization(beanFactory);
      
                      // Last step: publish corresponding event.
                      finishRefresh();
                  }
      
                  catch (BeansException ex) {
                      if (logger.isWarnEnabled()) {
                          logger.warn("Exception encountered during context initialization - " +
                                  "cancelling refresh attempt: " + ex);
                      }
      
                      // Destroy already created singletons to avoid dangling resources.
                      destroyBeans();
      
                      // Reset 'active' flag.
                      cancelRefresh(ex);
      
                      // Propagate exception to caller.
                      throw ex;
                  }
      
                  finally {
                      // Reset common introspection caches in Spring's core, since we
                      // might not ever need metadata for singleton beans anymore...
                      resetCommonCaches();
                  }
              }
          }

      2.  讀懂org.springframework.context.support.AbstractApplicationContext.refresh()方法的處理流程

      1)準(zhǔn)備context為了刷新

      // Prepare this context for refreshing.
                  prepareRefresh();

      2)從子類獲取BeanFactory實(shí)例

      // Tell the subclass to refresh the internal bean factory.
                  ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      3)準(zhǔn)備BeanFactory為了使用context

                  // Prepare the bean factory for use in this context.
                  prepareBeanFactory(beanFactory);
      /**
           * Configure the factory's standard context characteristics,
           * such as the context's ClassLoader and post-processors.
           * @param beanFactory the BeanFactory to configure
           */
          protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
              // Tell the internal bean factory to use the context's class loader etc.
              beanFactory.setBeanClassLoader(getClassLoader());
              beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
              beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
      
              // Configure the bean factory with context callbacks.
              beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
              beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
              beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
              beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
              beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
              beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
              beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
      
              // BeanFactory interface not registered as resolvable type in a plain factory.
              // MessageSource registered (and found for autowiring) as a bean.
              beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
              beanFactory.registerResolvableDependency(ResourceLoader.class, this);
              beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
              beanFactory.registerResolvableDependency(ApplicationContext.class, this);
      
              // Register early post-processor for detecting inner beans as ApplicationListeners.
              beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
      
              // Detect a LoadTimeWeaver and prepare for weaving, if found.
              if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                  beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                  // Set a temporary ClassLoader for type matching.
                  beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
              }
      
              // Register default environment beans.
              if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
                  beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
              }
              if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
                  beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
              }
              if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
                  beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
              }
          }

      重要1:

      beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)) 這段代碼很重要:

      如果你的bean實(shí)例里面需要ApplicationContext,你就需要實(shí)現(xiàn)ApplicationContextAwareProcessor這個(gè)接口,接口就會(huì)把ApplicationContext給到你的bean實(shí)例
      也可以通過(guò)autowired注解去獲取,因?yàn)橄旅娴倪@段代碼:

      beanFactory.registerResolvableDependency(ApplicationContext.class, this);

      重要2:

      注解方式加載配置

      package com.study.leesmall.spring.ext;
      
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.PropertySource;
      import org.springframework.context.support.ReloadableResourceBundleMessageSource;
      
      @Configuration
      @PropertySource("classpath:/application.properties")
      public class MyConfiguration {
      
          @Bean("messageSource")
          public ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
              ReloadableResourceBundleMessageSource rms = new ReloadableResourceBundleMessageSource();
              rms.setBasename("message");
              return rms;
          }
      }

      重要3:

      參數(shù)配置的優(yōu)先級(jí):命令參數(shù) > 環(huán)境變量 > properties 文件

              // Register default environment beans.
              if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
                  beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
              }
              if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
                  beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
              }
              if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
                  beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
              }

      命令參數(shù)配置方式:進(jìn)入要運(yùn)行的類——run as——run configurations——彈出如下界面——選擇——Arguments——添加參數(shù)

       環(huán)境變量參數(shù)配置方式:進(jìn)入要運(yùn)行的類——run as——run configurations——彈出如下界面——選擇——Environment——添加參數(shù)

       

       properties 文件參數(shù)配置方式:直接在Resource目錄下加入properties文件里面加入?yún)?shù)——在application.xml配置加載properties文件即可

      參數(shù):

      # jdbc properties
      jdbc.driverClassName=xxxx
      jdbc.url=xxxx
      jdbc.username=xxxx
      jdbc.password=xxxx

       在application.xml配置加載properties文件

          <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
              <property name="locations" value="classpath:application.properties"/>
          </bean>

       4)對(duì)BeanFactory進(jìn)行預(yù)處理

                // Allows post-processing of the bean factory in context subclasses.
                      postProcessBeanFactory(beanFactory);

       說(shuō)明:這里用了模板方法設(shè)計(jì)模式,需要子類去實(shí)現(xiàn)的

       5)調(diào)用執(zhí)行BeanFactoryPostProcessor (這是一個(gè)很重要的擴(kuò)展點(diǎn),如果你想在Bean實(shí)例化前對(duì)BeanFactory進(jìn)行處理的話,你就可以實(shí)現(xiàn)BeanFactoryPostProcessor接口及其子類如BeanDefinitionRegistryPostProcessor,示例如下面的排序優(yōu)先級(jí)代碼)

                      // Invoke factory processors registered as beans in the context.
                      invokeBeanFactoryPostProcessors(beanFactory);
          /**
           * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
           * respecting explicit order if given.
           * <p>Must be called before singleton instantiation.
           */
          protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
              PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
      
              // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
              // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
              if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                  beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                  beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
              }
          }

       委托給PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())執(zhí)行

       這里要注意一下Spring里面有很多類似這樣的委托處理

      代碼詳細(xì)解讀:

       

       

      說(shuō)明:

      BeanFactoryPostProcessor在實(shí)例化bean之前對(duì)BeanFactory進(jìn)行處理的
      BeanPostProcessor在bean實(shí)例化后,對(duì)bean進(jìn)行處理的
      這兩個(gè)類用了觀察者模式
      AbstractApplicationContextrefresh模板方法模式
      執(zhí)行優(yōu)先級(jí):priorityOrded>orded

      執(zhí)行順序示例:

      優(yōu)先排序的:

      package com.study.leesmall.spring.ext;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      import org.springframework.beans.factory.support.BeanDefinitionRegistry;
      import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
      import org.springframework.core.PriorityOrdered;
      import org.springframework.stereotype.Component;
      
      @Component
      public class MyBeanDefinitonRegistryPostProcessor3 implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
      
          @Override
          public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
              System.out.println("--- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanFactory 被執(zhí)行了。");
      
          }
      
          @Override
          public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
              System.out.println("--- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanDefinitionRegistry 被執(zhí)行了。");
          }
      
          @Override
          public int getOrder() {
              return 1;
          }
      
      }

      普通排序的:

      package com.study.leesmall.spring.ext;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      import org.springframework.beans.factory.support.BeanDefinitionRegistry;
      import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
      import org.springframework.core.Ordered;
      import org.springframework.stereotype.Component;
      
      @Component
      public class MyBeanDefinitonRegistryPostProcessor2 implements BeanDefinitionRegistryPostProcessor, Ordered {
      
          @Override
          public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
              System.out.println("--- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanFactory 被執(zhí)行了。");
      
          }
      
          @Override
          public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
              System.out.println("--- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanDefinitionRegistry 被執(zhí)行了。");
          }
      
          @Override
          public int getOrder() {
              return 0;
          }
      
      }

      沒(méi)有排序的:

      package com.study.leesmall.spring.ext;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      import org.springframework.beans.factory.support.BeanDefinitionRegistry;
      import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
      import org.springframework.stereotype.Component;
      
      @Component
      public class MyBeanDefinitonRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
      
          @Override
          public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
              System.out.println("--- MyBeanDefinitonRegistryPostProcessor.postProcessBeanFactory 被執(zhí)行了。");
      
          }
      
          @Override
          public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
              System.out.println("--- MyBeanDefinitonRegistryPostProcessor.postProcessBeanDefinitionRegistry 被執(zhí)行了。");
          }
      
      }

      運(yùn)行結(jié)果:

      --- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanDefinitionRegistry 被執(zhí)行了。
      --- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanDefinitionRegistry 被執(zhí)行了。
      --- MyBeanDefinitonRegistryPostProcessor.postProcessBeanDefinitionRegistry 被執(zhí)行了。
      --- MyBeanDefinitonRegistryPostProcessor3.postProcessBeanFactory 被執(zhí)行了。
      --- MyBeanDefinitonRegistryPostProcessor2.postProcessBeanFactory 被執(zhí)行了。
      --- MyBeanDefinitonRegistryPostProcessor.postProcessBeanFactory 被執(zhí)行了。

      6)向BeanFactory注冊(cè)BeanPostProcessor(這是一個(gè)很重要的擴(kuò)展點(diǎn),如果你想在Bean實(shí)例化后對(duì)Bean進(jìn)行處理的話)

      registerBeanPostProcessors(beanFactory)

      獲得用戶注冊(cè)的BeanPostProcessor的bean定義,創(chuàng)建他們的實(shí)例,注冊(cè)到BeanFactory,對(duì)bean實(shí)例化后進(jìn)行處理

       7)initMessageSource();初始化國(guó)際化資源文件

      示例:

      package com.study.leesmall.spring.ext;
      
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.PropertySource;
      import org.springframework.context.support.ReloadableResourceBundleMessageSource;
      
      //國(guó)際化 給入messageSource的bean實(shí)例到bean工廠
      @Configuration
      @PropertySource("classpath:/application.properties")
      public class MyConfiguration {
      
          @Bean("messageSource")
          public ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
              ReloadableResourceBundleMessageSource rms = new ReloadableResourceBundleMessageSource();
              rms.setBasename("message");
              return rms;
          }
      }

      8)initApplicationEventMulticaster 了解即可
      初始化Application Event廣播器,把所有事件廣播出去

      9)執(zhí)行onRefresh(); 由子類來(lái)提供實(shí)現(xiàn)

      10)registerListeners() (這是一個(gè)很重要的擴(kuò)展點(diǎn),如果你想對(duì)容器工作過(guò)程中發(fā)生的節(jié)點(diǎn)事件進(jìn)行一些處理,比如容器要刷新、容器要關(guān)閉了,那么你就可以實(shí)現(xiàn)ApplicationListener)
      注冊(cè)ApplicationListener:獲得用戶注冊(cè)的ApplicationListener的bean定義,創(chuàng)建他們的實(shí)例注冊(cè)到第8步初始化的廣播器上

      示例代碼:

      package com.study.leesmall.spring.ext;
      
      import org.springframework.context.ApplicationEvent;
      import org.springframework.context.ApplicationListener;
      import org.springframework.stereotype.Component;
      
      //如果你想對(duì)容器工作過(guò)程中發(fā)生的節(jié)點(diǎn)事件進(jìn)行一些處理,比如容器要刷新、容器要關(guān)閉了,那么你就可以實(shí)現(xiàn)ApplicationListener
      @Component
      public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
      
          @Override
          public void onApplicationEvent(ApplicationEvent event) {
              System.out.println("-----收到應(yīng)用事件:" + event);
          }
      }

      11)finishBeanFactoryInitialization(beanFactory); 完成剩余的單例bean的實(shí)例化,為了提前實(shí)例化,后面不用getBean去創(chuàng)建實(shí)例

      a)什么時(shí)候?qū)嵗痓ean?
        單例bean可以在啟動(dòng)時(shí)實(shí)例化好,這樣能提高使用時(shí)的效率
        原型bean在getBean(beanName)的時(shí)候?qū)嵗?br>b)單例bean和原型bean實(shí)例化的過(guò)程有區(qū)別嗎?
        沒(méi)有區(qū)別的
      c)Spring中支持的bean實(shí)例創(chuàng)建的方式有幾種?分別如何配置的,如何來(lái)獲取Bean實(shí)例的?
        創(chuàng)建bean實(shí)例的方式:構(gòu)造函數(shù)方式、工廠方式(靜態(tài)工廠方式、非靜態(tài)工廠方式)、實(shí)現(xiàn)FactoryBean的方式

       

      工廠方式創(chuàng)建bean實(shí)例示例代碼:

      package com.study.leesmall.spring.sample.factory;
      
      import com.study.leesmall.spring.service.CombatService;
      import com.study.leesmall.spring.service.LoveService;
      import com.study.leesmall.spring.service.LoveServiceImpl;
      
      //工廠方式創(chuàng)建bean實(shí)例
      public class LoveServiceFactory {
      
          //靜態(tài)工廠方式創(chuàng)建bean實(shí)例
          public static LoveService getLoveServiceFromStaticFactoryMethod() {
              return new LoveServiceImpl();
          }
      
          //非靜態(tài)工廠方式創(chuàng)建bean實(shí)例
          public CombatService getCombatServiceFromMemberFactoryMethod(int time) {
              return new CombatService(time);
          }
      }

      實(shí)現(xiàn)FactoryBean的方式創(chuàng)建bean實(shí)例示例代碼:

      package com.study.leesmall.spring.sample.factory;
      
      import org.springframework.beans.factory.FactoryBean;
      
      import com.study.leesmall.spring.service.LoveService;
      import com.study.leesmall.spring.service.LoveServiceImpl;
      
      //實(shí)現(xiàn)FactoryBean的方式創(chuàng)建bean實(shí)例
      public class LoveServiceFactoryBean implements FactoryBean<LoveService> {
      
          @Override
          public LoveService getObject() throws Exception {
              return new LoveServiceImpl();
          }
      
          @Override
          public Class<?> getObjectType() {
              return LoveService.class;
          }
      
      }

      那么上面的創(chuàng)建bean實(shí)例的方式怎么在xm里面配置呢:

          <!--靜態(tài)工廠方式的配置  -->
          <bean id="loveService" class="com.study.leesmall.spring.sample.factory.LoveServiceFactory" 
              factory-method="getLoveServiceFromStaticFactoryMethod">
              <property name="combatService" ref="combatService"></property>
          </bean>
          <!--非靜態(tài)工廠方式的配置  -->
          <bean id="loveServiceFactory" class="com.study.leesmall.spring.sample.factory.LoveServiceFactory"> 
          </bean>
              <bean id="combatService" factory-bean="loveServiceFactory" factory-method="getCombatServiceFromMemberFactoryMethod">
              <constructor-arg type="int" value="60" />
          </bean>
          <!--實(shí)現(xiàn)FactoryBean的方式的配置  -->
          <bean name="loveService2" class="com.study.leesmall.spring.sample.factory.LoveServiceFactoryBean"></bean>

      那么注解方式又怎么配置呢:

      工廠方式創(chuàng)建bean實(shí)例注解配置:

      import org.springframework.context.annotation.Bean;
      import org.springframework.stereotype.Component;
      
      import com.study.leesmall.spring.service.CombatService;
      import com.study.leesmall.spring.service.LoveService;
      import com.study.leesmall.spring.service.LoveServiceImpl;
      
      //工廠方式創(chuàng)建bean實(shí)例
      @Component
      public class LoveServiceFactory {
      
          //靜態(tài)工廠方式創(chuàng)建bean實(shí)例
          @Bean
          public static LoveService getLoveServiceFromStaticFactoryMethod() {
              return new LoveServiceImpl();
          }
      
          //非靜態(tài)工廠方式創(chuàng)建bean實(shí)例
          @Bean
          public CombatService getCombatServiceFromMemberFactoryMethod(int time) {
              return new CombatService(time);
          }
      }

      實(shí)現(xiàn)FactoryBean的方式創(chuàng)建bean實(shí)例注解配置:

      import org.springframework.beans.factory.FactoryBean;
      import org.springframework.stereotype.Component;
      
      import com.study.leesmall.spring.service.LoveService;
      import com.study.leesmall.spring.service.LoveServiceImpl;
      
      //實(shí)現(xiàn)FactoryBean的方式創(chuàng)建bean實(shí)例
      @Component
      public class LoveServiceFactoryBean implements FactoryBean<LoveService> {
      
          @Override
          public LoveService getObject() throws Exception {
              return new LoveServiceImpl();
          }
      
          @Override
          public Class<?> getObjectType() {
              return LoveService.class;
          }
      
      }

      代碼跟蹤:

      入口:org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(ConfigurableListableBeanFactory)

      數(shù)據(jù)類型的轉(zhuǎn)換:

      // Initialize conversion service for this context.
              if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                      beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
                  beanFactory.setConversionService(
                          beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
              }

      數(shù)據(jù)類型的轉(zhuǎn)換對(duì)應(yīng)在xml配置里面的寫(xiě)法:

          <bean id="combatService" class="com.study.leesmall.spring.service.CombatService">
              <constructor-arg type="int" value="60" />
          </bean>

      初始化內(nèi)嵌值的解析器,如properties文件里面配置的值就需要這種解析器:

          // Register a default embedded value resolver if no bean post-processor
              // (such as a PropertyPlaceholderConfigurer bean) registered any before:
              // at this point, primarily for resolution in annotation attribute values.
              if (!beanFactory.hasEmbeddedValueResolver()) {
                  beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
              }

      AOP:bean實(shí)例初始化后,在進(jìn)行代理增強(qiáng),不創(chuàng)建原始bean實(shí)例,直接創(chuàng)建代理子類的實(shí)例

              // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
              String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
              for (String weaverAwareName : weaverAwareNames) {
                  getBean(weaverAwareName);
              }

      提前實(shí)例化剩余的所有單例bean:

      // Instantiate all remaining (non-lazy-init) singletons.
              beanFactory.preInstantiateSingletons();

      說(shuō)明:看子類的實(shí)現(xiàn),過(guò)程是找到單例bean的名稱,然后getBean(beanName)拿到單例bean的實(shí)例

      d)beanfactory中g(shù)etBean()時(shí)的創(chuàng)建實(shí)例流程

       

      代碼跟蹤:

      入口:

      org.springframework.beans.factory.support.AbstractBeanFactory.getBean(String)
      org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)

       

       

       

       

       

       

      下面來(lái)看一下真正創(chuàng)建bean實(shí)例的方法

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[]):

      看一下org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])里面的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String, RootBeanDefinition)

      方法:

       然后看一下上面調(diào)用的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(Class<?>, String)方法:

       

      注意:

      這里又是一個(gè)擴(kuò)展點(diǎn), InstantiationAwareBeanPostProcessor 可以在 Bean 實(shí)例創(chuàng)建前、后進(jìn)行增強(qiáng)處理

      如果你想在bean實(shí)例創(chuàng)建前后進(jìn)行處理可以繼承InstantiationAwareBeanPostProcessor的子類InstantiationAwareBeanPostProcessorAdaper,然后覆寫(xiě)里面你需要實(shí)現(xiàn)的方法,創(chuàng)建前處理就實(shí)現(xiàn)創(chuàng)建前處理的方法

      對(duì)比:
      BeanPostProcessor可以在bean實(shí)例初始化前和初始化后進(jìn)行處理

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])

      -> 

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])

       

      看一下org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(String, RootBeanDefinition, BeanWrapper)方法:

      繼續(xù)看一下創(chuàng)建bean實(shí)例的代碼塊:

              if (instanceWrapper == null) {
                  instanceWrapper = createBeanInstance(beanName, mbd, args);
              }

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(String, RootBeanDefinition, Object[])

       

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(String, RootBeanDefinition, Constructor<?>[], Object[])

      ->

      org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(String, RootBeanDefinition, Constructor<?>[], Object[])

       

      說(shuō)明:

      explicitArgs:當(dāng)你調(diào)用getBean的時(shí)候給定的造參數(shù) spring在getbean的時(shí)候是可以自己傳入構(gòu)造參數(shù)的,可以不用bean定義里面指定或者xml里面配置的構(gòu)造參數(shù),示例如下:

      getbean(“l(fā)oveService”, .....)

       

      拓展:

      工廠Bean和Bean工廠的區(qū)別:
      工廠Bean實(shí)現(xiàn)了FactoryBean接口的Bean
      Bean工廠BeanFactory IOC容器

      12)finishRefresh() 發(fā)布事件

      二、 搞清楚這個(gè)過(guò)程中涉及的核心類

      三、 搞清楚IOC容器提供的擴(kuò)展點(diǎn)有哪些,學(xué)會(huì)擴(kuò)展

      1. 擴(kuò)展點(diǎn):如第一個(gè)大標(biāo)題

      一、ApplicationContext實(shí)例化bean的過(guò)程

      2.  讀懂org.springframework.context.support.AbstractApplicationContext.refresh()方法的處理流程

      的5)、6)、10)步均為擴(kuò)展點(diǎn)

      5)調(diào)用執(zhí)行BeanFactoryPostProcessor (這是一個(gè)很重要的擴(kuò)展點(diǎn),如果你想在Bean實(shí)例化前對(duì)BeanFactory進(jìn)行處理的話,你就可以實(shí)現(xiàn)BeanFactoryPostProcessor接口及其子類如BeanDefinitionRegistryPostProcessor,示例如下面的排序優(yōu)先級(jí)代碼)

      6)向BeanFactory注冊(cè)BeanPostProcessor(這是一個(gè)很重要的擴(kuò)展點(diǎn),如果你想在Bean實(shí)例化后對(duì)Bean進(jìn)行處理的話)

      10)registerListeners() (這是一個(gè)很重要的擴(kuò)展點(diǎn),如果你想對(duì)容器工作過(guò)程中發(fā)生的節(jié)點(diǎn)事件進(jìn)行一些處理,比如容器要刷新、容器要關(guān)閉了,那么你就可以實(shí)現(xiàn)ApplicationListener)
      注冊(cè)ApplicationListener:獲得用戶注冊(cè)的ApplicationListener的bean定義,創(chuàng)建他們的實(shí)例注冊(cè)到第8步初始化的廣播器上

      BeanDefinitionRegistryPostProcessor

      BeanFactoryPostProcessor

      BeanPostProcessorr

      ApplicationListener

      11)finishBeanFactoryInitialization(beanFactory); 完成剩余的單例bean的實(shí)例化,為了提前實(shí)例化,后面不用getBean去創(chuàng)建實(shí)例的

      然后看一下上面調(diào)用的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(Class<?>, String)方法的講解

      注意:

      這里又是一個(gè)擴(kuò)展點(diǎn), InstantiationAwareBeanPostProcessor 可以在 Bean 實(shí)例創(chuàng)建前、后進(jìn)行增強(qiáng)處理

      如果你想在bean實(shí)例創(chuàng)建前后進(jìn)行處理可以繼承InstantiationAwareBeanPostProcessor的子類InstantiationAwareBeanPostProcessorAdaper,然后覆寫(xiě)里面你需要實(shí)現(xiàn)的方法,創(chuàng)建前處理就實(shí)現(xiàn)創(chuàng)建前處理的方法

      對(duì)比:
      BeanPostProcessor可以在bean實(shí)例初始化前和初始化后進(jìn)行處理

      2. Spring容器啟動(dòng)時(shí)完成了哪幾件核心事情:
      1)Bean定義的獲得(解析xml或者掃描注解)
      2)環(huán)境的初始化 env
      3)BeanDefinitionRegistryPostProcessor的自動(dòng)發(fā)現(xiàn)與執(zhí)行
      4)BeanFactoryPostProcessor的自動(dòng)發(fā)現(xiàn)與執(zhí)行
      5)BeanPostProcessorr的自動(dòng)發(fā)現(xiàn)與注冊(cè)
      6)國(guó)際化資源初始化
      7)事件廣播器的初始化
      8)ApplicationListener的自動(dòng)發(fā)現(xiàn)與注冊(cè)
      9)實(shí)例化單例bean

      四、 學(xué)會(huì)IOC容器這里使用的設(shè)計(jì)模式

      模板方法設(shè)計(jì)模式、觀察者模式(主要是這兩個(gè))、策略模式、工廠模式

      搞清楚不同創(chuàng)建方式的bean的創(chuàng)建過(guò)程

       完整代碼獲取地址:https://github.com/leeSmall/FrameSourceCodeStudy/tree/master/spring-source-study

      posted @ 2019-03-17 10:52  小不點(diǎn)啊  閱讀(6180)  評(píng)論(2)    收藏  舉報(bào)
      主站蜘蛛池模板: 妺妺窝人体色www看美女| 中文字幕无码免费久久| 国产av仑乱内谢| 国产高潮刺激叫喊视频| 在线观看国产成人av片| 亚洲第一香蕉视频啪啪爽| 久久一级精品久熟女人妻| 自拍偷在线精品自拍偷免费| 高清免费毛片| 日韩精品亚洲 国产| 国产不卡av一区二区| 国产精品日本一区二区不卡视频| 亚洲精品国产福利一区二区| 精品一区二区中文字幕| 久久综合老鸭窝色综合久久| 欧美国产日韩久久mv| 国产精品制服丝袜第一页| 亚洲国产午夜福利精品| 日韩熟女精品一区二区三区| 小伙无套内射老熟女精品| 久久亚洲中文字幕伊人久久大| 国产精品制服丝袜第一页 | 久久se精品一区二区三区| 一个人在看www免费| 亚洲成av人片天堂网| 日韩成人无码影院| 国产一区二区三区不卡自拍| 麻豆一区二区中文字幕| 国产午夜成人无码免费看| 天堂а√在线地址中文在线| 国产一区二区亚洲一区二区三区 | 国产成人午夜福利精品| 亚洲精品一区二区二三区| 国产一区二区不卡自拍| 亚洲国产成人久久精品软件| 免费的特黄特色大片| 亚洲欧美一区二区成人片| 久热这里只国产精品视频| 亚洲AVAV天堂AV在线网阿V| 欧美性猛交xxxx乱大交丰满| 婷婷色综合视频在线观看|