spring IOC容器源码分析(上)

spring ioc容器源码最重要的是这两部分,一部分是创建bean容器,加载、注册bean,一部分是实例化(初始化)bean,本篇文章是针对第一部分进行分析的。

IOC容器的简单使用

获取IOC容器

public static void main(String[] args){
    
    
    ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:application.xml");
}

在maven中添加spring-context的依赖

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.11.RELEASE</version>
</dependency>
//spring-context会自动将spring-core,spring-beans,spring-aop,spring-expression这几个jar包导入进来

实现往容器中加入bean

1.首先定义一个接口

public interface Fruit{
    
    
    String getFruit();
}

2.定义接口实现类

public class Apple implements Fruit{
    
    
    
    @Override
    public String getFruit(){
    
    
        return "Apple";
    }
}

3.在resource目录下新建一个配置文件application.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">

    <bean id="fruit" class="com.lx.example.Apple"/>
</beans>

4.通过以下代码运行实例

public class Demo{
    
    
    public static void main(String[] args){
    
    
    	//获取容器
        ApplicationContext ac=ClassPathXmlApplicationContext("classpath:classpath:application.xml");
        //从容器中获取对象,而不是通过new的方式创建对象,降低程序间的耦合
        Fruit fruit=ac.getBean(Fruit.class);
        //这句将打印:Apple
        System.out.println(fruit.getFruit());
    }
}

接下来,通过具体深入到这个简单的实例中来进行分析

BeanFactory的介绍

BeanFactory,就是生产和管理bean的工厂,具体的类图和继承关系如下

这里具体分析几个特别的BeanFactory

ListableBeanFactory,这个接口可以获取多个bean,最上层的BeanFactory是获取单个bean

HierarchicalBeanFactory,Hierarchical 单词本身能说明问题了,在应用中我们可以有多个BeanFactory,然后设置它们之间的父子关系,加载子BeanFactory时,先加载父BeanFactory

AutowireCapableBeanFactory ,@Autowire也是我们经常用到的关键字,用于BeanFactory自动装载bean,ApplicationContext并没有继承这个这个接口,而是通过getAutowireCapableBeanFactory()方法来获取

ApplicationContext继承了ListableBeanFactory和HierarchicalBeanFactory,没有继承AutowireCapableBeanFactory,但没有继承不代表不能使用,ApplicationContext接口定义中最后一个方法getAutowireCapableBeanFactory()可以获取

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
    
    
  
  private Resource[] configResources;

  //如果需要配置成父子关系,调用这个构造方法
  public ClassPathXmlApplicationContext(ApplicationContext parent) {
    
    
    super(parent);
  }
  ...
  public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
      throws BeansException {
    
    

    super(parent);
    //根据提供的路径,处理成配置文件数组
    setConfigLocations(configLocations);
    if (refresh) {
    
    
       //核心方法
      refresh();
    }
  }
    ...
}

refresh()方法,重点

@Override
public void refresh() throws BeansException, IllegalStateException {
    
    
   
   synchronized (this.startupShutdownMonitor) {
    
    

      //准备工作
      prepareRefresh();

      //获取容器
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      //预处理
      prepareBeanFactory(beanFactory);

      try {
    
    
         // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
         invokeBeanFactoryPostProcessors(beanFactory);

         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
         //调用 BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization
         registerBeanPostProcessors(beanFactory);

         initMessageSource();

         //钩子方法
         onRefresh();

         registerListeners();

         //初始化所有的 singleton beans(lazy-init 的除外)
         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.
            // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
            destroyBeans();

            cancelRefresh(ex);

            // 把异常往外抛
            throw ex;
      } finally {
    
    
            resetCommonCaches();
        }
    }
}

obtainFreshBeanFactory(),创建bean容器,加载注册bean

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    
    
   //关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean
   refreshBeanFactory();

   //创建的 BeanFactory
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   if (logger.isDebugEnabled()) {
    
    
      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
   }
   return beanFactory;
}

进入到refreshBeanFactory()方法

protected final void refreshBeanFactory() throws BeansException {
    
    
   
   //当前 ApplicationContext 是否有 BeanFactory
   if (hasBeanFactory()) {
    
    
      destroyBeans();
      closeBeanFactory();
   }
   try {
    
    
      //初始化一个 DefaultListableBeanFactory
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      //序列化
      beanFactory.setSerializationId(getId());

      //设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
      customizeBeanFactory(beanFactory);

      //加载 Bean 到 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);
   }
}

其中customizeBeanFactory(beanFactory),
设置是否允许BeanDefinition覆盖和是否允许循环引用,默认情况下,如果在同一配置文件中重复了,会报错,如果不是同一配置文件中,会发生BeanDefinition覆盖。同时,默认情况下,spring允许循环依赖

loadBeanDefinitions(beanFactory) 方法,加载bean

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    
    
   //实例化一个 XmlBeanDefinitionReader
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   initBeanDefinitionReader(beanDefinitionReader);
   //加载beanDefinition
   loadBeanDefinitions(beanDefinitionReader);
}

处理XML每个元素

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    
    
    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)) {
    
    
                //处理每个xml中的元素
                parseDefaultElement(ele, delegate);
            }
            else {
    
    
                delegate.parseCustomElement(ele);
            }
        }
    }
}

解析和注册bean

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    
    
    // 解析
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
    
    
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
    
    
            // 注册
            // Register the final decorated instance.
            BeanDefinitionReaderUtils.registerBeanDefinition(
                bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
    
    
            getReaderContext().error("Failed to register bean definition with name '" +
                    bdHolder.getBeanName() + "'", ele, ex);
        }
        // Send registration event.
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

这一步中,通过parseBeanDefinitionElement将XML的元素解析为BeanDefinition,然后存在BeanDefinitionHolder中,然后再利用BeanDefinitionHolder将BeanDefinition注册

注册bean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, 
        final Object[] args) {
    
    
    //初始化bean
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    
    
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
    
    
        //创建bean的实例
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
    
    
        //初始化bean的实例,注入属性
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
    
    
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
    }
    // ... ...
}

猜你喜欢

转载自blog.csdn.net/weixin_42478399/article/details/101792089