您的位置:首页 > 编程语言

pojo编程模型+轻量级容器+控制反转讲解

2016-12-11 17:58 211 查看

pojo编程模型

POJO的意思是简单的Java对象(Plain Old Java Objects),该名称最先由Martin Fowler、Rebecca Parsons以及Josh MacKenzie提出,从而为常规的Java对象赋予了一个令人兴奋且响亮的名字。POJO代表了一种编程趋势,旨在简化Java应用程序(特别是企业级Java应用程序)的编码、测试以及部署等阶段。

POJO编程模型最重要的优点是编写应用程序类非常快速和简单。这是因为所编写的类不需要依赖任何特定的API,不需要实现任何特定的接口或者扩展自某一特定的框架类。开发人员不需要创建任何特殊的回调方法,除非确实需要使用这些方法。

因为基于POJO的类不依赖任何特定的API或框架代码,所以可以非常容易地通过网络进行传输并在不同层之间使用。因此,也不需要为了通过网络传输数据而创建单独的数据传输对象类。

此外,不再需要为了能够运行和测试自己的类而将类部署到容器中或者等待漫长的部署周期。可以通过使用JUnit在所喜欢的IDE中轻松测试自己的类。不必使用容器内测试框架(比如Cactus)就可以进行集成单元测试。

POJO编程模型可让开发人员从面向对象而不是面向过程的角度来编写代码,从而准确地将问题域反映到解决方案域中。可以通过一个更精细的模型来处理业务逻辑,而该模型在行为方面也可以更加丰富。

轻量级容器

虽然一些人并没有使用EJB来开发他们的应用程序,但仍然利用了前面介绍的许多中间件功能。另一方面,他们通常认为只有将他们的应用程序部署到一个功能齐全的J2EE应用程序服务器上才可以利用这些中间件服务。在当时这可能是一个错误的观点。从技术角度看,完全不使用容器来开发企业级应用程序是可能的。但如果是这样的话,就必须亲自创建和装配组件以及执行所需的中间件服务。显然,这些任务将会极大地分散开发人员的精力,使他们无法专心处理系统的业务需求,从而延迟系统的完成时间。

因此,在实践中,拥有如下一个环境可能会更好:在该环境中,所有组件都被创建和装配,并且提供了所需的中间件服务。这样一个环境被称为容器(container)。Java EE平台就提供了多个这样的容器。每一个专门容器为应用程序的一个特定层提供所需的服务。例如,Servlet容器负责创建和管理应用程序Web层的组件,比如Servlet、JSP、Filter等。而另一方面,EJB容器专注于应用程序的业务层,负责管理其EJB组件。与Java EE平台相类似,Spring Container也是一个容器,在该容器中,应用程序被创建、彼此装配,并以一种轻量级方式提供中间件服务。

当谈到容器时,可以认为任何容器都应该能够向该环境中所管理的组件提供一些基本服务。根据Rod Johnson和Jürgen H?ller所编写的开创性书籍Expert One-on-One J2EE Development Without EJB(Wrox,2004),可以列出如下所示的预期服务:

生命周期管理

依赖解析

组件查找

应用程序配置

除了上述功能之外,如果容器能够提供下面所示的中间件服务,那就更好了:

事务管理

安全性

线程管理

对象和资源池

对组件的远程访问

通过JMX之类的API管理组件

容器的扩展和定制

一个轻量级容器(lightweight container)包括所有上述功能,但并不需要为了依赖这些API而编写应用程序代码。也就是说,轻量级容器没有侵入特性,启动非常快,并且不需要将其部署到一个功能齐全的Java EE应用程序服务器上就能提供上述服务(部署组件是一个非常烦琐的过程)。在企业级Java世界中,Spring Application Framework是最著名的轻量级容器之一。


控制反转

容器及其管理的组件所提供的最重要的好处是可插拔的体系结构。组件需要实现一些接口,并且可以通过类似的接口访问其他组件所提供的服务。组件不需要知道这些服务的具体实现类。因此,可以非常容易地使用一个不同的实现替换系统中的任何组件。而容器的工作则是创建这些组件以及所依赖的服务,并将这些组件装配在一起。

在组件类中,不需要使用新的操作符来实例化依赖组件,而是在运行时由容器实例将依赖组件注入组件。因此,对依赖项的控制由组件转到容器。这种模式被称为控制反转(Inversion of Controll),或者简称为IoC。一般来说,IoC是框架中一个非常重要的概念,可以通过好莱坞原则"不要给我们打电话,我们会给你打电话(don't call us, we'll call you)"来更好地理解IoC的重要性。

IoC被认为是任何容器都需要提供的基本功能之一。它主要有两种形式:依赖查找(dependency lookup)和依赖注入(dependency injection)。

在依赖查找中,容器向其管理的组件提供了回调方法,而组件则通过这些回调方法与容器进行交互并显式地获取它们的依赖项。这种情况下,通常使用一个查找上下文来访问依赖组件以及容器管理的其他资源。

在依赖注入中,组件提供了合适的构造函数或Setter方法,以便容器可以注入依赖组件。一般来说,很少在组件内执行显式依赖查找,大多数情况下,是通过构造函数或Setter方法在创建组件的时候注入依赖项。

在J2EE的最初几年里,所使用的方法主要是依赖查找。在J2EE环境中,前面所提及的查找上下文也被称为JNDI上下文。通过JNDI上下文,可以访问EJB组件以及其他资源,比如JDBC DataSource和JMS ConnectionFactory。图1-3显示了在J2EE平台中通过JNDI API实现的JNDI库不同部分之间的交互。

 





随着Spring Application Framework以及其他轻量级IoC框架的出现,依赖注入方法逐步变得流行起来。这种情况下,组件如何实例化以及需要哪些依赖组件则完全由容器自己的配置机制来确定。容器的任务是处理相关的配置信息,以便在运行时实例化所需的组件并装配依赖项。在J2EE向Jave EE的演化过程中,使用JNDI进行的显式依赖查找被逐步转变为隐式依赖注入方法。如今,当开发人员提及IoC时,通常会被理解为依赖注入。


依赖注入

Setter注入

当一个对象被容器实例化之后就会马上调用Setter方法。该注入在组件的创建或初始化阶段发生,并且在处理业务方法调用之前完成。因此,不存在与调用这些Setter方法相关的线程问题。因为Setter方法是JavaBean规范的一部分,所以外部世界可以更改组件的协作者以及属性值。同样,也可以使用JavaBean属性使简单属性外部化,比如int或boolean值。这样就可以简化代码,使代码可以在不同的环境中重复使用。

Setter注入最重要的优点是在组件创建之后可以进行重新配置。组件的依赖项可以在运行时更改。许多现有的类可以被标准的JavaBean样式编程所使用。换句话说,这些类提供了Getter和Setter方法来访问它们的属性。例如,Jakarta Commons DBCP DataSource提供了一个常用的DataSource实现,并且可以在容器中通过其所带的JavaBean属性进行管理。必要时,可以使用标准JavaBean属性编辑器机制进行类型转换。例如,可以非常容易地将配置中给定的String值转换为需要的类型值,或者将一个位置分解为一个资源实例,等等。如果每一个Setter方法都有一个对应的Getter方法,那就可以获取组件的当前状态并进行保存,以便日后恢复。如果组件的部分或全部属性有默认值,那么可以更容易地使用Setter注入进行配置。你也可酌情提供一些依赖项。

Setter注入最大的缺点是:并不是所有所需的依赖项都可以在使用前被注入,从而使组件处于一种部分配置状态。某些情况下,调用Setter方法的顺序可能非常重要,而该顺序无法在组件约定中得以表达。因此,在创建阶段,容器提供了相关机制来探测并防止此类组件状态不一致的情况发生。

 
构造函数注入

通过构造函数注入,Bean可以利用构造函数参数来表达依赖项,这样就可以在组件创建期间注入依赖项。同样,出于线程安全的考虑,也需要使用构造函数注入。此外,还可以像注入构造函数参数那样注入简单的属性,比如整数值或布尔值。

构造函数注入的最大优点是可以保证容器中每一个被管理的组件都处于一致状态,并且在创建之后可以马上使用。另一个优点是使用构造函数注入所编写的代码量要比使用Setter注入所编写的代码量少一些。

构造函数注入的最大缺点是在组件创建完毕后就无法再对组件进行重新配置,除非为相关属性提供一个Setter作为构造函数参数。为不同的配置选项创建多个重载构造函数可能会造成混乱,在大多数情况下甚至是无法使用的。此外,具体继承也可能有问题,除非你非常仔细地重写超类中的所有构造函数。

Setter注入或构造函数注入

Setter注入方法和构造函数注入方法都有各自的优缺点,在任何应用程序中仅仅使用一种方法是不可能的。你可能拥有一些由第三方特别编写的类,而这些类可能并不具有相关的构造函数来接收适合自己配置情况的合适参数。因此,可能首先需要创建一个带有一个构造函数的组件,而该构造函数接收贴近你需求的参数。然后再使用Setter方法注入其他的依赖项。如果需要在运行时对组件进行重新配置,就必须为特定的属性创建Setter。IoC容器允许开发人员在应用程序配置中针对相同的组件混合使用这两种不同类型的依赖注入方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 框架 web j2ee ioc