Spring ioc分析,以及编码实现

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的自定义实现:
这里写图片描述

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值