码迷,mamicode.com
首页 > 编程语言 > 详细

框架源码系列Spring5 Mybatis SpringBoot Dubbo Netty Zookeeper Tomcat源码深度解析

时间:2020-02-28 18:58:47      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:netty   factory   framework   原创文章   throw   了解   puts   failed   default   

1、IOC(控制反转)、AOP(切面)、DI (依赖注入)是spring的核心部分

    Spring是一种设计思想的体现,发生了“主从换位”的变化。应用程序由主动的创建对象,转换称了从IOC容器里获取对象,对象的创建、解析和注册都由Spring来替用户实现,用户只管定义。

2、IoC容器的设计与实现--Bean组件与Context组件

使用Spring时,它首先替我们完成的时IOC容器的初始化,初始化的过程包括定义(BeanDefinition)、载入定义(loadBeanDefinitions,包含了解析的方法)、注册定义(registerBeanDefinitions),注册最后落实到代码中就是

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);

this.beanDefinitionMap.put(beanName, beanDefinition);
注册到map集合中, 将BeanName作为键, BeanDefinition作为值保存。接下来看具体的源码,加深IOC容器初始化的过程理解

2.1Bean组件

bean组件在Spring的org.springframework.beans包下。IOC容器的初始化就在这个包里完成的,定义、载入、注册,对于使用者来说只要完成bean的定义就可以了,其他两个由 Spring 在内部帮我们完成了,对我们来说是透明的。

bean的定义我们不多说,可以用配置文件定义bean,也可以用注解的方式,接下来我们看下Spring的做了那些操作:

2.1.2 BeanFactory概述

BeanFactory是Spring bean容器的根接口.提供获取bean,是否包含bean,是否单例与原型,获取bean类型,bean 别名的方法 。

 

2.1.3BeanFactory的继承关系

 

我们可以看到DefaultListableBeanFactory  是最终的实现类,它实现了所有的接口,它也是Spring框架里核心的类之一

2.1.4BeanDefinition概述

BeanDefinition是一个接口类,Bean 的定义主要由 BeanDefinition 实现,项目启动首先是读取bean的xml配置文件,然后解析xml文件中的各种bean的定义,将xml文件中的每一个<bean />元素分别转换解析成一个BeanDefinition对象,其中保存了从配置文件中读取到的该bean的各种信息,以后所有的操作都是对这个对象的操作。

2.1.5 BeanDefinitionReader概述

BeanDefinitionReader同样也是接口类,读取xml配置文件,解析为BeanDefinition对象过程是繁琐的,整个解析过程主要通过下图中的类完成:

 

2.1.6BeanDefinitionHolder概述

BeanDefinitionHolder是一个class实现类,BeanDefinitionHolder对象中持有的BeanDefinition实例的引用,还有beanName,还有bean的别名

先对这几个类有个大体的了解,接下来从源码中看它们实际的作用。

2.1.7Bean Definition从加载、解析、处理、注册到BeanFactory的过程,也就是IOC容器的初始化过程

Bean Definition加载
用配置文件的方式定义bean ,首先要做的就是读取xml文件
public static void main(String[] args){//直接使用BeanFactory 作为容器
String xmlPath = "applicationContext.xml";
BeanFactory factory = new XmlBeanFactory(new ClassPathResource(xmlPath));
userService = (UserService) factory.getBean("userService");
userService.add();
}

在XmlBeanDefinitionReader类中
&1.loadBeanDefinitions方法从xml文件中加载beanDefinition,将Resource转化为EncodedResource对象,交给它的重载方法来做加载前的准备,实际去加载xml文件的是方法doLoadBeanDefinitions(InputSource inputSource, Resource resource),

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException{
....
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
....
}
&2.doLoadBeanDefinitions方法中加载得到一个Document对象,把Document和resource交给registerBeanDefinitions完成注册

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource){
....
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
....
}
&3.registerBeanDefinitions(Document doc, Resource resource)方法,这里实际上是创建了一个BeanDefinitionDocumentReader对象然后让它来完成。
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
Bean Definition解析

在DefaultBeanDefinitionDocumentReader类中
DefaultBeanDefinitionDocumentReader 是BeanDefinitionDocumentReader的实现类,这个类来实际的解析<bean/>标签
&1.registerBeanDefinitions()也做的前期准备,真正去解析文件的方法是doRegisterBeanDefinitions()
   
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
              ....
             doRegisterBeanDefinitions(root);
}

&2.doRegisterBeanDefinitions方法将</beans>节点下的每一个<bean/>相对应的bean definition注册。但是真正做这件事的是另一个方法 parseBeanDefinitions(root, this.delegate);
protected void doRegisterBeanDefinitions(Element root){
....
parseBeanDefinitions(root, this.delegate);
....
}
&3.<beans/>中还包含<bean/>元素,需要对bean元素进行解析,parseBeanDefinitions方法中调用来
parseDefaultElement方法来完成对<bean/>元素的解析,具体分解析过程有processBeanDefinition(ele, delegate)方法来实现,就是对beanDefinition的处理。
Bean Definition处理
  在DefaultBeanDefinitionDocumentReader类中
&1.processBeanDefinition方法中将Element对象转化成了BeanDefinitionHolder对象。这个BeanDefinitionHolder对象中持有的BeanDefinition实例的引用,还有beanName,还有bean的别名。
      然后将BeanDefinitionHolder对象和特定的bean工厂作为参数交给BeanDefinitionReaderUtils类来处理来进行注册。到了实际的注册步骤啦
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));
}
}
Bean Definition注册
在BeanDefinitionReaderUtils类中
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());

   // Register aliases for bean name, if any.
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
      for (String alias : aliases) {
         registry.registerAlias(beanName, alias);
      }
   }
}

DefaultListableBeanFactory类中,在这个方法中,将BeanDefinition 注册到了ConcurrentHashMap对象中了。注册完成
 
————————————————
版权声明:本文为CSDN博主「snow123f」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014676895/article/details/89669924

框架源码系列Spring5 Mybatis SpringBoot Dubbo Netty Zookeeper Tomcat源码深度解析

标签:netty   factory   framework   原创文章   throw   了解   puts   failed   default   

原文地址:https://www.cnblogs.com/kysj/p/12378364.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!