一、BeanFactory 及 容器继承体系
- 基础概念回顾
- BeanFactory 是容器的顶级接口,它定义了容器的基础行为
- ApplicationContext 是容器的高级接口,字面意思就是 Spring 应用上下文,官方称之为 IOC 容器
- 错误的认识:容器就是 map 而已
- 正确的认识:map 是 IOC 容器的一个成员,叫做单例池(singletonObjects),容器是一组组件和过程的集合,包括 BeanFactory ,单例池,BeanPostProcessor 等以及之间的协作流程
-
BeanFactory 容器继承体系
通过其接口设计,我们可以看到我们⼀贯使用的 ApplicationContext 除了继承 BeanFactory 的子接口,还继承了 ResourceLoader(加载资源)、MessageSource(国际化) 等接口,因此其提供的功能也就更丰富了
二、容器初始化流程
Bean 生命周期关键时机点:都在 AbstractApplicationContext 类中的 refresh 方法中
关键点 | 触发代码 |
---|---|
构造器 | finishBeanFactoryInitialization(beanFactory) |
BeanFactoryPostProcessor 初始化 | invokeBeanFactoryPostProcessors(beanFactory) |
BeanFactoryPostProcessor 方法调用 | invokeBeanFactoryPostProcessors(beanFactory) |
BeanPostProcessor 初始化 | registerBeanPostProcessors(beanFactory) |
BeanPostProcessor 方法调用 | finishBeanFactoryInitialization(beanFactory) |
- refresh 方法
@Override public void refresh() throws BeansException, IllegalStateException { /* * 对象加锁 * 目的:在容器 启动、刷新、关闭 的时候不能同时执行 refresh 操作 */ synchronized (this.startupShutdownMonitor) { /* * 刷新前的预处理 * 表示在真正做 refresh 操作之前需要准备做的事情: * 1. 设置 Spring 容器的启动时间 * 2. 开启活跃状态,撤销关闭状态 * 3. 验证环境信息里一些必须存在的属性等 */ prepareRefresh(); /* * 获取 BeanFactory,默认实现是 DefaultListableBeanFactory * 加载 BeanDefinition 并注册到 BeanDefinitionRegistry */ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // BeanFactory 的预准备工作(BeanFactory 进行一些设置,比如 context 的类加载器等) prepareBeanFactory(beanFactory); try { // BeanFactory 准备工作完成后进行的后置处理工作 postProcessBeanFactory(beanFactory); // 实例化实现了 BeanFactoryPostProcessor 接口的 Bean,并调用接口方法 invokeBeanFactoryPostProcessors(beanFactory); // 注册 BeanPostProcessor(Bean 的后置处理器),在创建 Bean 的前后等执行 registerBeanPostProcessors(beanFactory); // 初始化 MessageSource 组件(做国际化功能,消息绑定,消息解析) initMessageSource(); // 初始化事件派发器 initApplicationEventMulticaster(); /* * 子类重写这个方法,在容器刷新的时候可以自定义逻辑 * 如:创建 tomcat,jetty 等 web 服务器 */ onRefresh(); // 注册应用的监听器,就是注册实现了 ApplicationListener 接口的监听器 bean registerListeners(); /* * 1.初始化所有剩下的非懒加载的单例 bean * 2.初始化创建非懒加载方式的单例 bean 实例(未设置属性) * 3.填充属性 * 4.初始化方法调用(比如调用 afterPropertiesSet 方法、init-method 方法) * 5.调用 BeanPostProcessor(后置处理器)对实例 bean 进行后置处理 */ finishBeanFactoryInitialization(beanFactory); /* * 完成 context 的刷新 * 主要是调用 LifecycleProcessor 的 onRefresh() 方法 * 并且发布事件(ContextRefreshedEvent) */ 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(); } } }
- 获取 beanFactory 流程
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory(); }
@Override protected final void refreshBeanFactory() throws BeansException { // 判断是否已有 beanFactory if (hasBeanFactory()) { // 销毁 beans destroyBeans(); // 关闭 beanFactory closeBeanFactory(); } try { // 实例化 DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); // 设置序列化id beanFactory.setSerializationId(getId()); // 自定义bean工厂的一些属性(是否覆盖、是否允许循环依赖) customizeBeanFactory(beanFactory); // 加载应用中的BeanDefinitions loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { // 赋值当前beanFactory this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
- BeanDefinition加载注册流程
所谓的注册就是把封装的 XML 中定义的 Bean信息封装为 BeanDefinition 对象之后放入⼀个Map中,BeanFactory 是以 Map 的结构组织这些 BeanDefinition的
loadBeanDefinitions(beanFactory);
@Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // 给指定的beanFactory创建一个XmlBeanDefinitionReader读取器对象,用于读取解析xml对象 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // 给XmlBeanDefinitionReader对象设置一些context上下文中的环境属性 beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // 提供给子类实现提供一些自定义的初始化策略 initBeanDefinitionReader(beanDefinitionReader); // 真正的去加载BeanDefinitions loadBeanDefinitions(beanDefinitionReader); }
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { // 从Resource资源对象加载BeanDefinitions Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } // 从xml配置文件加载BeanDefinition对象 String[] configLocations = getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); } }
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException { Assert.notNull(locations, "Location array must not be null"); int count = 0; // 如果有多个配置文件,循环读取加载,并统计总共加载了多少个BeanDefinition for (String location : locations) { count += loadBeanDefinitions(location); } return count; }
public int loadBeanDefinitions(String location, @Nullable Set
actualResources) throws BeanDefinitionStoreException { // 获取上下文的资源加载器 ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException( "Cannot load bean definitions from location [" + location + "]: no ResourceLoader available"); } // 判断资源加载器是否ResourcePatternResolver类型(xml、url等不同类型统一接口为匹配类型) if (resourceLoader instanceof ResourcePatternResolver) { try { // 统一加载转换为Resource资源对象 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); // 加载资源中配置的BeanDefinition对象,并返回数量 int count = loadBeanDefinitions(resources); // ...... } // ...... } // ...... } public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int count = 0; for (Resource resource : resources) { count += loadBeanDefinitions(resource); } return count; }
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { // ...... try { // 从资源对象中获取流信息 InputStream inputStream = encodedResource.getResource().getInputStream(); try { // 把xml文件流封装为InputSource对象 InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } // do!执行加载逻辑 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } // ...... } //...... }
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { // 读取xml信息,将xml中信息保存到Document对象 Document doc = doLoadDocument(inputSource, resource); // 解析Document对象,封装BeanDefinition对象并进行注册 int count = registerBeanDefinitions(doc, resource); //...... } //...... }
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); //获取已有BeanDefinition的数量 int countBefore = getRegistry().getBeanDefinitionCount(); //注册BeanDefinition documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); //返回新注册的BeanDefinition数量 return getRegistry().getBeanDefinitionCount() - countBefore; }
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; doRegisterBeanDefinitions(doc.getDocumentElement()); }
protected void doRegisterBeanDefinitions(Element root) { //...... preProcessXml(root);//供子类实现的方法 parseBeanDefinitions(root, this.delegate); postProcessXml(root);//供子类实现的方法 this.delegate = parent; }
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { //解析默认标签元素 parseDefaultElement(ele, delegate); } else { //解析自定义标签元素 delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { //import元素处理 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } //alias元素处理 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } //bean元素处理 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } //嵌套beans处理 else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //解析bean元素为BeanDefinition,但是此时使用BeanDefinitionHolder又包装成了BeanDefinitionHolder对象 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { //如果有自定义标签,则处理自定义标签 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { //完成BeanDefinition的注册 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } //...... }
public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); //...... }
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { //...... BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { //...... } else { if (hasBeanCreationStarted()) { //...... } else { // 注册beanDefinition到beanDefinitionMap中 this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } //...... }
- Bean对象创建流程
finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //...... // 实例化所有 非懒加载 的单例Bean beanFactory.preInstantiateSingletons(); }
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // 所有Bean的名字 List
beanNames = new ArrayList<>(this.beanDefinitionNames); // 触发所有非延迟加载的单例Bean的初始化,主要步骤为getBean for (String beanName : beanNames) { //合并父BeanDefinition对象 //map.get(beanName) RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //只实例化非抽象方法并且是单例并且是非懒加载的Bean if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { //如果是一个FactoryBean,那么实例化的时候会在beanName前面加一个"&"的前缀 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //...... } else { //实例化当前bean getBean(beanName); } } } //...... } @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
protected
T doGetBean(final String name, @Nullable final Class requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { /* * 解析beanName * 1.如果以"&"开头,去掉"&" * 2.如果是别名,获取到真正的名字 */ final String beanName = transformedBeanName(name); Object bean; //单纯理解尝试从缓存中获取bean Object sharedInstance = getSingleton(beanName); //如果已经存在则返回 if (sharedInstance != null && args == null) { //...... //针对FactoryBean的处理 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { //如果是prototype类型且开启允许循环依赖,则抛出异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 检查父工厂中是否存在该对象 BeanFactory parentBeanFactory = getParentBeanFactory(); //...... try { //合并父子Bean属性 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 处理dependsOn配置 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); } } } // 创建单例bean if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { //创建bean return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //...... } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } //...... } public Object getSingleton(String beanName, ObjectFactory> singletonFactory) { Assert.notNull(beanName, "Bean name 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 + "'"); } //验证完要真正开始创建对象,先标识该bean正在被创建,因为SpringBean创建过程复杂,步骤很多,需要标识 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //传进来的调用,lambda表达式使用 singletonObject = singletonFactory.getObject(); newSingleton = true; } //...... } return singletonObject; } }
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } //将beanDefinition转换成了RootBeanDefinition RootBeanDefinition mbdToUse = mbd; //获得类信息 Class> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } //...... try { //进入真真正正创建bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //创建bean实例,仅仅调用构造方法,但是尚未设置属性 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { 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. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { //Bean属性填充 populateBean(beanName, mbd, instanceWrapper); //调用初始化方法,应用BeanPostProcessor后置处理器 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
actualDependentBeans = new LinkedHashSet<>(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."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
三、lazy-init 延迟加载机制原理
- lazy-init 延迟加载机制分析
- 普通 Bean 的初始化是在容器启动初始化阶段执行的
- 被
lazy-init=true
修饰的 bean 是在从容器里第⼀次进行context.getBean()
时进行触发 - Spring 启动的时候会把所有bean信息(包括XML和注解)解
析转化成Spring能够识别的BeanDefinition并存到Hashmap里供下面的初始化时用,然后对每个BeanDefinition 进行处理,如果是懒加载的则在容器初始化阶段不处理,其他的则在容器初始化阶段进行初始化并依赖注入