美文网首页
Spring IOC原理

Spring IOC原理

作者: 自负的鱼 | 来源:发表于2018-09-25 18:04 被阅读91次

    Spring IOC原理

    IOC(Inversion of Control)控制反转另外一种说法叫DI(Dependency Injection)即依赖注入。它并不是一种技术实现,而是一种设计思想。从实现原理上来讲,IOC其实就是反射变成,通过类名来动态生成对象。最主要是完成了对象创建和依赖的注入管理。


    image.png

    Spring IOC涉及定义

    bean的xml配置文件:我们以xml形式描述bean的名称、属性等信息。

    BeanDefinition:Spring将bean的注解、xml配置信息存储为Spring可以理解的结构化描述信息。

    BeanFactory:即IOC容器,是Spring的核心。在这集出场扩展多种IOC容器满足不同需求,例如常用ApplicationContext。

    IoC容器初始化:


    image.png

    依赖注入过程


    image.png

    IOC容器Bean

    Java Bean是一个满足规范的类。

    BeanFaoctory体系

    BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范。

    public interface BeanFactory {
        /**
         * 对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,如果需要得到工厂本身,需要转义
         */
        String FACTORY_BEAN_PREFIX = "&";
    
        /**
         * 根据bean的名字,获取在IOC容器中得到bean实例
         */
        Object getBean(String name) throws BeansException;
    
        /**
         * 根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制
         */
        <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
    
        /**
         * 根据bean的名字和Class类型来得到bean实例,args实例化bean时的参数
         */
        Object getBean(String name, Object... args) throws BeansException;
    
        /**
         * 根据bean的Class类型类获取bean实例
         */
        <T> T getBean(Class<T> requiredType) throws BeansException;
    
        /**
         * 根据bean的Class类型类获取bean实例,args实例化bean时的参数
         */
        <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    
        /**
         * 提供对bean的检索,看看是否在IOC容器有这个名字的bean
         */
        boolean containsBean(String name);
    
        /**
         * 根据bean名字得到bean实例,并同时判断这个bean是不是单例
         */
        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
        /**
         * [2.0.3新增]根据bean名字得到bean实例,并同时判断这个bean是不是原型
         */
        boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    
        /**
         * 检查给定名称的getBean调用是否将返回可分配给指定目标类型的对象。
         */
        boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    
        /**
         * [2.0.1版本新增]检查给定名称的getBean调用是否将返回可分配给指定目标类型的对象。
         */
        boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
    
        /**
         * 得到bean实例的Class类型
         */
        @Nullable
        Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    
        /**
         * 得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
         */
        String[] getAliases(String name);
    }
    

    BeanFactory初始化顺序如下:

    1、BeanNameAware的setBeanName;
    2、BeanClassLoaderAware的setBeanClassLoader;
    3、BeanFactoryAware的setBeanFactory;
    4、EnvironmentAware的setEnvironment;
    5、EmbeddedValueResolverAware的setEmbeddedValueResolver;
    6、ResourceLoaderAware的setResourceLoader(仅适用与运行时的应用上下文) ;
    7、ApplicationEventPublisherAware的setApplicationEventPublisher (仅适用与运行时的应用上下文) ;
    8、MessageSourceAware的setMessageSource (仅适用与运行时的应用上下文) ;
    9、ApplicationContextAware的setApplicationContext (仅适用与运行时的应用上下文) ;
    10、ServletContextAware 的setServletContext (仅适用与运行时的应用上下文) ;
    11、 BeanPostProcessors的postProcessBeforeInitialization方法;
    12、InitializingBean的afterPropertiesSet;
    13、自定义一个初始化方法(init-method);
    14、BeanPostProcessors的postProcessAfterInitialization方法;

    关闭BeanFactory时,以下生命周期方法适用:

    1、DestructionAwareBeanPostProcessors的postProcessBeforeDestruction方法;
    2、DisposableBeans destroy ;
    3、自定义一个销毁方法(destroy-method)

    Bean作用域

    Spring 定义了多种Bean作用域

    单例(Singleton):在整个应用中只有一个实例
    原型(Prototype):每次使用的时候都会创建一个新实例
    会话(Session):web应用中,为每个会话保留一份实例
    请求(Request):web应用中,每次请求创建一个实例

    Bean生命周期

    Spring对Bean进行实例化,默认是单例模式。
    Spring对Bean进行依赖注入,使用反射方法。
    bean已经准备就绪,驻留在应用上下文中,直到该应用上下文被销毁
    Bean实例被销毁,spring将调用它的distroy()接口方法。

    单例对象管理

    Spring在读取xml、注解配置时,默认创建该实例。
    创建对象时调用构造器和init-method方法
    实例被销毁时会调用destroy-method方法
    lazy-init="true",可以让这个对象在第一次被访问的时候创建

    非单例对象管理

    Spring在读取xml、注解配置时,不会创建实例
    在每一次访问容器实例时,都会创建新对象,并调用构造方法和init-method
    在对象销毁时不会调用任何方法

    Bean 自动注入

    spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系。

    byName:通过属性的名称自动装配(注入)。Spring会在容器中查找名称与bean属性名称一致的bean,并自动注入到bean属性中。bean的属性需要有setter方法。

    byType:通过类型自动装配(注入)。Spring会在容器中查找类(Class)与bean属性类一致的bean,并自动注入到bean属性中,如果容器中包含多个这个类型的bean,Spring将抛出异常。如果没有找到这个类型的bean,那么注入动作将不会执行。

    constructor:类似于byType,但是是通过构造函数的参数类型来匹配。假设bean A有构造函数A(B b, C c),那么Spring会在容器中查找类型为B和C的bean通过构造函数A(B b, C c)注入到A中。与byType一样,如果存在多个bean类型为B或者C,则会抛出异常。但时与byType不同的是,如果在容器中找不到匹配的类的bean,将抛出异常,因为Spring无法调用构造函数实例化这个bean。

    相关文章

      网友评论

          本文标题:Spring IOC原理

          本文链接:https://www.haomeiwen.com/subject/ddwloftx.html