zoukankan      html  css  js  c++  java
  • spring技术内幕学习笔记01

    该来的总会来,spring源码我抵触好几年的东西,总该还了。。。。

    1.1 IOC容器的实现

    1.1.1 关于DI和IOC

    可以说IOC与DI是相互依赖的概念,IOC是指依赖倒置原理,指的是可以在对象生成或初始化的时候直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中。

    1.1.2 BeanFactory与ApplicationContext

    这是Spring IOC容器中最重要的两个容器,一般设计线路有两种:

    • 一个是实现Beanfactory接口的简单容器系列
    • 另一个是ApplicationContext应用上下文,它作为高级容器的存在增强了许多面向框架的特性

    2.1 IOC容器的设计


    这里涉及的是主要接口关系,而具体的IOC容器都是在这个接口体系下实现的,比如DefaultListableBeanFactory,这个基本的容器的实现就是实现了ConfigurableBeanFactory接口从而成为一个简单的IOC容器。
    基于这个最基本容器又可以做很多扩展,比如:XmlBeanFactory就是在DefaultListableBeanFactory的基础上做扩展实现的,ApplicationContext的实现也是如此。
    关于这个高级容器ApplicationContext可以看到它继承了BeanFactory体系下的ListableBeanFactory和AutowireCapableBeanFactory等接口。具备了BeanFactory的基本功能。在此基础上通过继承MessageSource,ResourceLoadr等接口赋予了更高级的IOC容器特性。

    2.1.1 BeanFactory的应用场景

    在Spring中BeanFactory只是一个接口类,基于这个接口实现的简单容器譬如:DefaultListableBeanFactory,XmlBeanFactory等等。用户在使用容器的时候可以使用转移符号“&”来得到FactoryBean本身。

    关于BeanFactory与FactoryBean前者是一个Bean在Spring中所有的Bean都是由BeanFactory来管理的。而后者是一个工厂,虽然也是一个Bean但是这个Bean不是一个简单的Bean,而是一个能够生产或者修饰对象生成的工厂Bean。

    BeanFactory中定义了作为一个IOC容器最基本的功能:

    • Object getBean()
    • boolean containsBean()
    • boolean isSingleton()
    • boolean isPrototype()
    • booolean isTypeMatch()
    • Class getType()
    • String[] getAliases()

    2.1.2 BeanFactory的设计原理


    XmlBeanFactory继承与DefaultListableBeanFactory,后者非常重要,它是一个我们经常要用到的一个IOC容器的实现,在设计ApplicationContext的时候也会用到这个基类。在Spring中实际上是把DefaultListableBeanFactory作为一个默认的功能完整的Ioc容器来使用的。下面是XmlBeanFactory的源码:

    public class XmlBeanFactory extends DefaultListableBeanFactory {
    
        private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
    
    
        /**
         * Create a new XmlBeanFactory with the given resource,
         * which must be parsable using DOM.
         * @param resource XML resource to load bean definitions from
         * @throws BeansException in case of loading or parsing errors
         */
        public XmlBeanFactory(Resource resource) throws BeansException {
            this(resource, null);
        }
    
        /**
         * Create a new XmlBeanFactory with the given input stream,
         * which must be parsable using DOM.
         * @param resource XML resource to load bean definitions from
         * @param parentBeanFactory parent bean factory
         * @throws BeansException in case of loading or parsing errors
         */
        public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
            super(parentBeanFactory);
            this.reader.loadBeanDefinitions(resource);
        }
    
    }
    

    创建一个IOC容器的基本步骤:

    1. 创建Ioc配置文件的抽象资源,这个抽象资源包括了BeanDefinition的定义信息
    2. 创建一个BeanFactory工厂一般用的是DefaultListableBeanFactory
    3. 创建一个载入BeanDefinition的读取器,这里使用XmlBeanDefinitionReader来载入XML文件形式的BeanDefinition
    4. 从定义好的资源位置开始载入配置信息。完成整个资源定位,载入,注册这三个步骤后,需要的IOC容器就被建立起来了。

    2.1.3 ApplicationContext的应用场景

    不同于基于BeanFactory的设计线路,应用上下文多了如下特性:

    • 支持不同的信息源,因为实现了MessageSource接口,这些信息源的扩展功能可以支持国际化的实现
    • 访问资源。由于ResourceLoader和Resource接口的支持,我们可以从不同的地方获取BeanDefinition
    • 支持应用事件

    2.1.4 ApplicationContext的设计原理

    /**
    	 * Create a new FileSystemXmlApplicationContext with the given parent,
    	 * loading the definitions from the given XML files.
    	 * @param configLocations array of file paths
    	 * @param refresh whether to automatically refresh the context,
    	 * loading all bean definitions and creating all singletons.
    	 * Alternatively, call refresh manually after further configuring the context.
    	 * @param parent the parent context
    	 * @throws BeansException if context creation failed
    	 * @see #refresh()
    	 */
    	public FileSystemXmlApplicationContext(
    		String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
    			throws BeansException {
    		super(parent);
    		// 设置配置文件集,字符串数组
    		setConfigLocations(configLocations);
    		if (refresh) {
    			refresh();
    		}
    	}
    

    FileSystemXmlApplicationContext继承与基类AbstractXmlApplicationContext。直接创建这样一个IOC容器实列的话会调用IOC容器的启动方法refresh()。

    2.2 IOC容器的初始化过程

    分为3个主要过程:

    • Resource的定位,指的是BeanDefinition的定位,它由ResourceLoader通过统一的Resource接口来实现。比如文件系统中的BeanDefinition可以用FileSystemResouce来扫描,类路径中的bean信息可以用ClassPathResouce来扫描
    • BeanDefinition信息的载入。具体来说就是将POJO对象中的方法字段抽象到IOC容器中
    • IOC容器注册这些BeanDefinition的过程,这个过程是通过调用BeanDefinitionRegister接口来完成的,在IOC容器内部将这些Bean信息会注入到一个CurrentHashMap中。

    Bean的载入和依赖注入是两个不同概念,bean载入不包含实列数据,而依赖注入发生在第一次通过getbean()方法从IOC容器中获取bean的时候。有一个例外就是bean开启了lazy-init那么在IOC容器初始化的时候该bean的依赖注入过程就已经完成了。

  • 相关阅读:
    初学者易上手的SSH-spring 01控制反转(IOC)
    初学者易上手的SSH-hibernate04 一对一 一对多 多对多
    初学者易上手的SSH-hibernate03 三大状态与缓存
    初学者易上手的SSH-hibernate02 三种查询方式
    初学者易上手的SSH-hibernate01环境搭建
    Maven-环境搭建以及建立Maven项目
    初学者易上手的SSH-struts2 05拦截器与自定义拦截器
    初学者易上手的SSH-struts2 04值栈与ognl表达式
    screen常用操作总结
    word2016教程:使用密码保持修订
  • 原文地址:https://www.cnblogs.com/xhj928675426/p/14671761.html
Copyright © 2011-2022 走看看