Spring IOC和DI简单认识(转)

原文链接:https://blog.csdn.net/nihui123/article/details/82917121

IOC的基本思想就是反转资源获取的方向,传统的资源查找方式要求组件向容器发起请求,然后获取到所要请求的资源作为回应,应用了IOC之后,则是容器主动的将资源推送给它所管理的组件,组件只需要做的是选择一种合适的方式来接受资源,这种行为就被看做是组件被动的查找资源。DI(依赖注入),这个是对IOC的另一种表达方式,也就是组件以一些预先定义好的方式(例如setter方法)接受来自容器的资源注入,相对于IOC而言,这种表述更直接。

如图,传统情况下一个容器中有两个类A和B,要想把A类作为B类的属性需要先创建一个A类的对象,然后创建一个B类的对象,通过对象的setter方法将这个属性赋给B类。而使用IOC容器,则是容器就把这个注入关系给完成了,我们只需要通过B类的getter方法获取到对象的属性就可以了,达到了在代码上的解耦合。

在IOC之前需要解决的几个问题

    -分离接口的实现

需求:生成HTML或PDF格式的不同类型报表

 如图需要先定义一个ReportService类,而两种实现方式需要实现同一个接口,而且接口和两个类都需要继承ReportService类。并没有实现解耦合,组件类之间的耦合度还是很高。这个就引出了第二种方式

    -采用工厂设计模式

这里看出,ReportService与功能类之间的耦合度降低了,但是与工厂类之间的耦合有所增加,也没有很好的解决组件之间的耦合问题。这种情况下,需要扩展新功能的时候需要改动的类还是比较多的,各个功能类之间的影响还是比较大的。

    -采用控制反转

这里我们可以看出与工厂设计模式相比较,ReportService与功能类之间的耦合度有所降低,但是相比较之下,在实现不同的功能的时候只需要扩展ReportGenerator接口就可以以了。Container类直接作为一个“中间人”调和了组件之间的关系。

    这里我们可以来了解一下Spring框架的底层实现原理,这里我们可以看到控制反转与工厂方法模式的最大的差异就是少了一个工厂类的集成,而是通过容器将这个依赖注入到了各个类中,不是通过工厂来获取。其实在Spring底层实现中就是通过工厂模式实现了功能类之间的解耦合。使用工厂模式获取到对应的配置文件中的内容,利用反射机制获取到配置文件中定义的类的实例对象,然后通过工厂类返回。这样看来Spring容器所做的事情就是将这些东西进行了一个简单的封装。主要使用到的原理就是Java提供的反射机制,当然了底层实现并不仅仅使用到的这个技术应该是多种技术的结合。才能诞生Spring这样一个优秀的框架。

    那么简单的说完底层的原理我们就来了解一下这个配置文件到底应该该怎么使用。在Java中我们使用dom4j来解析XML配置文件,当然Spring还提供了注解方式,这里我们先介绍一下XML配置文件对于Bean对象的配置

    Bean配置方式,通过全类名(主要用户反射可以找到对应的类)、通过工厂方法(静态工厂方法&实例工厂方法)、FactoryBean。在SpringIOC容器有两种,一种是BeanFactory一种是ApplicationContext,这里需要说明一下BeanFactory和FactoryBean并不是我写错了而是一个是面向开发者,一个面向Spring底层。那么,哪一个是面向开发者,哪一个是面向Spring底层呢?在上面我们说过Spring框架的底层是通过工厂模式实现的所以说FactoryBean是为了底层提供不同的“工厂”,而BeanFactory是面向开发者,但是这个我们并不会经常的使用,这个面向开发者应该定义为Spring开发者而不是应用开发者。作为应用开发者经常使用到的就是ApplicationContext。

    依赖注入的方式有两种一种是属性注入,一种是构造器注入。

<bean id="World" class="com.nihui.spring.bean.World">
    <property name="name" value="Spring"></property>
</bean>

在XML文件中通过Bean节点的方式,来配置Bean,而这个解析规则是由Spring规定好的。

    id:Bean名字,唯一标识,若id没有指定Spring将自动将权限定性为类名作为Bean的名字,id可以指定多个名字,名字之间通过逗号、分号或者空格分隔。

    Spring容器中读入Bean配置建立一个Bean之前,必须对它进行实例化,只有在容器实例化之后才可以从IOC容器中获取的Bean对象的实例并使用。这里就提到了之前的内容,这里我们对这里两个实例化IOC容器的方式做官方的理解

    BeanFactory:IOC容器的基本实现,也就是之前提到的Spring底层实现,可以理解为Spring的“基础设施”,面向Spring本身;也就是之前提到的Spring的开发者,

    ApplicationContext:提供了更多的高级特性,是BeanFactory的子接口,面向Spring应用开发者,但是几乎所有的应用场合都是直接使用ApplicationContext而不是使用底层的BeanFactory。但是无论哪一种实现方式,配置文件都是相同的。

    这里详细介绍一下ApplicationContext

    ApplicationContext有两个主要的实现类,ClassPathXmlApplicationContext:从类路径下加载配置文件;FileSystemXmlApplicationContext:从文件系统中加载配置文件。ConfigurationApplication扩展与ApplicationContext,新增加的两个主要方法,refresh()和close(),让ApplicationContext具有启动、刷新和关闭上下文的能力。

    ApplicationContext在初始化上下文时就实例化所有的单例Bean。

    WebApplicationContext是专门为WEB应用而准备,它允许从相对于WEB的根目录的路径中完成初始化工作。

猜你喜欢

转载自www.cnblogs.com/zhangrj9/p/11668606.html
今日推荐