Java学习笔记-《Java程序员面试宝典》-第5章Java Web-5.3框架(5.3.11-5.3.13)

5.3.11 什么是IoC

控制反转(Inverse of Control,IoC)有时也称为依赖注入,是一种降低对象之间耦合关系的设计思想。一般而言,在分层体系结构中,都是上层调用下层的接口,上层依赖于下层的执行,即调用者依赖于被调用者。而通过Ioc方式,使得上层不再依赖于下层的接口,即通过一定的机制来选择不同的下层实现,完成控制反转,使得由调用着决定被调用者。IoC通过注入一个实例化的对象来达到解耦合的目的。使用这种方法后,对象不会被显式的调用,而是根据需求通过IoC容器(例如Spring)来提供。
采用IoC机制能够提高系统的可扩展性,如果对象之间通过显式调用进行交互会导致调用者与被调用者存在着非常紧密的联系,其中一方的改动会导致程序出现很多的改动,例如,要为一家茶店提供一套管理系统,在这家商店刚开业时只卖绿茶,随着规模的扩大或者根据具体销售量,未来可能会随时改变茶的类型,例如红茶等,传统的实现方式会针对茶抽象化一个基类,绿茶类只需要继承自该基类即可,如下图所示:
这里写图片描述
采用该实现方法后,在需要使用GreenTea时,只需要执行以下代码即可:AbstractTea t = new GreenTea(),当然,这种方法是可以满足当前设计要求的,但是该方法的可扩展性不好,存在着不恰当的地方,例如商家发现绿茶的销售并不好,决定开始销售红茶,那么需要实现一个BlackTea类,并且让这个类继承自AbstractTea即可。但是,系统中用到的AbstractTea t = new GreenTea()都需要改为AbstractTea t = new BlackTea(),而这种创建对象实例额方法往往会导致程序的改动量非常大。
那怎么样才能增强系统的可扩展性呢?–设计模式。此时可以使用设计模式中的工厂模式来把创建对象的行为包装起来,实现方法如下图:
这里写图片描述
通过以上的方法,可以把创建对象的过程委托给TeaFactory来完成,在需要使用Tea对象时,只需要调用Factory类的getTea方法即可,具体创建对象的逻辑在TeaFactory中来实现,那么当商家需要把绿茶替换为红茶时,系统只需要改动TeaFactory中创建对象的逻辑即可,采用了工厂模式后,只需要在一个地方做改动就可以满足要求,这样就增强了系统的可扩展性。
虽然采用工厂设计模式后,增强了系统的可扩展性,但是本质上来讲,工程模式只不过把程序中会变动的逻辑移动到工厂类里面了,当系统中类较多时,在系统扩展时需要经常改动工厂类中的代码。而采用IoC设计思想后,程序会有更好的扩展性,下面介绍Spring框架在采用Ioc后的实现方法,如下图:
这里写图片描述
Spring容器将会根据配置文件来创建调用者对象(sale),同时把被调用的对象(Abstract-Tea的子类)的实例化对象通过构造函数或set()方法的形式注入到调用者对象中。
1.创建名为SpringConfig.xml的文件
这里写图片描述
2.在实现Sale类时,需要按照如下方式实现
这里写图片描述
当Spring容器创建Sale对象时,根据配置文件SpringConfig.xml就会创建一个BlueTea的对象,作为Sale构造函数的参数。当需要把BlueTea修改为BlackTea时,只需要修改上述配置文件,而不需要修改代码。
在需要Sale时,可以通过如下方式来创建Sale对象:

ApplicationContext ctx = new FileSystemXmlApplicationContext("SpringConfig.xml");
Sale s = (Sale)ctx.getBean("sale");

上例中,Spring采用IoC的方式来实现把实例化的对象注入到开发人员自定义的对象中,有较强的可扩展性。
具体而言,IoC主要有以下两个方面的优点:
1>通过IoC容器,开发人员不需要关注对象如何被创建的,同时增加新类也非常方便,只需要修改配置文件即可实现对象的”热插拔”
2>IoC容器可以通过配置文件来确定需要注入的实例化对象,因此非常便于进行单元测试。
尽管如此,IoC也有自身的缺点,具体表现为以下两点:
1>对象是通过反射机制实例化出来的,因此会对系统的性能有一定的影响
2>创建对象的流程变得复杂。

5.3.12 什么是AOP

面向切面编程(Aspect-oriented Programming,AOP)是对面向对象开发的一种补充,它允许开发人员在不改变原来模型的基础上动态的修改模型以满足新的需求,例如,开发人员可以在不改变原来业务逻辑模型的基础上可以动态的增加日志、安全或异常处理的功能。
下面介绍一个在Spring中使用AOP编程的简单例子。
1>创建一个接口TestAOPIn以及实现这个接口的类TestAOPImpl
这里写图片描述
这里写图片描述
2>配置SpringConfig.xml,使得这个类的实例化对象可以被注入到使用这个对象的Test类中
这里写图片描述
3>在完成配置文件之后,编写如下测试代码
这里写图片描述
运行结果为:
TestAOPImpl:doSomething
编写完这个模块后,开发人员需要增加对doSomething()方法调用的跟踪,也就是说,要跟踪该方法何时被调用以及调用何时结束等内容。当然,也可以使用传统方法实现该功能,但会产生额外的开销,即需要修改已存在的模块。此时可以采用AOP的方式来实现这个功能。它在不修改原有模块的前提下可以完成相同的功能。
这里写图片描述
实现原理如下图:
这里写图片描述
traceBeforeCall.java文件的内容如下所示:

public class traceBeforeCall implements MethodBeforeAdvice{
    public void beforeCall(Method arg0,Object[] arg1,Object arg2) throws Throwable{
        System.out.println("beginCall doSomething");
    }
}

traceEndCall.java文件的内容如下所示:
这里写图片描述
只需在配置文件中配置在调用doSomething()方法之前需要调用traceBeforeCall类的beforeCall()方法以及在调用doSomething方法前后自动调用对应的方法,通过在beforeCall()方法和afterCall()方法中添加跟踪代码就可以满足对doSomething()方法调用的跟踪要求,同时还不需要更改原来已实现的代码模块。

5.3.13 什么是Spring框架

Spring是一个J2EE框架,这个框架提供了对轻量级IoC的良好支持,同时也提供了对AOP技术非常好的封装。相比其他框架,Spring框架的设计更加模块化,框架内的每个模块都能完成特定的工作,而且各个模块可以独立的运行,不会相互牵制,因此,在使用Spring框架开发时,开发人员可以使用整个框架,也可以只使用框架内的一部分模块,例如只使用Spring AOP模块来实现日志管理功能,而不需要使用其他模块。
Spring框架主要由7个模块组成,分别是Spring AOP、Spring ORM、Spring DAO、Spring Web、Spring Context、Spring Web MVC、Spring Core等。Spring框架图如下图:
这里写图片描述
下面是各模块的作用:

  1. Spring AOP:采用了面向切面编程的思想,使Spring框架管理的对象支持AOP,同时这个模块也提供了事务管理,可以不依赖具体的EJB组件,就可以将事务管理集成到应用程序中
  2. Spring ORM:提供了对现有ORM框架的支持,例如Hibernate、JDO等
  3. Spring DAO:提供了对数据访问对象(Data Access Object,DAO)模式和JDBC的支持。DAO可以实现把业务逻辑与数据库访问的代码实现分离,从而降低代码的耦合度。通过对JDBC的抽象,简化了开发工作,同时简化了对异常的处理(可以很好的处理不同数据库厂商抛出的异常)
  4. Spring Web:提供了Servlet监听器的Client和Web应用的上下文。同时还集成了一些现有的Web框架,例如Structs
  5. Spring Context:扩展核心容器,提供了Spring上下文环境,给开发人员提供了很多有用的服务,例如国际化、E-mail和JNDI访问等
  6. Spring MVC:提供了一个构件Web应用程序的MVC的实现
  7. Spring Core:Spring框架的核心容器,它提供了Spring框架的基本功能,这个模块中最主要的一个组件为BeanFactory,它使用工厂模式来创建所需的对象。同时BeanFactory使用IOC思想,通过读取XML文件的方式来实例化对象,可以说BeanFactory提供了组件生命周期的管理,组建的创建、装配、销毁等功能。

Spring的工作原理如下图所示:
这里写图片描述
可以看出,Spring不仅可以在Web容器中用来管理Web服务器端的模块,例如SAervlet,还可以用来管理用于访问数据库的Hibernate。由于Spring在管理Business Object(业务对象)和DAO时使用了IoC和AOP思想,因此这些被Spring管理的对象都可以脱离EJB单独进行运行和测试。在需要被Spring容器管理时,只需要增加配置文件,Spring框架就会根据配置文件与相应的机制实现对这些对象的管理。
除此之外,使用Spring还有如下好处:
1)在使用J2EE开发多层应用程序时,Spring有效地管理了中间层的代码,由于Spring采用的控制反转(IoC)和面向切面编程的思想(AOP),因此这些代码非常容易进行单独测试
2)使用Spring有助于开发人员培养一个良好的编程习惯:面向接口编程而不是面向类编程。面向接口编程使得程序有更好的扩展性。
3)Spring对数据的存取提供了一个一致的框架(不论是JDBC还是O/R映射的框架,例如Hibernate或JDO)
4)Spring通过支持不同的事务处理API(如JTA、JDBC、Hibernate等)的方法对事物的管理提供了一致的抽象方法。
5)使用Spring框架编写的大部分业务对象不需要依赖Spring。

猜你喜欢

转载自blog.csdn.net/qq_28814687/article/details/77340984