前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【SpringIOC容器初始化(一)】

【SpringIOC容器初始化(一)】

作者头像
用户5640963
发布2020-03-19 09:48:53
4040
发布2020-03-19 09:48:53
举报
文章被收录于专栏:卯金刀GG卯金刀GG

【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()); }

每天提高一点点

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档