0
点赞
收藏
分享

微信扫一扫

Java NIO2详解:异步文件和网络编程

火热如冰 2024-07-01 阅读 28

文章目录

一、前言

无论你是一个经验丰富的Java-er,还是一个Java初学者,都会听过Spring框架的大名,我在初学这个Spring框架的时候都是对这个框架当成一个工具使用,只知道这样做能够达到这样的效果,但是具体里面是怎么实现的也说不清楚,不过随着现在技术的越来越卷,我感觉有必要揭开Spring框架的内幕,深度学习领悟这一优秀的框架了!

本文是针对Spring框架中的IOC核心功能进行源码解读的,准备好的话,那就一起出发喽


二、前置准备

本文会对Spring框架的IOC源码进行解读,推荐各位去GitHub下载一份Spring源码配合本篇文章食用更佳!

本文是针对Spring 4.0.0 的源码而编写的,不同版本源码会有差异,但整体业务逻辑不变。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.0.0.RELEASE</version>
</dependency>

三、IOC容器的使用

首先,咱们先来复习一下Spring IOC容器的使用。

public interface UserService {

    String selectList();

}
public class UserServiceImpl implements UserService {
    @Override
    public String selectList() {
        return "小明, 小红, 小蓝";
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="messageService" class="spring.ioc.UserServiceImpl"/>
    
</beans>
public class SpringTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

        System.out.println("context 启动成功");

        UserService userService = context.getBean(UserService.class);

        System.out.println(userService.selectList());

    }
}

image-20240623201246675

Spring IOC的使用中,很直观就能感受到的就是Spring IOC代替我们程序缘完成了对一个对象的new

把创建实例的工作交给了Spring IOC,可以简化不少程序员的工作。


四、Spring IOC源码解读

对于Spring IOC的源码,我认为必须带着“Bean存储在哪?什么时候被实例化?怎么获取的?”这三个问题去阅读!

还是从上面的Demo代码入手阅读。

public class SpringTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

        System.out.println("context 启动成功");

        UserService userService = context.getBean(UserService.class);

        System.out.println(userService.selectList());

    }
}

在这个Demo代码中,干了三件事:

  1. 使用application.xml 配置文件作为构造参数,创建了一个Spring容器
  2. Spring容器中获取UserService实例
  3. 调用UserService实例的方法

针对这三步,我合理猜测Spring容器创建的时候就完成了Spring Bean的注入。

接下来进入ApplicationContext context = new ClassPathXmlApplicationContext("application.xml") 源码查看是不是这样子的。

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
    
    public ClassPathXmlApplicationContext(String configLocation) throws BeansException 	{
        this(new String[] {configLocation}, true, null);
	}
    
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {

        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

}

这里干了三件事:

  1. 调用了父类ApplicationContext的构造函数,并将parent参数传递给它
  2. 调用setConfigLocations方法,将传入的配置文件路径设置到当前的ClassPathXmlApplicationContext实例中
  3. 如果refreshtrue,则调用refresh方法。这个方法会触发Spring容器的刷新过程,重新加载所有的bean定义

其他都不重要,重要的是refresh()方法,这个方法会触发Spring容器的刷新,加载Bean的定义。

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
       // Prepare this context for refreshing.
       prepareRefresh();

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

       // Prepare the bean factory for use in this context.
       prepareBeanFactory(beanFactory);

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

          // Invoke factory processors registered as beans in the context.
          invokeBeanFactoryPostProcessors(beanFactory);

          // Register bean processors that intercept bean creation.
          registerBeanPostProcessors(beanFactory);

          // Initialize message source for this context.
          initMessageSource();

          // Initialize event multicaster for this context.
          initApplicationEventMulticaster();

          // Initialize other special beans in specific context subclasses.
          onRefresh();

          // Check for listener beans and register them.
          registerListeners();

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

          // Last step: publish corresponding event.
          finishRefresh();
       }

       catch (BeansException ex) {
          // Destroy already created singletons to avoid dangling resources.
          destroyBeans();

          // Reset 'active' flag.
          cancelRefresh(ex);

          // Propagate exception to caller.
          throw ex;
       }
    }
}

下面会针对refresh()的每一步进行解析!


1. prepareRefresh源码解读

prepareRefresh方法主要是进行Spring容器刷新前的一些准备工作,并不主要特别关注!

protected void prepareRefresh() {
    // 记录Spring容器开始刷新的时间
    this.startupDate = System.currentTimeMillis();
	
    // 标志Spring容器刷新工作开始
    synchronized (this.activeMonitor) {
       this.active = true;
    }

    if (logger.isInfoEnabled()) {
       logger.info("Refreshing " + this);
    }

    // 初始化上下文中的占位符属性源
    initPropertySources();

	// 调用getEnvironment方法获取环境对象,并调用其validateRequiredProperties方法来验证必需的属性
    getEnvironment().validateRequiredProperties();
}

2. obtainFreshBeanFactory源码解读

obtainFreshBeanFactory的作用是刷新内部Bean工厂返回一个新的BeanFactory实例。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
       logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

2.1 refreshBeanFactory源码解读

refreshBeanFactory 是解析application.xml配置文件并生成BeanDefinition注册到Spring IOC中去,具体怎么操作,请看下面org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory源码解读

protected final void refreshBeanFactory() throws BeansException {
    // 如果BeanFactory已经存在,先销毁原来的BeanFactory
    if (hasBeanFactory()) {
       destroyBeans();
       closeBeanFactory();
    }
    try {
       // 创建一个DefaultListableBeanFactory
       DefaultListableBeanFactory beanFactory = createBeanFactory();
       beanFactory.setSerializationId(getId());
       // 设置bean是否允许覆盖 是否允许循环依赖
       customizeBeanFactory(beanFactory);
       // 加载BeanDefinition
       loadBeanDefinitions(beanFactory);
       synchronized (this.beanFactoryMonitor) {
          this.beanFactory = beanFactory;
       }
    }
    catch (IOException ex) {
       throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)源码如下

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 将读取XML操作交付给XmlBeanDefinitionReader,且生成的BeanDefinition注册进IOC中
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // 设置Spring容器
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    
    initBeanDefinitionReader(beanDefinitionReader);
    // 读取xml
    loadBeanDefinitions(beanDefinitionReader);
}

接下来,着重看loadBeanDefinitions(beanDefinitionReader),深入了解如何加载BeanDefition

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    // 获取配置资源的数组
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
       reader.loadBeanDefinitions(configResources);
    }
    // 配置位置的路径字符串数组,以加载这些路径指定的Bean定义
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
       reader.loadBeanDefinitions(configLocations);
    }
}

接着看loadBeanDefinitions

public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    int count = 0;
    for (String location : locations) {
        // 只需要关注loadBeanDefinitions这个方法
        count += loadBeanDefinitions这个方法(location);
    }
    return count;
}

org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(new EncodedResource(resource));
}

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    /** 省略部分代码  **/
    return doLoadBeanDefinitions(inputSource, encodedResource.getResource());

}

继续看org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions这里开始就是加载BeanDefinitions

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
       throws BeanDefinitionStoreException {
    // 因为配置文件是一个xml文件,因此将inputSource进行解析封装成一个Document
    Document doc = doLoadDocument(inputSource, resource);
    // 注册Bean定义
    int count = registerBeanDefinitions(doc, resource);
    return count;  
}
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    // 创建一个DocumentReader, 负责读取和解析XML文档中的Bean定义
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    // 记录加载Bean之前容器的Bean数量
    int countBefore = getRegistry().getBeanDefinitionCount();
    // 注册Bean
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    return getRegistry().getBeanDefinitionCount() - countBefore;
}

org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    // 从根元素开始遍历
    doRegisterBeanDefinitions(doc.getDocumentElement());
}

protected void doRegisterBeanDefinitions(Element root) {
    BeanDefinitionParserDelegate parent = this.delegate;
    // 创建一个新的BeanDefinitionParserDelegate对象,这个对象将用于解析XML中的bean定义
    this.delegate = createDelegate(getReaderContext(), root, parent);
	
    
    // 解析Bean定义之前执行一些预处理操作,Spring框架并没有给出实现类, 属于一种扩展点
    preProcessXml(root);
    // 重点!!加载Bean定义
    parseBeanDefinitions(root, this.delegate);
    // 解析Bean定义之后执行一些后处理操作,Spring框架也并没有给出实现类, 属于一种扩展点
    postProcessXml(root);

    this.delegate = parent;
}

org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions的作用是根据XML配置文件的标签的不同,进行不同的处理

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

/**
* 根据标签不同进行不同的操作,这里重点介绍processBeanDefinition方法
**/
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        // 加载bean
        processBeanDefinition(ele, delegate);
    }
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // recurse
        doRegisterBeanDefinitions(ele);
    }
}

org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition这个方法是将Bean定义注册进容器中

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    // 将XML元素解析成BeanDefinitionHolder对象
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        // 对Bean进行适当装饰
       bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
       try {
          // 将Bean定义注册进容器中
          BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
       }
       catch (BeanDefinitionStoreException ex) {
          getReaderContext().error("Failed to register bean definition with name '" +
                bdHolder.getBeanName() + "'", ele, ex);
       }
       // 触发注册时间
       getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

debugorg.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition方法,看看是如何进行注册的

public static void registerBeanDefinition(
       BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
       throws BeanDefinitionStoreException {

    // 获取Bean定义的名字
    String beanName = definitionHolder.getBeanName();
    // 注册Bean定义
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // 获取别名
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
       for (String alias : aliases) {
          registry.registerAlias(beanName, alias);
       }
    }
}
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
       throws BeanDefinitionStoreException {
    // 根据BeanName获取BeanDefinition
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    if (existingDefinition != null) {
       // bean已经存在 进行一些操作,感兴趣自己去看源码
    }
    else {
 		// BeanName不存在
       if (hasBeanCreationStarted()) {
          // Cannot modify startup-time collection elements anymore (for stable iteration)
          synchronized (this.beanDefinitionMap) {
             this.beanDefinitionMap.put(beanName, beanDefinition);
             List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
             updatedDefinitions.addAll(this.beanDefinitionNames);
             updatedDefinitions.add(beanName);
             this.beanDefinitionNames = updatedDefinitions;
             removeManualSingletonName(beanName);
          }
       }
       else {
          // 将beanName与beanDefinition放至beanDefinitionMap中
          this.beanDefinitionMap.put(beanName, beanDefinition);
          this.beanDefinitionNames.add(beanName);
          removeManualSingletonName(beanName);
       }
       this.frozenBeanDefinitionNames = null;
    }
}

到这里BeanDefinition的注册就基本完成了,主要是以下这些步骤:

  1. 将XML文件包装成一个Document对象
  2. 利用BeanDefinitionDocumentReader解析Document
  3. 从XML的root进行遍历,针对不同标签import、bean、beans等进行不同的处理
  4. bean标签而言,在parseBeanDefinitionElement方法中将bean标签的组装成一个BeanDefinitionHolder
  5. 调用BeanDefinitionRegistryregisterBeanDefinition进行BeanDefinition注册
  6. 检查beanName是否已经注册,如果没有注册则将该BeanDefinition注册进org.springframework.beans.factory.support.DefaultListableBeanFactory#beanDefinitionMap中去
  7. 如果存在别名,也可以进行别名注册。

3. prepareBeanFactory源码解读

prepareBeanFactory方法主要是完善beanFactory, 对其进行一些属性填充

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 配置类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    // 配置表达式解析器, 用于解析Spring表达式
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
    // 注册属性编辑注册器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 添加BeanPostProcessor, 用于处理实现了ApplicationContextAware接口的Bean
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    // 忽略特定的依赖接口
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

    // 注册可解析的依赖
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // 检查和准备AOP织入
    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()));
    }

    // 注册环境相关bean
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
       beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
       beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
       beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

4. postProcessBeanFactory源码解读

没有给出实现,交由子类去实现

image-20240625230703942


5. invokeBeanFactoryPostProcessors源码解读

invokeBeanFactoryPostProcessors的作用是调用所有注册的BeanFactoryPostProcessor实例

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

6. registerBeanPostProcessors源码解读

registerBeanPostProcessors的作用是实例化BeanPostProcessor

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

7. initMessageSource源码解析

initMessageSource方法主要是为了初始化Spring框架中的MessageSource组件——Spring的国际化

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());
          }
       }
       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 + "]");
       }
    }
}

8. initApplicationEventMulticaster源码解读

initApplicationEventMulticaster的作用是初始化事件广播器,相对比较简单

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 + "]");
       }
    }
    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 + "]");
       }
    }
}

9. onRefresh源码解读

在Spring中没有给出实现,属于一个模板方法,但是在SpringBoot中启动了Web服务器

protected void onRefresh() throws BeansException {
    // For subclasses: do nothing by default.
}

10. registerListeners源码解读

registerListeners的作用是为了注册监听器,方便接收广播事件

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 lisName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(lisName);
    }
}

11. finishBeanFactoryInitialization源码解读

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化上下文转化服务,主要用于类型转化、数据转换等等
    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));
    }

    // 提前实例化LoadTimeWeaverAware的类
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
       getBean(weaverAwareName);
    }

    // 在BeanFactory初始化完成后,不再需要临时类加载器,因此将其设置为null。
    beanFactory.setTempClassLoader(null);

    // BeanFactory将不再期望对Bean的定义进行进一步的更改,这有助于提高性能。
    beanFactory.freezeConfiguration();

    // 实例化所有非延迟初始化的单例Bean。这意味着所有剩余的单例Bean都将被创建,即使它们尚未被显式请求。
    beanFactory.preInstantiateSingletons();
}

11.1 preInstantiateSingletons源码解读

这里的preInstantiateSingletons是经过简化的

public void preInstantiateSingletons() throws BeansException {

    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    for (String beanName : beanNames) {
        // 获取Bean定义
       RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 需要实例化的bean不是抽象的 并且是单例 并且不属于懒加载
       if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
          if (isFactoryBean(beanName)) {
              // 获取工厂Bean
             Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
             if (bean instanceof FactoryBean) {
                FactoryBean<?> factory = (FactoryBean<?>) bean;
                 // 为true表示需要被立刻实例化
                boolean isEagerInit;
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                   isEagerInit = AccessController.doPrivileged(
                         (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                         getAccessControlContext());
                }
                else {
                   isEagerInit = (factory instanceof SmartFactoryBean &&
                         ((SmartFactoryBean<?>) factory).isEagerInit());
                }
                if (isEagerInit) {
                   getBean(beanName);
                }
             }
          }
          else {
              // 不属于工厂Bean,就可以立即创建Bean
             getBean(beanName);
          }
       }
    }

}

这里干了这几件事情:

  1. 获取当前所有Bean定义的BeanName集合
  2. 遍历BeanName集合,进行判断
    • 如果该Bean是一个FactoryBean,则检查它是否实现了 SmartFactoryBean 接口,调用 isEagerInit 方法来确定是否需要立即初始化。
    • 如果不是FactoryBean,立刻实例化

12. finishRefresh源码解读

finishRefresh的完成容器的启动,清除上下文,初始化生命周期处理器,并发送刷新事件

protected void finishRefresh() {
    // 初始化生命周期处理器
    initLifecycleProcessor();

    // 刷新事件传播到生命周期处理器。
    getLifecycleProcessor().onRefresh();

    // 创建并发布一个ContextRefreshedEvent事件,通知所有监听器应用程序上下文已经刷新完成
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

13. IOC容器加载失败源码解读

当Spring容器启动的时候出现异常后会走catch流程,首当其冲就是调用destroyBeans,也就是销毁所有bean,让JVM能够回收内存。

protected void destroyBeans() {
    getBeanFactory().destroySingletons();
}


public void destroySingletons() {
    if (logger.isTraceEnabled()) {
        logger.trace("Destroying singletons in " + this);
    }
    synchronized (this.singletonObjects) {
        this.singletonsCurrentlyInDestruction = true;
    }

    String[] disposableBeanNames;
    synchronized (this.disposableBeans) {
        disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
    }
    for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
        destroySingleton(disposableBeanNames[i]);
    }

    this.containedBeanMap.clear();
    this.dependentBeanMap.clear();
    this.dependenciesForBeanMap.clear();

    clearSingletonCache();
}

public void destroySingletons() {
    super.destroySingletons();
    updateManualSingletonNames(Set::clear, set -> !set.isEmpty());
    clearByTypeCache();
}

接着将IOC容器的活跃状态设置为false

protected void cancelRefresh(BeansException ex) {
    synchronized (this.activeMonitor) {
       this.active = false;
    }
}

14. IOC容器销销毁源码解读

当IOC容器被关闭的时候,会调用close方法

public void close() {
    synchronized (this.startupShutdownMonitor) {
       doClose();
    }
}

close方法调用了doClose方法

protected void doClose() {
    boolean actuallyClose;
    synchronized (this.activeMonitor) {
       actuallyClose = this.active && !this.closed;
       this.closed = true;
    }

    // 发布容器关闭事件
    publishEvent(new ContextClosedEvent(this));

    getLifecycleProcessor().onClose();

    // 销毁Bean,上面有解释
    destroyBeans();

    // 将beanFactory设置为null,方便JVM回收
    closeBeanFactory();

    synchronized (this.activeMonitor) {
        this.active = false;
    }
}

五、流程图

暂时略~后面有时间再补充哈哈哈


举报

相关推荐

0 条评论