• 【深入spring】IoC容器的实现


    本文乃学习整理参考而来

    IoC概述:

             spring中,IoC容器实现了依赖控制反转,它可以再对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中的方式来注入方法调用的依赖,这种依赖注入是可以递归的,对象被逐层注入。对象之间的相互依赖关系由IoC容器管理,并由容器完成注入,如对象的创建、赋值等,这样很大程度简化开发。

    结构图如下

    1.1 BeanFactory

    接口BeanFactory:体现了spring为提供给用户的IoC容器所设定的最基本功能规范。

    接口BeanDefinition:spring通过BeanDefinition来管理spring容器中的各种对象以及他们之间的相互依赖关系。

     源码如下

    **
     * IoC容器最基本功能
     * 此类相当于容器中的具体容器产品
     * @author qjc
     */
    public interface BeanFactory {
    
        /**
         * 获取产生对象的FactoryBean
         * 如:myObject是一个FactoryBean,使用&myObject得到的是FactoryBean
         */
        String FACTORY_BEAN_PREFIX = "&";
    
        /**
         * 获取IoC容器中管理的bean
         * @param name
         * @return
         * @throws BeansException
         */
        Object getBean(String name) throws BeansException;
    
        /**
         * 判断容器是否含有指定名称的bean
         * @param name
         * @return
         */
        boolean containsBean(String name);
    
        /**
         * 检查指定名称的bean是否是单例(可以在BeanDefinition中指定)
         * @param name
         * @return
         * @throws NoSuchBeanDefinitionException
         */
        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
        /**
         * 检查指定名称的bean是否是prototype类型(可以在BeanDefinition中指定)
         * @param name
         * @return
         * @throws NoSuchBeanDefinitionException
         */
        boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    
        /**
         * 检查指定名称的bean的Class类型是否是特定Class类型
         * @param name
         * @param targetType 用户指定
         * @return
         * @throws NoSuchBeanDefinitionException
         */
        boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;
    
        /**
         * 查询指定名称bean的Class类型
         * @param name
         * @return
         * @throws NoSuchBeanDefinitionException
         */
        Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    
        /**
         * 查询指定名称bean的所有别名(用户在BeanDefinition中指定的)
         * @param name
         * @return
         */
        String[] getAliases(String name);
    }

    说明:

      在BeanFactory里只对IOC容器的基本行为作了定义,根本不关心你的bean是如何定义怎样加载的。正如我们只关心工厂里得到什么的产品对象,至于工厂是怎么生产这些对象的,这个基本的接口不关心。

    1.2  IoC容器XmlBeanFactory

      此类为IoC容器最底层的实现类,提供基本IoC功能。与ApplicationContext实现原理类似,通过持有或扩展DefaultListableBeanFactory来获取IoC容器功能。

    关系结构图如下

    源码

    public class XmlBeanFactory extends DefaultListableBeanFactory {
        /**
         * XmlBeanDefinitionReader:读取XML的类
         */
        private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
    
        /**
         * @param resource  spring用来封装io操作的类,可如下构建
         *         ClassPathResource resource = new ClassPathResource("bean.xml");
         * @throws BeansException
         */
        public XmlBeanFactory(Resource resource) throws BeansException {
            this(resource, null);
        }
    
        public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
            super(parentBeanFactory);
            this.reader.loadBeanDefinitions(resource);
        }
    }

    IoC容器创建的基本步骤

      ClassPathResource res = new ClassPathResource("bean.xml");
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions(resource);

    1、创建IoC配置文件的抽象资源(包含BenaDefinition定义信息)

    2、创建BeanFactory

    3、创建BeanDefinition读取器

    4、读取配置信息,完成载入和注册后IoC容器就创建出来了

    通常我们不是这么创建的,而是使用ApplictionContext接口创建

    1.3 ApplictionContext

      ApplictionContext属于高级IoC容器,它在BeanFactory基础上添加了特性(其他容器不具备)。

        1.  支持信息源,可以实现国际化。(实现MessageSource接口)

         2.  访问资源。(实现ResourcePatternResolver接口,这个后面要讲)

         3.  支持应用事件。(实现ApplicationEventPublisher接口)

     

    参考:

    《Spring 技术内幕》

     

  • 相关阅读:
    MySQL 中 where id in (1,2,3,4,...) 的效率问题讨论
    创建,增加,删除mysql表分区
    mysql分区及实例演示
    MySQL的表分区详解
    MySQL 存储过程传参之in, out, inout 参数用法
    MySQL里面的子查询实例
    超详细mysql left join,right join,inner join用法分析
    MySQL force Index 强制索引概述
    MyISAM和InnoDB的索引在实现上的不同
    java中的守护线程
  • 原文地址:https://www.cnblogs.com/dooor/p/5346333.html
Copyright © 2020-2023  润新知