欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring ioc分析,以及编码实现

程序员文章站 2022-07-12 13:09:11
...

1. 什么是IOC

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

他能够帮助我们管理所有类的创建,销毁,是否是单例模式,类与类之间的多层依赖关系

2. IOC 解决了什么问题?

  IOC 解决了类与类之间的依赖关系。将控制类与类之间依赖的权利交给了IOC

3. IOC 的原理是什么?

其实 IOC 的原理很简单,底层就是java的反射。给定一个字符串能创建一个实例,利用set方法对实例的依赖进行注入。

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException,
   InstantiationException, NoSuchMethodException, InvocationTargetException {
   String className="com.bean.User";
   Class clazz = Class.forName(className);
   User user = (User)clazz.newInstance();
   Method method = clazz.getMethod("setTest", String.class);
   method.invoke(user,"hello");
   user.work();
}

在真正的开发中,我们只需要在配置文件给定一个类名字符串,就什么都不用管了,对象就会创建出来,系统启动完毕之后,我们只需要直接使用该对象就好了,不必自己去new。解决了我们的对象创建问题。我们通过反射调用该方法的setText方法,完成了依赖注入。我们不再需要去new,然后去set,IOC 已经为我们做好了一切。

  1. BeanFactory:这是IOC容器的接口定义,如果将IOC容器定位为一个水桶,那么BeanFactory 就定义了水桶的基本功能,能装水,有把手。这是最基本的,他的实现类可以拓展水桶的功能。
  2. ApplicationContext:这是我们最常见的,上面我们说水桶,BeanFactory是最基本的水桶,而 ApplicationContext 则是扩展后的水桶,它通过继承 MessageSource,ResourceLoader,ApplicationEventPublisher 接口,在BeanFactory 简单IOC容器的基础上添加了许多对高级容器的支持。
  3. BeanDefinition:我们知道,每个bean都有自己的信息,各个属性,类名,类型,是否单例,这些都是bena的信息,spring中如何管理bean的信息呢?对,就是 BeanDefinition, Spring通过定义 BeanDefinition 来管理基于Spring的应用中的各种对象以及他们直接的相互依赖关系。BeanDefinition 抽象了我们对 Bean的定义,是让容器起作用的主要数据类型。对 IOC 容器来说,BeanDefinition 就是对依赖反转模式中管理的对象依赖关系的数据抽象。也是容器实现依赖反转功能的核心数据结构。
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 为刷新准备上下文
        prepareRefresh();
        // 告诉子类刷新内部的bean工厂,在子类中启动refreshBeanFactoty的地方,创建bean工厂,根据配置生成bean的定义
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 在本上下文中可以使用beanFactory
        prepareBeanFactory(beanFactory);
        try {
            // beanFactory的后置处理器
            postProcessBeanFactory(beanFactory);
            // 调用beanFactory的后置处理器,在bean定义中,向容器注册
            invokeBeanFactoryPostProcessors(beanFactory);
            // 后置处理器注册
            registerBeanPostProcessors(beanFactory);
            // 对上线web的消息源进行初始化
            initMessageSource();
            // 初始化上下文中的事件机制
            initApplicationEventMulticaster();
            // 初始化其它特殊的bean
            onRefresh();
            // 检查监听Bean并且将这些bean向容器注册
            registerListeners();
            // 实例化所有的non-lazy-init
            finishBeanFactoryInitialization(beanFactory);
            //  发布容器事件,结束refresh过程 Last step: publish corresponding event.
            finishRefresh();
        }
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }
            // 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
            destroyBeans();
            // 重置“active”标志
            cancelRefresh(ex);
            throw ex;
        }
        finally {
            resetCommonCaches();
        }
    }
}
  1. 构建BeanFactory,以便于产生所需的 Bean。
  2. 注册可能感兴趣的事件。
  3. 常见Bean实例对象。
  4. 触发被监听的事件。
@Override
protected final void refreshBeanFactory() throws BeansException {
    //如果存在,就销毁
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        //重新创建
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        //序列化
        beanFactory.setSerializationId(getId());
        // 定制的BeanFactory
        customizeBeanFactory(beanFactory);
        // 使用BeanFactory加载bean定义 AbstractXmlApplicationContext
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}
  1. 资源(Resource)定位;
  2. BeanDefinition 的载入和 BeanFactory 的构造.
  3. 想 IOC 容器(BeanFactory)注册 BeanDefinition.
  4. 根据 lazy-init 属性初始化 Bean 实例和依赖注入.

IOC的自定义实现:
Spring ioc分析,以及编码实现

github地址:https://gitee.com/huazhenguo/ioc-test/tree/master

转载地址: https://www.jianshu.com/p/6e25dc62e3a1

相关标签: ioc spring