当前位置:天才代写 > tutorial > JAVA 教程 > 软件体系架构模式在J2EE中的应用

软件体系架构模式在J2EE中的应用

2017-11-13 08:00 星期一 所属: JAVA 教程 浏览:426

副标题#e#

本文先容了软件体系架构发生的配景和架构模式的根基理论。重点先容管道与过滤器体系架构模式的布局,实现,优缺点等,然后以J2EE的Servlet Filter为例举办分解它是奈何应用该架构模式的,最后简朴叙述了在其它J2ee应用中(Jboss和Axis)的实践。

软件体系架构

1、软件体系架构发生配景

在经验60年月的软件危机之后,使人们开始重视软件工程的研究。来自差异应用规模的软件专家总结了大量的有代价的常识。 当初,人们把软件设计的重点放在数据布局和算法的选择上,如Knuth提出了数据布局+算法=措施。 可是跟着软件系统局限越来越大、越来越巨大,使软件系统的架构越来越重要。软件危机的水平日益加剧,现有的软件工程要领对此显得力有未逮。对付大局限的巨大软件系统来说,软件体系架构比起对措施的算法和数据布局的选择已经变得明明重要得多。在此种配景下,人们认识到软件体系架构的重要性,并认为对软件体系架构系统、深入的研究将会成为提高软件出产效率息争决软件危机的最有但愿的途径。 这时对软件体系架构的研究如雨后春笋般,呈现了百家争鸣的现象,如Rational公司提出了"以架构为中心"的统一软件开拓进程(RUP)。

2、软件体系架构模式

软件设计的一个焦点问题是可否利用反复的体系架构,即可否到达体系架构级的软件重用。也就是说,可否在差异的软件系统中,利用同一体系架构。基于这个目标,很多学者们开始研究和实践软件体系架构的模式问题。在<Pattern-Oriented Software Architecture (面向模式的软件体系架构) >中首次提出了8种体系布局模式: 层(Layers)、管道和过滤器(Pipes and Filters) 、黑板(Black board )、署理者(Broker)、模子-视图-节制器(Model-View-Controller)、暗示-抽象-节制(Presentation-Abstraction-Control)、微核(Microkernel)、映像(Reflection)。

J2EE体系架构

今朝,J2EE技能已经成为企业级应用的首选平台,基于J2EE技能构建的软件系统越来越多。J2EE代表着先进的软件体系架构想想,很多软件体系架构模式在J2ee中均被遍及应用,从本文起连续先容各架构模式在J2EE中的应用。

管道与过滤器

1、概述

管道和过滤器(Pipes and Filters)体系架构模式是为处理惩罚数据流的系统提供的一种模式。它是由过滤器和管道构成的.每个处理惩罚步调都被封装在一个过滤器组件中,数据通过相邻过滤器之间的管道举办传输。每个过滤器可以单独修改,成果单一,而且它们之间的顺序可以举办设置。下图是管道/过滤器模式的示意图。一个典范的管道/过滤器体系布局的例子是以Unix shell编写的措施。Unix既提供一种标记,以毗连各构成部门(Unix的历程),又提供某种历程运行机缘制以实现管道。另一个著名的例子是传统的编译器。传统的编译器一直被认为是一种管道系统,在该系统中,一个阶段(包罗词法阐明、语法阐明、语义阐明和代码生成)的输出是另一个阶段的输入。

软件体系架构模式在J2EE中的应用

2、问题

如果你正在开拓一个必需处理惩罚或转换输入数据流的系统。把这样的系统作为单个组件实现是不容易的,这有几个原因:系统必需由几个开拓人员同时举办协作开拓,整个系统任务自然就被解析为几个处理惩罚阶段,并且需求很容易变换。因此你就要通过替换或从头排序处理惩罚步调来为未来的机动性作筹划。通过插手这样的机动性,回收现有处理惩罚组件构建是可以办到的。系统的设计尤其是处理惩罚步调的内部毗连,必需思量以下因素:

将来系统的进级通过替换某些处理惩罚步调,或重组步调.

差异的语境中小的处理惩罚步调要比大的组件更易于重用。

不相连的处理惩罚步调不行共享信息。

存在差异的输入数据源,

可以用多种方法输出或存放最终功效。


#p#副标题#e#

3、办理方案与布局

管道和过滤器体系架构模式把系统任务分成为几个独立的处理惩罚步调。这些步调回收通过系统的数据流毗连。一个步调的输出是下一个步调的输入。每个处理惩罚步调由一个过滤器组件实现,它处理惩罚可能转化数据,而且系统的输入可以是多种数据源。

这种体系架构模式具有很多特性,如下:

过滤器是独立运行的部件.也就是除了输入和输出外,每个过滤器不受任何其他过滤器运行的影响.在设计上,过滤器之间不共享任何状态信息。

独立性还表示在它对其处理惩罚的上游和下游毗连的过滤器是"蒙昧"的.它的设计和利用差池与其毗连的任何过滤器施加限制,独一体贴的是其输入数据的,然后举办加工处理惩罚,最后发生数据输出。

#p#分页标题#e#

4、非软件描写 基于各类流体事情的系统,普遍都回收由输送管道毗连起来的处理惩罚布局.譬喻我们冬天见到的供暖系统中,处理惩罚器包罗加热器,过滤器,调理阀,流量表等,每个处理惩罚器都有流体的进口和出口,它们通过各类管道毗连在一起形成了整个系统.这样的布局在都市的自来水系统也可以看到。见下图:

软件体系架构模式在J2EE中的应用

5、利益与缺点

5.1 利益

通过利用过滤器互换增加了机动性

通过重组增加了机动性

过滤器组件的重用

流水线的快速原型

并行处理惩罚提高效率

5.2 缺点

共享状态信息可能昂贵可能不机动

数据转换特别开销。

错误处理惩罚

Servlet2.3 Filter

1、Servlet Filter概述

每每开拓过J2EE的web application的人员都知道,常常需要处理惩罚以下几种环境:

会见特定资源(Web 页、JSP 页、servlet)时的身份认证

应用措施级的会见资源的审核和记录

应用措施范畴内对资源的加密会见,它成立在定制的加密方案基本上

对被会见资源的实时转换, 包罗从 servlet 和 JSP 的动态输出

在servlet2.3之前这些成果处理惩罚是很难实现的,可是Java Servlet 2.3 类型新增了不少冲感人心的成果,个中之一即是过滤器(Filter),其实这就是我们所说的管道和过滤器体系架构在J2EE中的应用实践. 通过利用该模式使得Web Application开拓者可以或许在请求达到Web资源之前截取请求,在处理惩罚请求之后修改应答。其布局图如下:

软件体系架构模式在J2EE中的应用

一个执行过滤器的Java 类必需实现javax.servlet.Filter 接口。这一接口含有三个要领:

init(FilterConfig):这是容器所挪用的初始化要领。它担保了在第一次 doFilter() 挪用前由容器挪用。它能获取在 web.xml 文件中指定的filter初始化参数。

doFilter(ServletRequest, ServletResponse, FilterChain):这是一个完成过滤行为的要领。它同样是上一个过滤器挪用的要领。引入的 FilterChain 工具提供了后续过滤器所要挪用的信息。

destroy():容器在销毁过滤器实例前,doFilter()中的所有勾当都被该实例终止后,挪用该要领。

软件体系架构模式在J2EE中的应用

#p#副标题#e#

2、Filter链先容

所有过滤器都听从挪用的过滤器链,并通过界说明晰的接口获得执行。WebApplication可以指定很多过滤器来完成相关的事情.那么它们就构成一个过滤器链来完成相应的事情.其布局如下图:

软件体系架构模式在J2EE中的应用

3、例子

3.1 简朴filter

在PetStore1.3.1中的就存在两个Filter过滤器.个中一个过滤器,完成字符集的编码的转化,如各人常常碰着的汉字编码问题,你只需设置为GBK即可.它从Web.xml之中读取这些参数的设置信息,然后举办编码的转化.另一个是安详校验Fliter,它认真举办安详查抄哪些页面可以举办,哪些不行。它们构成一个Filter链,布局图和实现代码如下:

软件体系架构模式在J2EE中的应用

public class EncodingFilter implements Filter {
private FilterConfig config = null;
// default to ASCII
private String targetEncoding = "ASCII";
public void init(FilterConfig config) throws ServletException {
this.targetEncoding = config.getInitParameter("encoding");
}
//在过滤器中实现字符集编码转化
public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain chain)
throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest)srequest;
request.setCharacterEncoding(targetEncoding);
// move on to the next
chain.doFilter(srequest,sresponse);
}
public void destroy() {
……………..
}
}
public class SignOnFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
this.config = config;
URL protectedResourcesURL = null;
try {
protectedResourcesURL = config.getServletContext().getResource("/WEB-INF/signon-config.xml");
...............
} catch (java.net.MalformedURLException ex) {
System.out.println("SignonFilter: malformed URL exception: " + ex);
}
}
public void destroy() {
config = null;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
........
}
}

#p#副标题#e#

#p#分页标题#e#

容器通过 Web 应用措施中的设置描写符 web.xml 文件理会过滤器设置信息。有两个新的标志与过滤器相关:<filter> 和 <filter-mapping>。<filter> 标志是一个过滤器界说,它肯定有一个 <filter- name> 和 <filter-class> 子元素。<filter-name> 子元素给出了一个与过滤器实例相关的名字。<filter-class> 指定了由容器载入的实现类。您能随意地包括一个 <init-param> 子元素为过滤器实例提供初始化参数。<filter-mapping> 标志代表了一个过滤器的映射,指定了过滤器会对其发生浸染的 URL 的子集。

<!-- Encoding Filter Declaration Start -->
<filter>
<filter-name>EncodingFilter</filter-name>
<display-name>Encoding Filter</display-name>
<description>no description</description>
<filter-class>com.sun.j2ee.blueprints.encodingfilter.web.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- Encoding Filter Declaration End -->
<!-- Signon Filter Declaration Start -->
<filter>
<filter-name>SignOnFilter</filter-name>
<display-name>SignOn Filter</display-name>
<description>no description</description>
<filter-class>com.sun.j2ee.blueprints.signon.web.SignOnFilter</filter-class>
</filter>
<!-- Signon Filter Declaration End -->
<!-- Encoding Filter Mapping Start-->
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Encoding Filter Mapping End -->
<!-- Signon Filter Mapping Start-->
<filter-mapping>
<filter-name>SignOnFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Signon Filter Mapping End -->

3.2 巨大的filter

上面是petstore的例子,演示了通过Fliter修改字符编码和安详认证的成果。下面提供一个示例演示通过修改返回数据(通过过滤器把response的字符串酿成大写)。

public class UCaseResponse extends HttpServletResponseWrapper {
public UCaseResponse(HttpServletResponse response) {
super(response);
}
public PrintWriter getWriter() throws IOException {
return new UCaseWriter(super.getWriter());
}
}
public class UCaseWriter extends PrintWriter {
public UCaseWriter(Writer out) {
super(out);
}
public void write(int c) {
super.write(Character.toUpperCase( (char) c));
}
public void write(char buf[], int off, int len) {
for (int i = 0;i < len;i++) {
write(buf[off + i]);
}
}
public void write(String s, int off, int len) {
for (int i = 0;i < len;i++) {
write(s.charAt(off + i));
}
}
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {
try {
filterChain.doFilter(request, new UCaseResponse((HttpServletResponse)(response)));
}catch(Exception sx) {
filterConfig.getServletContext().log(sx.getMessage());
}

该示例利用HttpServletResponseWrapper技能,它是对HttpServletResponse的包装,其实就是装饰(decorate)设计模式的应用.这个例子可以或许事情的要害是UCaseResponse和UCaseWriter类,它实现了对每个要输出的字符都转成了大写后再写入实际的输出流的成果。

#p#副标题#e#

4、体系架构的实现

实现一个管道和过滤器一般要留意以下几个方面:

把系统任务分成一系列处理惩罚阶段。

按照管道和过滤器的设计方案,必需把系统处理惩罚的任务支解成相应独立的任务,如日志,数据转化,安详认证等。这样每个阶段仅依赖其前一阶段的输出。通过数据流将所有阶段相连起来。而且你可以举办替换每个步调,可能可以调解它们之间的顺序,以发生新的功效.如petstore中的编码转化Filter和安详Filter,分成两个独立的处理惩罚阶段。

界说沿每个管道传输的数据名目。

我们知道每个过滤器,界说一个统一名目以得到最大的机动性,因为它使过滤器的重组变得容易。如:每个过滤器的要领是doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)它们的参数是必需沟通的。

抉择如何实现每个管道毗连

Filter过滤器的毗连是推得方法来实现的.前一个过滤器主动的挪用filterChain.doFilter(request, response);来实现转向下一个过滤器。

设计和实现过滤器

设计每个Filter具有独立的成果,如编码转化,安详校验,等成果.而且每个Fliter都应该在实现javax.servlet.Filter接口。

成立处理惩罚流水线

过滤器的陈设是在Web.xml中举办设置,描写过滤器的实现类以及它们的map干系,来确定它们的顺序。

其他应用实例

1、JBOSS

#p#分页标题#e#

假如各人对EJB相识,应该知道客户挪用EJB实际上并不是直接引用EJB实例(ejb instance).它通过容器来截获客户端的请求,然后凭据EJB描写符做些很多相应的事情如,安详校验,事务的处理惩罚,线程并发处理惩罚等.这样就可以使开拓人员仅体贴本身的业务逻辑,而不需对巨大的基本处事举办实现.使开拓人员从繁琐的事情中摆脱出来.会合精神处理惩罚本身的业务逻辑,它的布局图如下:

软件体系架构模式在J2EE中的应用

#p#副标题#e#

笔者有幸阅读了JBOSS的源码,阐明白Jboss的EJB容器的实现. EJB的容器通过很多拦截器(Inteceptor)来实现,每个拦截器处理惩罚必然的成果,一个处理惩罚竣事后转发给下一个拦截器,最后一个拦截器才把真正挪用EJB的实例.个中它的EntityBean 容器的拦截器的布局如下:

软件体系架构模式在J2EE中的应用

我们看个中的log拦截器

public class LogInterceptor extends AbstractInterceptor{
public Object invoke(Invocation invocation)
throws Exception
{
boolean trace = log.isTraceEnabled();
// Log call details
if (callLogging)
{
......举办log的处理惩罚
}
//处理惩罚竣事,把请求转发给下一个拦截器
return getNext().invoke(invocation);
}

这些拦截器设置在standardjboss.xml文件中,如下:

<container-interceptors>
<interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.SecurityInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
<interceptor metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntityLockInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntityInstanceInterceptor</interceptor>
<interceptor>org.jboss.resource.connectionmanager.CachedConnectionInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.EntitySynchronizationInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor</interceptor>
</container-interceptors>

这就是Jboss容器架构最巧妙的处所,最初这个架构就是由天才少年Rickard Oberg提出的.其实这个架构就应用我们接头的管道和过滤器模式,其实每个拦截器就是一个过滤器,利用该模式给Jboss带来了如下的长处:

使系统的架构更容易领略,因为每个过滤器完成单一的成果。

使系统越发模块化,有利于系统的模块重用和扩展,假如系统想增加某种成果只需增加一个实现Interceptor接口的拦截器,然后设置在standardjboss.xml文件中即可。

使系统的容易举办错误处理惩罚,假如在一个拦截器中发明错误(error)可能异常(exception),只需返回即可.

2、AXIS

无独占偶,同样在Axis上也应用了管道和过滤器模式.Aixs是apache开源的webservice实现处事器。简朴的说,axis就是处理惩罚Message,它首先截获客户端的请求,然后转发到真正的实现业务逻辑上处理惩罚客户端的请求,在这之前颠末一系列的handler处理惩罚.它的布局很像EJB容器.其实就是管道和过滤器模式的应用,Handler就是过滤器.它的处理惩罚顺序主要思量两个方面一个是陈设描写符(deployment configuration )另一个就是是客户端照旧处事器端。Handler处理惩罚的工具是MessageContext它的由3个重要的部门构成,一是一个request Message,一个是response message,尚有很多属性。

#p#副标题#e#

我们经研究源码阐明,在处事器端,有一个Transport Listener 它监听客户端的请求, 可以通过多种协议,一旦有客户请求,它将凭据协议的类型把数据理会生成生成一个Message工具,然后把它配置到MessageContext,然后挪用一系列的Handler举办处理惩罚。

其布局图如下:

软件体系架构模式在J2EE中的应用

相关设计模式

在利用管道和过滤器模式时,一般会利用以下的GOF设计模式。

1、职责链模式(Chain Of Responsibility)

#p#分页标题#e#

职责链设计模式的意图就是使多个工具都有时机处理惩罚请求,从而制止请求的发送者和吸收者之间的耦合干系。将这些工具连成一条链,并沿着这条链通报该请求,直到有一个工具处理惩罚它为止。其实管道和过滤器模式就是职责链模式的抽象,把它应用到软件体系架构中。

2、 呼吁模式(Command)

呼吁模式的意图将一个请求封装为一个工具,从而使你可用差异的请求对客户举办参数化;对请求列队或记录请求日志,以及支持可除掉的操纵。在管道和过滤器模式中每个过滤器一般利用呼吁模式,把请求封装成一个呼吁举办处理惩罚。

3、装饰模式(Decorator)

装饰模式的意图就是动态地给一个工具添加一些特另外职责。就增加成果来说,Decorator模式对比生成子类更为机动。

在管道和过滤器模式中,在每个过滤器中常常需要对请求进动作态的增加成果,可能修改请求的内容,这时一般会利用装饰模式.如Servlet filter的javax.servlet.http.HttpServletRequestWrapper, javax.servlet.http.HttpServletResponseWrapper就是装饰模式的应用.

总结

本文接头了管道和过滤器模式的办理方案,以及它的优缺点.然后以J2EE类型的Servlet Filter为例具体先容了奈何应用该模式,同时简朴的先容了在Jboss,Axis中的应用。

 

    关键字:

天才代写-代写联系方式