当前位置: 移动技术网 > IT编程>开发语言>Java > Spring:IoC-DI

Spring:IoC-DI

2019年10月23日  | 移动技术网IT编程  | 我要评论

spring笔记(一)


什么是spring?

  spring是一个以ioc(inversion of control-控制反转)和aop(aspect oriented programming-面向切面编程)为内核的开源框架。

  那么什么是框架呢?框架能做什么?为什么要使用框架?框架其实就是能完成一定功能的半成品。框架能够帮助我们完成的是:项目的整体框架、一些基础功能、规定了类和对象如何创建,如何协作等,当我们开发一个项目时,框架帮助我们完成了一部分功能,我们自己再完成一部分,那这个项目就完成了。

spring框架包结构

  使用spring框架进行开发时,需要用到spring框架和第三方依赖包。

  框架包:

    以spring 4.3.16为例。下载之后,解压,最终的目录结构图如下:

       

    其中,libs目录下包含60个jar文件,这些jar文件分为3类:

      a、以release.jar结尾的是spring框架class文件的压缩包

      b、以release-javadoc.jar结尾的是spring框架的api文档的压缩包

      c、以release-sources.jar结尾的是spring框架源文件的压缩包

    整个spring由20个模块组成,该目录下为每个模块都提供了这三种压缩包。初次之外,在libs目录中,还有4个spring的基础包,分别对应spring核心容器的4个模块:

      spring-core-4.3.16.release.jar:包含spring框架的基本核心工具类,spring其他组件都要用到这个包里面的类。

      spring-beans-4.3.16.release.jar:所有基于spring框架的应用都要用到的jar包,包含访问配置文件、创建和管理bean以及进行ioc或者di操作相关的所有类。

      spring-context-4.3.16.release.jar:spring提供了在基础ioc功能上的扩展服务,还提供了许多企业级服务的支持,如任务调度、jndi定位、ejb集成、远程访问、缓存、邮件服务以及各种视图层框架的封装等。

      spring-expression-4.3.16.release.jar:定义了spring的表达式语言。

  第三方依赖包:

    在使用spring进行开发时,spring的核心容器还需要依赖commons-logging的jar包。  

什么是控制反转-ioc?

  学习ioc之前,要先懂什么是依赖?

    应用程序在没有引入ioc容器之前,对象a依赖对象b,那么a对象实例化或者运行到某一个点的时候,自己就必须去主动创建对象b或者使用已经创建好的对象b,如果没有对象b,对象a就无法使用,就是a has b的关系。此时,我们就可以理解为对象a对b对象产生了依赖。

  从上面的依赖关系可以看出,创建对象的过程是主动的:缺对象b马上new一个,也就是说我需要啥自己去创建一个;而将对象引入ioc容器之后呢?对象a和对象b就失去了直接联系,当a对象实例化或者运行到某个点需要对象b,ioc容器就是主动创建一个对象b给到a需要的地方。此时,对象a获取对象b的过程就是被动获取的,也就是把原来由自己创建对象的权力交给了ioc容器,此时对象的创建都由ioc容器来管理,这就是控制反转。你也可以这么理解:是的,你想抽烟!没结婚之前,想抽什么买什么,因为钱在自己手里。结婚之后呢?工资到哪里去了呢?很明显要上交给老婆大人,那你此时想抽烟就比较麻烦了,你该怎么做呢?是不是应该请求老婆大人给钱买烟呢?只有老婆大人给了你钱,你才能买到烟...这个权力的颠倒过程就是控制反转的过程。

  ioc在角色扮演上等价于一个第三方,我更习惯于理解成为一个代理商。为什么这么说呢?因为ioc实现了对具有依赖关系的对象之间的解耦!来,看图:

    

  从上面的图中可以看出,ioc做了什么事情呢?ioc它把各个对象类封装之后,再通过ioc容器来关联这些对象。这样一来,对象与对象之间的关系就通过ioc容器来进行联系,而对象与对象之间没有什么直接联系。怎么去理解呢?假如工厂支持diy笔记本电脑,你是消费者,你想diy笔记本电脑,就要直接联系工厂,那么此时你和工厂就产生了依赖关系,也就是你与工厂有了耦合。而ioc扮演的角色就是第三方的代理商,就是告诉你:你不用直接去联系工厂了,你告诉我需要什么,由我来把你的需求告诉工厂。然后代理商拿到按照你需求diy的笔记本电脑,然后注入给你。来看图:

    

什么是di-依赖注入?

  di(dependency inject)依赖注入:由ioc容器在运行期间动态的将某种依赖关系注入对象之中。也就是将对象b注入(赋值)给对象a的成员变量。

  怎么去理解di和ioc之间的联系呢?依赖注入( di) 和控制反转( ioc) 是对同一件事情的不同描述, 从某个方面讲, 就是它们描述的角度不同。 依赖注入是从应用程序的角度描述, 即应用程序依赖容器创建并注入它所需要的外部资源; 而控制反转是从容器的角度描述, 即容器控制应用程序, 由容器反向地向应用程序注入应用程序所需要的外部资源。 这里所说的外部资源可以是外部实例对象, 也可以是外部文件、对象等。

ioc和di带来的益处?

  1.可维护性比较号,便于单元测试、调试程序和争端故障。代码中的每一个class都可以单独测试,彼此之间互不影响,只要保证自身的功能无误即可,这就是组件之间低耦合或者无耦合带来的好处。

  2.每个开发团队的成员都只需要关注自己要实现的业务逻辑,完全不用关心其他人的工作进展,因为你的任务跟别人没有任何关系,你的任务可以单独测试,不用依赖于别人的组件,再也不会扯不清责任了。所以,在一个大中型项目中,团队成员分工明确、责任明晰,很容易将一个大的任务划分为细小的任务,开发效率和产品质量必将得到大幅度的提高。

  3.可复用性好,我们可以把具有普遍性的常用组件独立出来,反复应用到项目中的其他部分,或者是其他项目,当然这也是面向对象的基本特征。显然,ioc更好地贯彻了这个原则,提高了模块的可复用性。符合接口标准的实现都可以插接到支持此标准的模块中。

  4.生成对象的方式转为外置方式,就是把对象生成放在配置文件中进行定义。这样,当我们更换一个实现子类将会变得很简单,只要修改配置文件就可以了,完全具有热插拔的特性。

ioc和di的实现

  spring框架的主要功能是通过器核心容器来实现的。spring框架提供的两种核心容器分别是:beanfactory(来源与org.springframework.beans.factory的主要接口)和applicationcontext(来源于org.springframework.context的主要接口)。

  spring ioc框架的主要组件由beans、配置文件applicationcontext.xml、beanfactory接口及其相关类、applicationcontext接口及其相关类。

  1.beans是指项目中提供业务功能的bean,即容器要管理的bean。bean就是一个常见的javabean、java类。

  2.在spring中对bean的管理是在配置文件中进行的。在spring容器内编辑配置文件管理bean又被称为bean的装配,实际上装配就是告诉容器需要哪些bean,以及容器是如何使用ioc来将他们配合起来的。

    其中,配置文件包含bean的id、类、属性及其值,包含一个<beans>元素和数个<bean>子元素。spring ioc框架可以根据bean的id从bean配置文件中取得该bean类,并生成该类的一个实例对象,继而从配置文件中获得该对象的属性和值。

    <!--将指定类配置给spring,让spring创建其对象的实例-->
    <bean id="chinese" class="com.soai.model.chinese">
        <!--property元素用来指定需要容器注入的属性,name指定其属性值为 language,ref指向需要向language属性注入的id,即注入对象“english”,该对象由english实体类生成
        -->
        <property name="language" ref="english" />
    </bean>       
     
    <--配置另外一个bean-->
    <bean id="english" class="com.soai.model.english">

  3.beanfactory采用了工厂设计模式,即bean容器模式,负责读取bean的配置文件,管理对象的生成、加载,维护bean对象与bean对象之间的依赖关系,负责bean的生命周期。对于简单的应用程序来说,使用beanfactory就已经足够管理bean了,在对象的管理上可以获得许多便利性。

    常用的方法:

      getbean(string name):根据bean的id生成该bean的对象。

      getbean(string name,class requiredtype):根据bean的id和相应类生成该bean的对象。

  4.applicationcontext接口提供高级功能的容器,基本功能与beanfactory很相似,

    但它还有以下功能:

      a.提供访问资源文件更方便的方法。

      b.支持国际化消息。

      c.提供文字消息解析的方法。

      d.可以发布事件,对事件感兴趣的bean可以接收到这些事件。

    applicationcontext常用的实现类:

      1.classpathxmlapplicationcontext:读取classpath中的资源(从类路径中的xml文件中加载上下文定义的信息)      

    applicationcontext context= new filesystemxmlapplicationcontext(" d:/ applicationcontext. xml ");

      2.filesystemxmlapplicationcontext:读取指定路径的资源(从文件系统中的xml文件中加载上下文中定义的信息)     

    applicationcontext context= new classpathxmlapplicationcontext(" applicationcontext. xml ");

      3.xmlwebapplicationcontext:需要在web环境下才能运行(从web系统中的xml文件中加载上下文中定义的信息)      

    xmlwebapplicationcontext ac = new xmlwebapplicationcontext(); // 这时并没有初始化容器
    ac.setservletcontext(servletcontext); // 需要指定servletcontext对象
    ac.setconfiglocation("/web-inf/applicationcontext.xml"); // 指定配置文件路径,开头的斜线表示web应用的根目录
    ac.refresh(); // 初始化容器    
 

beanfactory和applicationcontext

  spring ioc容器的设计主要基于以下两个接口:beanfactory和applicationcontext,其中applicationcontext是beanfactory的子接口之一,换句话说:beanfactory是spring ioc容器所定义的最底层接口,只提供了最简单的ioc功能,负责配置,创建和管理bean.而applicationcontext是其最高级的接口之一,并对beanfactory功能做了许多的扩展,所以在绝大多数情况下,都会使用applicationcontext作为spring ioc容器.

di(依赖注入)的实现方式

  注入:bean实例默认在调用类的无参构造器创建对象后,就要对bean实例的属性进行初始化。这个初始化过程是由容器自动完成的,称为注入。

  di注入的实现方式通常有2种:

    1.设置注入:spring调用类的setter方法,通过set方法完成属性赋值

      a.简单类型   

<bean id="bean别名" class="类全限定名称">
    <property name="类属性名" ref="引用类型属性值"/>
</bean>

      b.引用类型

<--ref作为属性-->
<bean id="bean别名" class="类全限定名称">
    <property name="类属性名" ref="引用类型属性值"/>
</bean>

<--ref作为子标签-->
<bean id="bean别名" class="类全限定名称">
    <property name="类属性名">
        <ref="引用类型属性值"/>
    </property>
</bean>

      c.其他类型

    2.构造注入:spring调用类的有参构造器,通过构造方法给属性赋值,每个参数代表着一个依赖

      a.使用name完成构造注入

<constructor-age name="myage" value="22"/>

      b.使用index构造器,参数位置从0开始

<constructor-age index="0" value="..."/>

      c.省略index属性,必须按照构造器的参数位置(顺序)来复制

<constructor-age value="...">

 

 

  

 

 

    

      

 

  

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网