【深入学习Spring】3——Spring容器启动过程分析
一、DefaultListableBeanFactory的使用
我们使用IOC容器通常会使用比较高级的ApplicationContext,而非较低层的BeanFactory。但对于那些不需要使用ApplicationContext中高级功能的场景,我们可以选择使用低层的BeanFactory。上一节中提到过Spring提供了BeanFactory的默认实现类DefaultListableBeanFactory,通常会结合XmlBeanDefinitionReader一起使用。
public static void test() { ClassPathResource resource = new ClassPathResource("classpath:bean.xml"); DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); //加载Bean定义 reader.loadBeanDefinitions(resource); //获取Bean User user = (User) factory.getBean("user"); System.out.println(user.getName()); }
跟踪一下上面loadBeanDefinitions()方法的调用,得到如下调用链。
XmlBeanDefinitionReader#loadBeanDefinitions() -->loadBeanDefinitions()重载 -->doLoadBeanDefinitions() -->registerBeanDefinitions -->BeanDefinitionDocumentReader#registerBeanDefinitions() #注册Bean定义 默认实现DefaultBeanDefinitionDocumentReader#registerBeanDefinitions() -->doRegisterBeanDefinitions() -->parseBeanDefinitions() #解析Bean定义 ……
上面过程主要分为注册BeanDefinition和解析BeanDefinition两个步骤:
Resource资源的定位
BeanDefinition的加载
BeanDefinition的注册
将BeanDefinition注册到IOC容器中。这个过程通过调用BeanDefinitionRegistry接口实现类来完成。
(这一部分待完成)
二、ApplicationContext容器启动过程
我们先来看看常用的两种ApplicationContext实现:ClassPathXmlApplicationContext和AnnotationConfigApplicationContext,其构造方法调用代码如下。
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); //设置xml配置文件位置。此时并未解析和加载配置文件中的Bean setConfigLocations(configLocations); if (refresh) { refresh(); } } public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); //注册配置类(配置类也是一个Bean)。此时并未解析和注册配置类中配置的Bean register(annotatedClasses); refresh(); }
上面的xml形式,由于Bean存在于xml配置文件中,所以需要先确定配置文件的位置(setConfigLocations),最终将该位置保存在configLocations数组中(因为可能有多个配置)。
下面的注解形式,由于Bean存在于注解配置类中,所以需要先确定注解配置类的位置和其它信息(如scope等),最后将该注解类相关信息保存在beanDefinitionMap中,spring将其称为注册,该配置类本身也是一个Bean,这里只注册了该配置Bean,在后续过程中会解析配置类中的Bean并进行注册。(beanDefinitionMap属性在defaultListableBeanFactory中声明。AnnotationConfigApplicationContext从GenericApplicationContext继承了registerBeanDefinition()方法,而该方法又委托底层默认容器DefaultListableBeanFactory的registerBeanDefinition()方法将注解类的信息保存到默认容器的beanDefinitionMap属性中。)
之后,两者的过程都是一样了,也就是最最重要的refresh()方法。该方法是定义在AbstractApplicationContext类中的模板方法,其定义了容器启动的基本流程,并预留了一些钩子方法供子类进行扩展。
//AbstractApplicationContext public void refresh() throws BeansException, IllegalStateException { // synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // 准备刷新。准备上下文 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 告诉子类刷新内部BeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 准备使用BeanFactory prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 执行上下文子类中BeanFactory的后置处理器 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. //调用BeanFactory的后置处理器(这些后置处理器是在Bean的定义中向容器注册的) invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. //为Bean注册后置处理器(Bean创建后就会调用) registerBeanPostProcessors(beanFactory); // Initialize message source for this context. //初始化消息源(国际化信息) initMessageSource(); // Initialize event multicaster for this context. //初始化消息广播, initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. //初始化其它特殊Bean(子类实现)。SpringBoot核心基类EmbeddedWebApplicationContext就是实现该方法来初始化容器的 onRefresh(); // Check for listener beans and register them. //注册监听器 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //将所有非延迟加载的Bean初始化,并设置冻结标识,以防止不必要的重新实例化 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. //注册、启动LifeCycleProcessor,并且发送启动完成事件 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(); } } }
ApplicationContext容器启动流程图
根据上面的代码逻辑,可以绘制出如下的ApplicationContext启动流程图。
其中registerBeanPostProcessors和finishBeanFactoryInitialization这两个步骤需要重点关注一下。registerBeanPostProcessors流程如下,而finishBeanFactoryInitialization在后文中有详细解析。
下面依次来看每一个步骤。
2.1 prepareRefresh
/** * Prepare this context for refreshing, setting its startup date and * active flag as well as performing any initialization of property sources. * 准备上下文刷新,记录启动时间和激活标识,还有属性源的初始化。 */ protected void prepareRefresh() { // Switch to active. //将相关标识切换到激活状态 this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // Initialize any placeholder property sources in the context environment. // (子类实现)初始化上下文环境中的placeholder属性。默认空实现。 initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties // 校验属性 getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... // 用于早期ApplicationEvents的收集,一旦multicaster广播器可用,将会广播这些事件。 this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); }
2.2 obtainFreshBeanFactory
/** * Tell the subclass to refresh the internal bean factory. */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); //这里返回的是底层容器DefaultListableBeanFactory实例 ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
2.3 prepareBeanFactory
/** * Configure the factory's standard context characteristics,such as the context's ClassLoader and post-processors. */ protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. //告诉内部BeanFactory使用上下文类加载器 beanFactory.setBeanClassLoader(getClassLoader()); //设置bean表达式(spel)解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. //将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,从而在Aware接口实现类中的注入applicationContext 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. //如果当前BeanFactory包含loadTimeWeaver Bean,说明存在类加载期织入AspectJ,则把当前BeanFactory交给类加载期BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理,从而实现类加载期织入AspectJ的目的。 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. //注册当前容器环境environment组件Bean if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } //注册系统配置systemProperties组件Bean if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } //注册系统环境systemEnvironment组件Bean if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
2.4 postProcessBeanFactory
/** * 在内部BeanFactory进行标准初始化之后,修改应用上下文。所有的Bean定义都会被加载,但都还未被初始化。 * 这考虑到的是为某种ApplicationContext实现版本中用来注册特殊的Bean后置处理器 */ protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }
2.5 invokeBeanFactoryPostProcessors
/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans,respecting explicit order if given. * <p>Must be called before singleton instantiation. * 实例化并调用所有已注册的BeanFactoryPostProcessor(它们也都是Bean),遵循显式的顺序(如果给定了的话)。必须在单例实例化之前调用。 */ 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())); } }
2.6 registerBeanPostProcessors
/** * 实例化并注册所有BeanPostProcessor(它们也都是Bean),遵循显式的顺序(如果给定了的话)。必须在所有应用Bean实例化之前调用。 */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); } public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>(); List<String> orderedPostProcessorNames = new ArrayList<String>(); List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, register the BeanPostProcessors that implement PriorityOrdered. //首先,注册实现了PriorityOrdered接口的BanPostProcessors sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. //然后,注册实现了Ordered接口的BanPostProcessors List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. //注册所有常规的BeanPostProcessors List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. //最后,重新注册所有内部BeanPostProcessors sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). //重新注册后置处理器作为应用监听器,用于监听内部Bean。移动到处理器链的尾部 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
2.7 initMessageSource
/** * Initialize the MessageSource. * Use parent's if none defined in this context. * 初始化MessageSource。如果上下文中未定义,则使用父级的。 */ protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //如果已经配置了MessageSource,则从容器中直接获取使用。 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()); } } if (logger.isDebugEnabled()) { logger.debug("Using MessageSource [" + this.messageSource + "]"); } } 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); if (logger.isDebugEnabled()) { logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME + "': using default [" + this.messageSource + "]"); } } }
2.8 initApplicationEventMulticaster
/** * Initialize the ApplicationEventMulticaster. * Uses SimpleApplicationEventMulticaster if none defined in the context. * 初始化事件广播器。如果没有定义,则创建一个impleApplicationEventMulticaster */ protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //容器中定义了事件广播器,则直接从容器中获取使用。 if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } //否则,创建一个impleApplicationEventMulticaster else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } }
2.9 onRefresh
/** * Template method which can be overridden to add context-specific refresh work. * Called on initialization of special beans, before instantiation of singletons. * <p>This implementation is empty. */ protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. }
模板方法,在子类中实现该方法用于子类上下文相关的刷新操作。默认是空实现。
2.10 registerListeners
/** * Add beans that implement ApplicationListener as listeners. * Doesn't affect other listeners, which can be added without being beans. */ protected void registerListeners() { // 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... Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
2.11 finishBeanFactoryInitialization
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. * 完成当前上下文BeanFactory的初始化。初始化所有剩余的单例bean。 */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. // 初始化类型转换服务(比如string转date类型,实现Converter接口的服务类) 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. //如果之前没有bean后置处理器(例如PropertyPlaceholderConfigurer)被注册,则注册一个默认内置的值解析器:此时,主要用于注释属性值的解析 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. //初始化LoadTimeWeaverAware(用于动态转换类) 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. //冻结所有bean的定义,不期望再进行修改。(设置configurationFrozen = true,将所有注册的bean名称到frozenBeanDefinitionNames中) beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. //【重点】实例化所有剩余(非懒加载)单例 beanFactory.preInstantiateSingletons(); }
完成BeanFactory的初始化工作。包括ConversionService的设置、注册默认的内置值解析器、初始化LoadTimeWeaverAware、停用用于类型匹配的临时类加载器、配置冻结、以及实例化所有非懒加载的单例。最后一步实例化非懒加载的单例Bean在文章后面会重点进行分析。
2.12 finishRefresh
/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the{@link org.springframework.context.event.ContextRefreshedEvent}. * 完成上下文的刷新,调用生命周期处理器的onRefresh()方法,并发布ContextRefreshEvent事件 */ 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); }
Spring提供了Lifecycle接口,该接口中包含了start和stop方法。实现了Lifecycle接口后,Spring会保证在启动时调用其start方法开始生命周期,并在关闭时调用stop方法来结束生命周期。通常用于配置后台程序,启动后一直会运行。
2.13 resetCommonCaches
/** * Reset Spring's common core caches, in particular the ReflectionUtils,ResolvableType and CachedIntrospectionResults caches. */ protected void resetCommonCaches() { ReflectionUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader()); }
清除创建单例Bean过程中的一些缓存。如反射时的缓存,解析Bean过程中的缓存等。因为单例Bean一旦创建,就不用再次创建了,缓存信息也就不再需要了。
三、(非懒加载)Bean的创建流程分析
容器启动阶段,仅非懒加载的bean才会创建。我们继续追踪上面refresh步骤中的倒数第二步finishBeanFactoryInitialization()
refresh()
-->finishBeanFactoryInitialization()
-->beanFactory.preInstantiateSingletons()
-->DefaultListableBeanFactory#preInstantiateSingletons()
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isDebugEnabled()) { logger.debug("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... // 触发非lazy-init的单例Bean的初始化 for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 如果是FactoryBean if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { @Override public Boolean run() { return ((SmartFactoryBean<?>) factory).isEagerInit(); } }, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } //非FactoryBean(普通Bean) else { getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... // 所有单例Bean创建后,依次触发后置处理 for (String beanName : beanNames) { //此时由于所有单例都已经创建并初始化好了,且被缓存在SingletonObjects中,所以直接(通过一级缓存)就能获取到 Object singletonInstance = getSingleton(beanName); //SmartInitalizingSingleton接口用于在所有(非懒加载的)单例创建后的回调 if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { smartSingleton.afterSingletonsInstantiated(); return null; } }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
继续往下追踪其中的getBean方法:
getBean-->AbstractBeanFactory#getBean-->doGetBean
@SuppressWarnings("unchecked") protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 1.三级缓存方式获取Bean Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } //返回bean实例,或者如果是FactoryBean则进行一些额外处理 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } //通过三级缓存方式未获取到Bean,或者args==null else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. //如果已经创建了Bean实例,则失败:我们很可能正处于循环引用中 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 检查工厂中是否存在Bean的定义 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (args != null) { // Delegation to parent with explicit args. // 带参 -> 委派给父类带参的getBean return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. // 无参 -> 委派给标准的getBean return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 保证使用depends-on属性(xml形式)或@DepdensOn依赖的Bean初始化 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // 2.Create bean instance.创建Bean实例 if (mbd.isSingleton()) { //创建单例Bean sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) {// 创建多例Bean // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { //创建其它scope类型的Bean(scope类型除了singleton和prototype,还有request、session、global session作用域) String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. // 检查所需的类型是否与真实Bean实例类型相匹配 if (requiredType != null && bean != null && !requiredType.isInstance(bean)) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
大体上获取Bean的过程就是
- 如果能从容器中获取到就返回(getSingleton)
- 如果获取不到就创建(createBean)
3.1 getSingleton
首先从容器中获取Bean,代码如下。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<Exception>(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } }
上面代码逻辑可以转换为以下流程图:
存在以下三个存储位置,网上有博客称为三级缓存。获取Bean时,会依次按照singletonObjects-->earlySingletonObjects-->singletonFactories先后顺序获取。
- singletonObjects:用于存放完全创建完成的bean(完成了实例化,属性填充,和初始化)
- earlySingletonObjects:提前暴露的单例缓存,存放原生(raw) bean对象(尚未填充属性,和初始化),用于解决循环依赖
- singletonFactories:存放bean工厂对象,从该工厂可以获取原始对象的引用,也就是“早期引用”。
由于singletonObjects是缓存完全初始化好的Bean的,所以,直接从中获取到 的Bean是可以直接使用的。如果从中获取不到,则从earlySingletonObjects获取未初始化完全的单例,之后的流程中会再经过属性赋值,最终也会成为一个完整的Bean。要是前两个过程都无法获取到Bean,则再由单例工厂Bean来获取了,获取到的Bean是原生(raw) Bean。将其移入earlySingletonObjects缓存中,便于需要时直接获取,而此时singletonFactories缓存也就不再需要了,直接从中清除工厂对象,也就是将三级缓存提升为二级缓存。
3.2 createBean
如果getBean未获取到Bean说明容器中不存在,也就只能让容器来创建Bean了,代码如下。
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } // 这里才是真正的创建Bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
createBean-->doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //1.创建实例(返回的是包装类型) instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. //判断singletonsCurrentlyInCreation中是否有beanName,有则表明单例正在创建中 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } //缓存单例工厂,该工厂用于创建指定的单例 addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { //2.为Bean的属性赋值 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //3.初始化Bean exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // 4.注册销毁方法 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
由于篇幅原因,这里我没有花太多语言来介绍上面整个创建过程。而是将其放到了Spring源码系列4 - Bean的生命周期中。
另外,我将创建Bean的整个过程绘制成了详细的流程图,对照流程图来理解代码会更轻松一些。
finishBeanFactoryInitialization的完整流程图
图一:
图二:
图三:
三、Spring如何解决循环依赖?
①基于构造器的循环依赖
基于构造器的循环依赖是无解的,会直接抛出BeanCurrentlyInCreationException异常,表示循环依赖。
<!--基于构造器的循环依赖--> <bean id="beanA" class="com.lp.test.recycledependency.constructor.A"> <constructor-arg ref="beanB"/> </bean> <bean id="beanB" class="com.lp.test.recycledependency.constructor.B"> <constructor-arg ref="beanA"/> </bean>
②基于setter的循环依赖
基于setter注入方式的循环依赖,是通过Spring容器将刚完成构造器注入,但尚未完成其它步骤(属性赋值)的bean提前暴露来完成的,而且只能解决单例作用域的bean循环依赖。
<!--基于setter的循环依赖--> <bean id="beanC" class="com.lp.test.recycledependency.setter.C"> <property name="d" ref="beanD"/> </bean> <bean id="beanD" class="com.lp.test.recycledependency.setter.D"> <property name="c" ref="beanC"/> </bean>
假如 beanC 和 beanD 相互依赖,beanC为C类型,beanD为D类型,beanC中存在一个D类型的属性d ,beanD中存在一个C类型的属性c。
①假设首先实例化beanC,在完成beanC的实例化后,此时beanC实例中的所有属性还未被赋值,都为null,当前beanC称为原始Bean。
beanC创建完后,会将自己提前暴露出来(加入到了三级缓存中)。
②接下来为beanC中的属性赋值,经过解析依赖,发现beanC依赖beanD。
③于是会先去实例化beanD,也同样会再经过解析依赖的过程,会检测发现依赖beanC,此时会通过(隐式的)getBean从容器中获取beanC。
由于beanC已经添加到缓存中,通过ObjectFactory提前暴露,通过ObjectFactory#getObject()即可获取到beanC。容器获取 beanC 对象的一个早期的引用(early reference),并把这个早期引用注入到 beanD 中,让 beanD 先完成初始化。beanD 完成初始化后,beanC 就可以获取到 beanD 的完整引用,beanC也就随之完成初始化。
下图就是解决循环依赖的流程图。注意图中标出的①②③这三处缓存的变化。
①处是Bean刚创建完后,将创建该Bean的工厂加入到三级缓存。
②处是在解决依赖时,通过一级缓存取出工厂创建Bean,然后将Bean加入到二级缓存中,同时删除了三级缓存(相当于三级缓存升级为二级缓存)。
③处是在Bean完成初始化后成为一个完整的Bean时,将该Bean加入到一级缓存,并同时清理二级缓存和三级缓存(相当于二级缓存升级为一级缓存)。
四、总结
1.Spring容器的启动流程
2.Spring能解决哪种情况的循环依赖?
只能解决基于setter方式的循环依赖,不能解决基于构造器注入循环依赖,和多例(prototype)的循环依赖。
3.Spring是如何解决循环依赖的?理解其中的三级缓存!
4.Spring为什么不能解决构造器的循环依赖?
Bean在调用构造器进行实例化的过程中,并不会用到三级缓存,只是在实例化之后才放入三级缓存中。所以只能抛出循环依赖的异常了。
5.为什么多实例Bean不能解决循环依赖?
多实例Bean是每次创建都会调用doGetBean方法,根本没有使用一二三级缓存,也就不能解决循环依赖。
参考: