SpringIOC源码解析

透彻理解SpringIOC设计原理分析

接下来我们带着问题学习

1、  Spring平台组成技术体系有哪些?

2、  SpringIoc容器技术的设计演化?

3、  高级形式容器技术ApplicationContext的初始化细节?

4、  容器中的Bean组件如何装配依赖?

 

Spring平台组成技术体系有哪些?

Spring是一个分层框架,由七个体系模块组成。所有的模块都是构建在容器技术上

由上图看出所有的模块都是以SpringCore即Bean容器技术为基础的,换句话说:

SpringIOC容器技术,为我们上层所有模块提供依赖注入,这样上层模块才能正确执行, Java尿性,解耦

SpringIOC都是以面向接口编程, 将IOC容器技术体系勾勒的非常清晰, 实现非常复杂, 子类实现多样性。

容器技术最开始思路?

         BeanFactory:完成Bean实例的提供工作,输入参数,产出成品, 可以反复提供

         BeanFactory源码分析?

        

只需要把FileSystemXmlApplicationContext里面的设计运转原理搞懂就窥视我们Ioc容器的体系

public FileSystemXmlApplicationContext(String[]configLocations, boolean refresh, ApplicationContext parent)
     
throws BeansException{
  
// 调用父类的构造, 确认关系
   super(parent);
  
setConfigLocations(configLocations);
   if (refresh){
     
refresh();
   }
}

refresh方法是主方法

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

      // 初始化beanFactory
      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;
      }
   }
}

 

@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果过旧的bean工厂,销毁清空
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      customizeBeanFactory(beanFactory);
// 加载我们外部配置的BeanDefinitions字节信息到工厂
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

再进入 AbstractXmlApplicationContext类中的这个方法;这里加入了reader读取器

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // 加载xml的读取器到beanFactory中
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   // Configure the bean definition reader with this context's
   // resource loading environment.
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   // Allow a subclass to provide custom initialization of the reader,
   // then proceed with actually loading the bean definitions.
   initBeanDefinitionReader(beanDefinitionReader);
        // 关键对BeanDefinition进入载入IOC源码分析, 通过Resouce定位路径来读取
   loadBeanDefinitions(beanDefinitionReader);
}

ResourceLoader如下


   /** Pseudo URL prefix for loading from the class path: "classpath:" */
   String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;

 

获取资源的方法,Resource可以是下面成千上万种子类, IO定位的对象

通过Reader读取器, 通过Resouce(IO)通道来读取外界配置的beanDefinition的信息applicationContext

然后注册到某个集合容器,String Name(bean  id =”xxx”)装配输出这个实例

@Override
protected Resource getResourceByPath(String path) {
   if (path != null && path.startsWith("/")) {
      path = path.substring(1);
   }
   return new FileSystemResource(path);
}

 

Reader的入口,就是在Resource 的基础上来进行加载, 再进入源码分析

Definition? IOC的内部数据结构.

 

注册环节:

BeanDefinitionRegistery

void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException;

ApplicationContext.getBean()扫描注解的时候拿到我们需要的实例, getBean 内部隐化

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页