spring之IOC

Posted 红桃xin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring之IOC相关的知识,希望对你有一定的参考价值。

1, 产生原因

在现实业务中由两个或多个类通过彼此的合作来实现业务逻辑。如果 获取 过程都要靠自身实现,将导致代码高度耦合并难以测试。

2,IOC容器是什么

Inversion of control 控制反转。或者又称依赖演注入。容器是把组件对象控制权,从程序代码自身转移到外部容器。
她负责创建对象,管理对象,装配对象,配置对象,并且管理对象的整个生命周期。

3 ,有你什么作用

  • 管理对象的创建和依赖关系的维护
  • 解耦,由容器去维护具体的对象
  • 把应用的代码量降到最低
  • 使应用容易测试,单元测试方便
  • 最小 的代价和侵入性使代码松散耦合

4, BeanFactory和ApplicationContext的设计与实现

B低级容器和A高级容器,可以用下面UML图展示。
在这里插入图片描述

  • 依赖关系

BeanFactory接口定义了IoC容器最基本的形式,并且提供IoC容器所应该遵守的最基本的服务契约,并没有给出容器的具体实现。
ApplicationContext接口及DefaultListableBeanFactory/XmlBeanFactory等都可以看成是容器某种功能的具体实现。

  • 加载方式

BeanFactory采用的是延迟加载形式来注入Bean。可能在调用后,某一属性没有注入,直至第一次调用getBean方法才会排出异常。
ApplicationContext 在容器启动时,一次性创建了所有Bean。但是会占用较大内存空间。

  • 创建方式

BeanFactory通常以编程的方式被创建,
ApplicationContext不能以声明的方式创建,如使用ContextLoader

  • 实现

BeanFacotry 简单粗暴,可以理解 为HashMap,Key是BeanName,Value是Bean实例。通常提供put(注册),get(获取)。
Application 继承了多个接口,具备更多的功能。EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource(国际化), ApplicationEventPublisher(支持事件,这些事件结合Bean为管理生命周期便利), ResourcePatternResolver(访问资源)。可以理解为容器工厂的上下文。

4,初始化过程

refresh()方法来启动,标志容器正式启动。具体来说包括BeanDefinitin的Resource定位、载入和注册三个基本过程。spring把这三个过程分开,并使用不同的模块来完成,ResourceLoader、BeanDefinitionReader、BeanDefinitionRegistry。
注意的是依赖注入是独立的过程,一般发生在getBean向容器索取Bean的时候),设置过lazyinit属性除外。

4, ApplicationContext应用场景

  • FileSystemXmlApplicationContext : 从xml文件中加载Beans的定义
  • ClassPathXmlApplication:同上,区别参考
  • WebXmlApplication:些容器加载xml文件,定义了一个Web应用的所有bean.

5, FactoryBean的实现

可参考类org.springframework.beans.factory.support.AbstractBeanFactory
主要方法doGetBean->getObjectForBeanInstance->getObjectFromFactoryBean->doGetObjectFromFactoryBean
最终 调用factory的getObject方法来从FactoryBean中得到Bean

6, BeanPostProcessor接口的实现

Bean的后置处理器是一个监听器,它可以监听容器触发的事件。和管理Bean的生命周期相关的,

  • postProcessBeforeInitialization:Bean初始化后前提供回调入口
  • postProcessAfterInitialization:Bean初始化后提供回调入口
public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

7,autowiring(自动依赖装配)的实现

这个autowiring属性在对Bean属性进行依赖注入时起作用。现在节选AbstractAutowireCapableBeanFactory的populateBean方法中的与autowiring实现相关部分。

int resolvedAutowireMode = mbd.getResolvedAutowireMode();
//开始进行依赖注入过程,先处理autowireing的注入
            if (resolvedAutowireMode == RootBeanDefinition.Autowire_by_name || resolvedAutowireMode == RootBeanDefinition.Autowire_by_type) {
                MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                if (resolvedAutowireMode == RootBeanDefinition.Autowire_by_name) {
                //根据bean的名字 进行autowire的过程
                    this.autowireByName(beanName, mbd, bw, newPvs);
                }

                if (resolvedAutowireMode == RootBeanDefinition.Autowire_by_type) {
                //根据type 进行autowire的过程
                    this.autowireByType(beanName, mbd, bw, newPvs);
                }

                pvs = newPvs;
            }

8,其它

  • Bean的依赖检查,可参考方法 checkDependencies
  • Bean对IoC容器的感知
  • BeanNameAware
  • BeanFcotryAware
  • ApplicationContextAware
  • MessageSourceAware
  • ApplicatonEventPublisherAware
  • ResourceLoaderAware

9,参考书目

以上是关于spring之IOC的主要内容,如果未能解决你的问题,请参考以下文章

Spring IOC源代码具体解释之容器依赖注入

Spring IOC源代码具体解释之容器初始化

3.1.2 Spring之IoC

Spring系列之IOC容器

Spring入门之IoC

面试之Spring框架IOC和AOP的实现原理