【SpringIOC容器初始化(一)】

心不动则不痛 提交于 2020-03-05 14:07:41

【SpringIOC容器初始化(一)】
 1、 IOC容器是指的spring bean 工厂里面MAP存储结构,包含beanFactory、applicationContext工厂;
 2、 beanFactory采取的延迟加载,第一次getBean时才会初始化Bean;
     applicationContext是加载完applicationContext.xml 就创建了具体的bean实例(只对BeanDefition中描述是单例的bean,才进行恶汉模式创建)
   
 3、applicationContext接口常用实现类
    classpathXmlApplicationContext : 它是从类的跟路劲下加载配置文件,推荐使用这种
    FileSystemXmlApplicationContext: 它是从磁盘上加载配置文件,配置文件可以在磁盘的任意位置
    AnnotationConfigApplicationContext : 当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
    
 4、步骤
    4.1 new ClassPathXmlApplicationContext(),初始化ClassPathXmlApplicationContext
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
    }
    
    4.2 调用AbstractRefreshableConfigApplicationContext的setConfigLocations(configLocations),设置xml文件路径
    public void setConfigLocations(String... locations) {
    if (locations != null) {
        Assert.noNullElements(locations, "Config locations must not be null");
        this.configLocations = new String[locations.length];
        for (int i = 0; i < locations.length; i++) {
            this.configLocations[i] = resolvePath(locations[i]).trim();
        }
    }
    else {
        this.configLocations = null;
    }
    }
    4.3 AbstractXmlApplicationContext方法loadBeanDefinitions
    public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
            private boolean validating = true;
            public AbstractXmlApplicationContext() {  }
            public AbstractXmlApplicationContext(ApplicationContext parent) {
                super(parent);
            }
            public void setValidating(boolean validating) {      this.validating = validating;    }
            protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 这里最终还是通过XmlBeanDefinitionReader进行加载xml
                XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
                beanDefinitionReader.setEnvironment(this.getEnvironment());
                beanDefinitionReader.setResourceLoader(this);
                beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
                this.initBeanDefinitionReader(beanDefinitionReader);
                this.loadBeanDefinitions(beanDefinitionReader);
            }
            protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
                reader.setValidating(this.validating);
            }
           protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
                Resource[] configResources = this.getConfigResources();  // 获取配置文件路径的资源。
                if (configResources != null) {
                    reader.loadBeanDefinitions(configResources);  // 这里调用了XmlBeanDefinitionReader的loadBeanDefinitions方法。这里将对xml进行解析,最终加入到map中
                }
                String[] configLocations = this.getConfigLocations();
                if (configLocations != null) {
                    reader.loadBeanDefinitions(configLocations);
                }
            }
            protected Resource[] getConfigResources() {
                return null;
            }
        }
    4.4 XmlBeanDefinitionReader 形成
       private Class<?> documentReaderClass = DefaultBeanDefinitionDocumentReader.class; 
       private NamespaceHandlerResolver namespaceHandlerResolver;
       private DocumentLoader documentLoader = new DefaultDocumentLoader();
       private EntityResolver entityResolver;
       private ErrorHandler errorHandler = new SimpleSaxErrorHandler(logger);
       private final XmlValidationModeDetector validationModeDetector = new XmlValidationModeDetector();
       private final ThreadLocal<Set<EncodedResource>> resourcesCurrentlyBeingLoaded =new NamedThreadLocal<Set<EncodedResource>>("XML bean definition resources currently being loaded");
       public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
          super(registry);  // 将XmlBeanFactory进行保存
       }
       @Override
       public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
          return loadBeanDefinitions(new EncodedResource(resource));  // 包装了一下
       }
    // 返回发现bean的个数
      public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
          Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); //尝试获取
          if (currentResources == null) {   // 如果没有,是刚初始化,就进行初始化
             currentResources = new HashSet<EncodedResource>(4); // 默认空间大小为4
             this.resourcesCurrentlyBeingLoaded.set(currentResources);  
          }
          if (!currentResources.add(encodedResource)) {  // 添加当前的资源文件到Set容器中
             throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
          }
          try { // 获得配置文件的输入流(将配置资源文件转换为流)
             InputStream inputStream = encodedResource.getResource().getInputStream(); 
             try {
                InputSource inputSource = new InputSource(inputStream); // 包装了这个流,为Source
                if (encodedResource.getEncoding() != null) {   // 是否编码。编码了就进行解码
                   inputSource.setEncoding(encodedResource.getEncoding());
                }
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); // 这里加载这个配置
             } finally {
                inputStream.close();
             }
          } catch (IOException ex) {。。。。
          }
          finally {
             currentResources.remove(encodedResource); //
             if (currentResources.isEmpty()) {   // 如果为空,则从ThreadLocal中移除
                this.resourcesCurrentlyBeingLoaded.remove();
             }
          }
       }
       public int loadBeanDefinitions(InputSource inputSource) throws BeanDefinitionStoreException {
          return loadBeanDefinitions(inputSource, "resource loaded through SAX InputSource");
       }
       public int loadBeanDefinitions(InputSource inputSource, String resourceDescription) throws BeanDefinitionStoreException {
          return doLoadBeanDefinitions(inputSource, new DescriptiveResource(resourceDescription));
       }
        //实际完成对xml进行载入的方法
       protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
          try {      // Document代表xml文档对象
             Document doc = doLoadDocument(inputSource, resource); // 总之这里会返回一个Document
             return registerBeanDefinitions(doc, resource);  // 将返回的Document注册
          } catch (BeanDefinitionStoreException ex) {
             throw ex; …. 
          catch (Throwable ex) {
             throw new BeanDefinitionStoreException(resource.getDescription(),"Unexpected om ");
          }
       }
       // 加载xml文件,返回Document。使用DefaultDocumentLoader的loadDocument方法,返回一个Document
       protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
          return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
                getValidationModeForResource(resource), isNamespaceAware());
       }
        //使用DefaultNamespaceHandlerResolver 进行解析Document
       public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
          BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        // 用代理对象
          int countBefore = getRegistry().getBeanDefinitionCount();  // 获取父类的BeanDefinitionRegistry(这里也就是IOC容器DefaultListableBeanFactory),然后调用getBeanDefinitionCount方法。获得注册之前的数量
          documentReader.registerBeanDefinitions(doc, createReaderContext(resource));// 这里进行了解析和注入,DefaultBeanDefinitionDocumentReader中实现
          return getRegistry().getBeanDefinitionCount() - countBefore;  // 这里返回了数量
       }
       protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
      return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));
       }
       public XmlReaderContext createReaderContext(Resource resource) {
          return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, getNamespaceHandlerResolver());
       }
       public NamespaceHandlerResolver getNamespaceHandlerResolver() {  // 单例模式获取
          if (this.namespaceHandlerResolver == null) {
             this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
          }
          return this.namespaceHandlerResolver;
       }
       protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
          return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader());
       }
    4.5 AbstractRefreshableConfigApplicationContext 将配置文件进行保存
    public void setConfigLocation(String location) {
      setConfigLocations(StringUtils.tokenizeToStringArray(location, CONFIG_LOCATION_DELIMITERS));
       }
       public void setConfigLocations(String... locations) {  // 将配置文件进行保存
          if (locations != null) {
             Assert.noNullElements(locations, "Config locations must not be null");
             this.configLocations = new String[locations.length];
             for (int i = 0; i < locations.length; i++) {
                this.configLocations[i] = resolvePath(locations[i]).trim(); // 查找出真实的路径
             }
          } else {
             this.configLocations = null;
          }
       }
    4.6 AbstractRefreshableApplicationContext之BeanFactory的处理
    @Override
    protected final void refreshBeanFactory() throws BeansException {
      if (hasBeanFactory()) {  // 判断是否有BeanFactory
         destroyBeans();   // 如果有就销毁,
         closeBeanFactory();//并且关闭
      }
      try {
         DefaultListableBeanFactory beanFactory = createBeanFactory();  // 创建新的BeanFactory
         beanFactory.setSerializationId(getId());  // 设置序列化
         customizeBeanFactory(beanFactory);
         loadBeanDefinitions(beanFactory);
         synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
         }
      } catch (IOException ex) {
         throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
      }
      }
      ...
      @Override
       protected void cancelRefresh(BeansException ex) {
          synchronized (this.beanFactoryMonitor) {
             if (this.beanFactory != null)
                this.beanFactory.setSerializationId(null);
          }
          super.cancelRefresh(ex);
       }
      
    4.7 调用AbstractApplicationContext的refresh(),重点看,对于ClassPathXmlApplicationContext加载bean,只需了解它的obtainFreshBeanFactory方法。
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 刷新上下文环境
            prepareRefresh();

            // 初始化BeanFactory,进行xml文件读取
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 对BeanFactory进行各种功能的填充
            prepareBeanFactory(beanFactory);

            try {
                // 子类覆盖方法做其他的处理
                postProcessBeanFactory(beanFactory);

                // 激活BeanFactory的处理器
                invokeBeanFactoryPostProcessors(beanFactory);

                // 注册拦截Bean创建的Bean处理器
                registerBeanPostProcessors(beanFactory);

                // 为上下文初始化Message源
                initMessageSource();

                // 初始化应用消息广播器
                initApplicationEventMulticaster();

                // 留给子类初始化其他的bean
                onRefresh();

                // 查找Listeners bean,注册到消息广播器中
                registerListeners();

                // 初始化剩下的单实例
                finishBeanFactoryInitialization(beanFactory);

                // 完成刷新过程,通知生命周期处理器
                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();
            }
        }
    }
    4.8 refresh中各个方法解析
    protected void prepareRefresh() {
       this.startupDate = System.currentTimeMillis();
       this.closed.set(false);
       this.active.set(true); 
       initPropertySources();  // 初始化配置文件
       getEnvironment().validateRequiredProperties();
       this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
    }
    ..
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
       refreshBeanFactory();  // 这里对xml进行了解析,并且已经成功加入到map中了
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       return beanFactory; // 最终返回这个bean,就是DefaultListableBeanFactory对象,加载了xml的工厂
    }
    ..
    子类实现:
  1、在bean工厂自动装配的时候忽略一些接口。如:ServletContextAware、ServletConfigAware
  2、注册WEB应用特定的域(scope)到bean工厂中,以便WebApplicationContext可以使用它们。比如"request", "session", "globalSession", "application",
  3、注册WEB应用特定的Environment bean到bean工厂中,以便WebApplicationContext可以使用它们。如:"contextParameters", "contextAttributes"
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
       PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());//主要是在这里面调用了所有的BeanFactoryPostProcessor
       if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
          beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
          beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
       }
    }
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
       PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
    ..
    //初始化MessageSource接口的一个实现类。这个接口提供了消息处理功能。主要用于国际化/i18n。
    protected void initMessageSource() {
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
          this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
          // Make MessageSource aware of parent MessageSource.
          if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
             HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
             if (hms.getParentMessageSource() == null) {
       // Only set parent context as parent MessageSource if no parent MessageSource registered already.
                hms.setParentMessageSource(getInternalParentMessageSource());
             }
          }
       } else {
          // Use empty MessageSource to be able to accept getMessage calls.
          DelegatingMessageSource dms = new DelegatingMessageSource();
          dms.setParentMessageSource(getInternalParentMessageSource());
          this.messageSource = dms;
          beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); 
       }
    }
    ..
    //为这个context初始化一个事件广播器(ApplicationEventMulticaster)。
    protected void initApplicationEventMulticaster() {
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {//’applicationEventMulticaster’ 检查是否给context配了一个ApplicationEventMulticaster实现类
          this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); 
       }
       else {//如果没有,就是用默认的实现类 SimpleApplicationEventMulticaster
          this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
          beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); 
       }
    }
    ..
    protected void onRefresh() throws BeansException {  // 子类实现.在AbstractApplicationContext的子类中初始化其他特殊的bean。其实就是初始化ThemeSource接口的实例。这个方法需要在所有单例bean初始化之前调用。
       // For subclasses: do nothing by default.
    }
    protected void registerListeners() {//注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的。这不会影响到其它监听器bean。在注册完以后,还会将其前期的事件发布给相匹配的监听器。
       // Register statically specified listeners first.
       for (ApplicationListener<?> listener : getApplicationListeners()) {
          getApplicationEventMulticaster().addApplicationListener(listener);
       }
       // Do not initialize FactoryBeans here: We need to leave all regular beans
       // uninitialized to let post-processors apply to them!
       String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
       for (String listenerBeanName : listenerBeanNames) {
          getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
       }
       // Publish early application events now that we finally have a multicaster... 至此,已经完成将监听器注册到ApplicationEventMulticaster中,下面将发布前期的事件给监听器。
       Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
       this.earlyApplicationEvents = null;
       if (earlyEventsToProcess != null) {
          for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
             getApplicationEventMulticaster().multicastEvent(earlyEvent);
          }
       }
    }
    //完成bean工厂的初始化工作。这一步非常复杂,也非常重要,涉及到了bean的创建。第二步中只是完成了BeanDefinition的定义、解析、处理、注册。但是还没有初始化bean实例。这一步将初始化所有非懒加载的单例bean。这一步将会重新在一篇新的笔记中介绍。
    //对配置了lazy-init属性的Bean进行预实例化处理
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
       // Initialize conversion service for this context. 为容器指定一个转换服务(ConversionService)  在对某些Bean属性进行转换时使用  
       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));
       }
       // 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(new StringValueResolver() {
             @Override
             public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
             }
          });
       }
       // 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);
       }
       // Stop using the temporary ClassLoader for type matching. //为了类型匹配,停止使用临时的类加载器  
       beanFactory.setTempClassLoader(null);
       // Allow for caching all bean definition metadata, not expecting further changes. /缓存容器中所有注册的BeanDefinition元数据,以防被修改
       beanFactory.freezeConfiguration();
       // Instantiate all remaining (non-lazy-init) singletons. //对配置了lazy-init属性的单态模式Bean进行预实例化处理
       beanFactory.preInstantiateSingletons();//DefaultListableBeanFactory对配置lazy-init属性的单例bean预实例化
    }
    ...
    //完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)
    protected void finishRefresh() {
       // Initialize lifecycle processor for this context.
       initLifecycleProcessor();
       // Propagate refresh to lifecycle processor first.
       getLifecycleProcessor().onRefresh();
       // Publish the final event.
       publishEvent(new ContextRefreshedEvent(this));
       // Participate in LiveBeansView MBean, if active.
       LiveBeansView.registerApplicationContext(this);
    }
    ...
    protected void resetCommonCaches() {
       ReflectionUtils.clearCache();
       ResolvableType.clearCache();
       CachedIntrospectionResults.clearClassLoader(getClassLoader());
    }

每天提高一点点

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!