资源描述
一、了解中间件背景:课本上1,为了解决分布异构问题
二、什么是中间件:还是第一面
三、IDC的中间件分类:第2面,六大类或者新版本2类
四、中间件的特点及优势:第7面:优势在8,9面吧
五、中间件在应用软件开发中的作用。举例说明!
第二章 应用服务器与JavaEE
一、什么是应用服务器:一个可以通过Internet 来实施电子商务和企业计算的平台,所以有人将它称之为“Internet上的操作系统”
二、为什么Application Server是中间件,流行的产品有哪些:应用服务器是提供运行环境,处理业务逻辑的,也就是通过特定的网络通道来传输数据进行特定的数据交换来实现一些功能。符合中间件的定义
文件服务器 - 如Novell的NetWare :数据库服务器 - 如Oracle数据库服务器,MySQL,PostgreSQL,Microsoft SQL Server等
邮件服务器 - Sendmail,Postfix,Qmail,Microsoft Exchange,Lotus Domino等
网页服务器 - 如Apache,thttpd,微软的IIS等
FTP服务器 - Pureftpd,Proftpd,WU-ftpd,Serv-U等
应用服务器 - 如Bea公司的WebLogic,JBoss,Sun的GlassFish
代理服务器 - 如Squid cache
计算机名称转换服务器 - 如微软的WINS服务器
三、多层应用体系的优势(相比C/S和B/S):
瘦客户:提供简洁的人机交互界面,完成数据的输入/输出。
业务服务(中间层):完成业务逻辑、实现与数据库通信、实现分布式管理 负载均衡、Fail/Recover、安全隔离等。数据服务:提供数据存储。安全性:中间层隔离了客户直接对数据库的访问,保护数据。稳定性:中间层缓冲了客户端与数据库的实际连接,使数据库的连接数量远小于客户端应用数量。易维护:业务逻辑在中间服务器,当业务规则变化后,客户端基本不变。快速响应:通过负载均衡以及缓存数据能力,客户端能够快速响应。系统扩展灵活:可以在中间层部署更多的应用服务。
四、什么是JavaEE:Java EE是一种利用Java 2 平台简化企业解决方案的开发、
部署和管理相关复杂问题的体系结构。
五、JavaEE是多层的应用体系:13面那个图
六、面向对象编程(Object-Oreinted Programming)
基于组件开发(Component-Based Development)
面向服务架构(Service-Oreinted Architecture)
七、JavaEE开发模式:分为非分布式和分布式两大体系结构:非分布式体系结构比较适合于Web应用,它们在一个容器里处理所有的页面逻辑和业务逻辑,所有的应用组件都只运行
在同一个JVM里面。系统变得简单而有效。
1.1数据库构建业务逻辑的Web应用
企业的业务逻辑主要在数据库服务器端,通过使用存储过程、触发器等数据库特有
技术完成。Web容器利用JDBC调用数据库的存储过程获取数据,利用Servlet、Jsp、HTML等处理表示层的逻辑。优点:简单性。速度。测试容易。系统部署简单。缺点:整个应用对数据库的功能和容量要求高。维护不易。数据库代码可能会很复杂。系统扩展性差,数据库性能要求高,性能调整代价大。
1.2具有处理业务逻辑组件的Web应用:Web容器不仅负责表示层,还要处理业务逻辑。
优势J2EE中最常见,结构最简单的开发模式,所谓的“轻量级”企业开发模式。
结构简单。不需EJB容器支持的J2EE应用服务器(Tomcat、Resin)
相应速度快。整个应用运行在同一个JVM内,没有远程调用。
调试和测试容易。代码本地化,无需部署就可调试。
系统部署容易灵活。利用Web应用服务器的负载均衡技术,在多台机器上部署同一应用。
缺点对外只有一个Web接口,除非增加一个Web Service,否则很难支持其它
独立GUI客户端。
2. 整个应用只能运行在一个JVM,无法将组件自由地部署在其它机器上。
3. 没有用到EJB容器的事务支持,需要自己在代码里创建和管理事务。
4. 应用服务器不支持EJB容器,对于开发复杂的企业应用显得力不从心。
1.3 使用本地接口EJB的Web应用:中间业务层的业务接口使用本地EJB实现,而不是采用普通JavaBean
优势具备第二种模式(使用JavaBean)的所有优点。
利用了EJB容器的各种服务,而又没有分布式EJB应用那么复杂。
本地EJB不用远程调用,不需要窜行化,系统性能开销小。
缺点开发相对复杂。
对外也只是一个Web接口,很难支持其它客户端,除非增加Web Service。
整个应用运行在同一JVM,所有组件必须部署在同一物理机器上。
调试不容易。需要运行J2EE应用服务器。
即使是本地调用,仍然慢于普通方法调用。
2.1 1. 使用远程EJB的分布式应用
通过EJB及其调用EJB的组件部署在不同JVM的方式对应用进行物理的以及逻辑的划分
优点:很容易地使用J2EE应用服务器的各种现成的服务,减低开发分布式系统的难度。
通过标准的RMI远程接口来支持所有的J2EE客户类型。
提供灵活的部署方式。允许应用组件在不同物理机器上部署。
缺点:复杂,开发难度大。业务逻辑和表示逻辑的合理划分和设计。
影响性能。应为使用了RMI远程调用。
业务层组件都必须运行在EJB容器内,对J2EE应用服务器要求高。
分布式应用调试和测试都是最难的。
分布式系统使异常的处理变得复杂。
还必须考虑网络故障等引起的传输问题
2.2 具有Web Service 接口的分布式应用:非分布式开发体系结构中各种开发模式为了实现分布式开发的一个扩展模式。在原有的各种模式上增加一个Web Service服务层,不需要RMI和EJB来支持远程客户,而是通过SOAP与中间业务服务器通信。
优点:通信协议SOAP比RMI/IIOP更开放,支持JAVA外其他语言的客户端。
对企业来说,提供标准的Web服务接口比提供远程EJB接口更有好处。
Web Service基于Http协议,与RMI相比,防火墙更友好。
缺点:性能差。通过SOAP和XML协议传递对象的性能比RMI差。
如果客户端都是基于J2EE技术,没有必要采用SOAP。
传输对象编码复杂。Java对象与XML之间作转换,对复杂的Java对象支持差。
第三章 数据访问中间件
一、JDBC类型JDBC(Java Database Connectivity)是Java访问数据库的应用程序接口。JDBC是数据访问中间件(UDA),该接口基于SQL语言,采用同步通信。
连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
二、DAO模式:Data Accessor 模式: 实现了数据访问和业务逻辑的分离,业务层无需关心CRUD操作避免了业务代码中混杂JDBC调用语句。 Active Domain Object 模式: 实现了业务数据的对象化封装。
三、ORM框架:ORM框架采用元数据来描述对象一关系映射细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。
只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。当前ORM框架主要有三种:Hibernate,iBATIS,EclipseLink。消费者的案例<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "
<hibernate-mapping>
<class name= "dao.Customer" table="customer">
<!-- 主键设置 -->
<id name="id" type="string">
<column name="id"></column>
<generator class="uuid"></generator>
</id>
<!-- 属性设置 -->
<property name="username" column="username" type="string"></property>
<property name="balance" column="balance" type="integer"></property>
<set name="orders" inverse="true" cascade="all">
<key column="customer_id" ></key>
<one-to-many class="dao.Order"/>
</set>
</class>
</hibernate-mapping>
第四章 消息中间件MOM
一、什么是Message Oriented Middleware消息中间件作为一个中间层软件,它为分布式系统中创建、发送、接收消息提供了一套可靠通用的方法,实现了分布式系统中可靠的、高效的、实时的跨平台数据传输。
二、企业什么需要MOMMOM指的是利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。
三、Queue和Topic模式
四、同步和异步通信:(UDA数据访问中间件RMI同步)、(RPC、ORB、TMP同)、MOM(异)、同步通信易编程输出立即可知更易恢复错误 (通常)更好实时响应 (通常)但是服务必须启动、在线请求方阻碍占用资源通常要求面向连接的通信协议。异步请求无需指定服务器服务无需在线由于没有占用, 资源可以释放可以使用非连接协议。缺点是响应时间不可预测错误处理通常复杂难以设计程序?
五、MOM特点时间独立性、安全可靠、支持多种数据传送、断点续传、数据压缩等once and only once消息传递和排队技术有以下三个主要特点:1. 通讯程序可在不同的时间运行。2. 对应用程序的结构没有约束。3. 程序与网络复杂性相隔离。
第五章 JMS一、什么是JMS为Java程序提供了一种创建、发送、接收和读取企业消息系统中消息的通用方法。
二、JMS的消息类型
三、被管理的对象ConnectionFactory: 客户端用来创建同JMS提供者之间的连接的对象。
Destination :这个对象是客户端用来指明消息被发送的目的地以及客户端接收消息的来源。
被管理的对象一般被管理员放在JNDI名字空间中,通常在JMS客户端应用的文档中说明它所需要的JMS被管理对象,以及应以何种JNDI名字来提供这些JMS被管理对象。
四、JMS客户端编程
五、JMS中的Session:JMS 会话是一个用来生产和消费消息的单线程的上下文。会话服务于以下几个目的:1. 它是MessageProducers和MessageConsumers 的工厂。2. 它是TemporaryTopics和TemporaryQueues的工厂。3. 它为那些需要动态操作提供者指定目的名称的客户端创建Queue 或Topic对象。4. 它支持独立序列的事务。5. 它定义了消息的顺序。6. 它保留消费的消息,直到这些消息确认已经接收。7. 有顺序地执行MessageListener。8. 它是QueueBrowser的工厂(直接浏览)
六、JMS与RMI:
1. 通信方式不同
JMS支持同步和异步消息处理模式。
RMI基于请求/应答的同步通信模式。
2. 耦合度不同
JMS建立了一个松散耦合的通信框架。图
RMI是紧耦合结构。图二
3. 需求对象获得方式
JMS:对象从网络的某个节点移动到另一个节点。
RMI:对象是绑定在本地JVM 中,只有参数和返回值是通过网络传送。
第六章 CORBA分布对象技术
一、什么是CORBA公共对象请求代理结构,为解决分布式处理环境(DCE)中,硬件和软件系统的互连而提出的一种解决方案。
二、ORB对象请求代理(ORB,Object Request Broker)是对象之间建立客户端/服务端(Client/Server)关系的中间件。使用ORB,客户可以透明地调用一个服务对象上的方法,这个服务对象可以在本地,也可以在通过网络连接的其他机器上。ORB截获这一调用,同时负责查找实现服务的对象并向其传递参数、调用方法并返回最终结果。客户并不知道服务对象位于什么地方、它的编程语言和操作系统是什么,也不知道不属于对象接口的其他系统部分。这样,ORB在异构分布环境下为不同机器上的应用提供了互操作性,并无缝地集成了多种对象系统。
三、OMA的CORBA体系结构
)对象请求代理 (Object Request Broker,ORB)。负责对象在分布环境中透明地收发请求和响应,它是构建分布对象应用、在异构或同构环境下实现应用间互操作的基础。
(2)对象服务(Object Services)。为使用和实现对象而提供的基本对象集合,这些服务应独立于应用领域。主要的CORBA服务有:名录服务(Naming Service)、事件服务(Event Service)、生命周期服务(Life Cycle Service)、关系服务(Relationship Service)以及事务服务(Transaction Service)等。这些服务几乎包括分布系统和面向对象系统的各个方面,每个组成部分都非常复杂。
(3)公共设施(Common Facilitites)。向终端用户提供一组共享服务接口,例如系统管理、组合文档和电子邮件等。
(4)应用接口(Application Interfaces)。由销售商提供的可控制其接口的产品,相应于传统的应用层表示,处于参考模型的最高层。
(5)领域接口(Domain Interfaces)。为应用领域服务而提供的接口,如OMG组织为PDM系统制定的规范。
四、对象模型和参考模型对象模型:定义如何描述分布式异构环境中的对象。网络环境中的分布对象如何以实现无关的方式进行描述。参考模型:描述对象之间的交互。分布对象间如何通过ORB进行交互。
五、IDL IDL接口定义语言不是作为程序设计语言体现在CORBA体系结构中的,
而是用来描述产生对象调用请求的客户对象和服务对象之间的接口的语言。IDL文件描述了服务器提供的服务功能,客户机可以根据该接口文件描述的方法向服务器提出业务请求。
六、Stub 和 Skeleton133页
七、CORBA的命名服务CosNaming
必须为操作中的每一个参数指明方向属性!!!
in :由客户机在运行时声明参数的类型并赋值,服务器只能使用不能修改其值。
out:由客户机在运行时声明参数的类型,服务器运行中为其赋值。
inout:由客户机在运行时声明参数的类型并赋值,服务器可以使用或修改其值。
any 可以和任意的数据类型匹配,也可以在运行中被动态转换为任意数据类型。
实例module MeineBank {
exception BankFehler { //异常定义
string info;
}; //基本账户
interface BasisKonto {
readonly attribute long nummer;
double einzahlen ( in double betrag ) raises ( BankFehler )//存钱
};//接口继承---支票账号
interface GiroKonto : BasisKonto {
double attribute dispoKredit;//信贷额度
}; //储蓄账号
interface SparKonto : BasisKonto {
double attribute zinssatz;//存款利率
}; //接口多重继承
//interface GiroSparKonto : SparKonto, GiroKonto {......};};
例如:
CosNaming::Name_var name(4);
name.length(4);//注意:下标从0开始。
name[0].id = CORBA::string_dup("aa");
name[0].kind = CORBA::string_dup("");
name[1].id = CORBA::string_dup("bb");
name[1].kind = CORBA::string_dup("");
name[2].id = CORBA::string_dup("cc");
name[2].kind = CORBA::string_dup("");
name[3].id = CORBA::string_dup("dd");
name[3].kind = CORBA::string_dup("");
CosNaming::NamingContextExt::StringName strName; //调用to_string
strName = root_cxt->to_string(name);
//调用to_name
name = root_cxt->to_name("aa/bb/cc/dd");
命名服务的具体过程示例:
/************* 1.初始化部分 ***************/
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); //初始化orb
//初始化命名服务,即初始化命名树或初试化命名环境
CORBA::Object obj = orb->resolve_initial_references("NameService")
CosNaming::NamingContextExt_var root_cxt;
root_cxt = CosNaming::NamingContextExt::_narrow(obj);
/************* 2.将名字帮定到命名环境中 ***************/
//区分:名字和命名环境是两个不同概念。
//名字为:CosNaming::Name_var,命名环境为:CosNaming::NamingContext。//方法一:
//创建一个新的命名环境
CosNaming::NamingContext_var aa_cxt;
aa_cxt = root_cxt->new_context();
//初始化名字
CosNaming::Name_var name;
name.length(1);
name[0].id = CORBA::string_dup("aa");
name[0].kind = CORBA::string_dup("");
//在初始化环境中绑定新的名字
root_cxt->bind_context(name, aa_cxt); //rebind_context( )//方法二:
//定义一个新的命名环境
CosNaming::NamingContext_var aa_cxt;
CosNaming::Name_var name; //初始化名字
name.length(1);
name[0].id = CORBA::string_dup("aa");
name[0].kind = CORBA::string_dup("");
aa_cxt = root_cxt->bind_new_context(name); //绑定
/************* 3.绑定对象引用 ***************/
//绑定,obj_ref为对象引用
aa_cxt->bind(name, obj_ref); //rebind()
/************* 4.获得对象引用 ***************/
CosNaming::Name_var name; //设置名字(方法一)
name.length(1);
name[0].id = CORBA::string_dup("aa");
name[0].kind = CORBA::string_dup("");
CORBA::Object_var obj; //获得引用
obj = root_cxt->resolve(name);
//再使用narrow即可.
CORBA::Object_var obj; //获得引用(方法二)
obj = root_cxt->resolve("aa");
第七章 JavaRMI
一、什么是RMI
二、定义一个远程接口
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface InterfaceService extends Remote {
Object service(Object obj) throws RemoteException;
}
/**
* RMI服务对象接口实现, 此对象将被RMI服务器导出做为远程服务对象
* @author 王华东
*/
// 远程接口必须继承java.rmi.server.RemoteServer或它的子类
public class ImpService extends java.rmi.server.UnicastRemoteObject
implements InterfaceService {
public ImpService() throws java.rmi.RemoteException {
super();
}/*** 客户端将要调用的方法示例*/
public Object service(Object obj) {
System.out.println("RMI客户机请求: "+obj);
return System.currentTimeMillis()/1000 + ": "
+ obj.toString(); }}
import java.rmi.*;
import java.rmi.registry.*;
/**
* 启动RMI服务器,导出服务对象
* @author 王华东
*/
public class StartRMIServer {
/**启动方法*/
public static void main(String[] args) {
int listerPort=9911; //设置RMI监听器在9911端口
String serverIP="localhost"; //监听的IP
String serviceObjName="service"; //要导出的服务对象名字
try {
LocateRegistry.createRegistry(listerPort); //设置RMI服务器监听端口
ImpService.setLog(System.out); //设置日志对象,打印到控制台
ImpService remoteObj = new ImpService(); //创建导出的对象, 绑定服务
Naming.rebind("rmi://"+serverIP+":"+listerPort+"/"+serviceObjName, remoteObj);
System.out.println("RMI启动在"+serverIP+": "+listerPort+" 服务名为: "+serviceObjName);
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();}}}
import java.rmi.*;
/**
* RMI调用客户端
* @author 王华东
*/
public class RmiClient {
public static void main(String[] args) {
int listerPort=9911;//设置RMI监听器在9911端口,1099是默认端口
String serverIP="localhost";//监听的IP
String serviceObjName="service";//要导出的服务对象名字
try {
//查找服务器上的服务对象
InterfaceService stub = (InterfaceService)
Naming.lookup("rmi://"+serverIP+":"+listerPort+"/"+serviceObjName);
for(int i=0;i<10;i++){
//调用对象的服务方法
Object response = stub.service("请说话....."+i);
System.out.println("RMI服务器应答:" + response.toString());
Thread.sleep(1000);
}
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
第八章 XML
一、XML 与 HTML:95和96页
二、写一个Student.xml文档:这个就不会了
三、DOM基于树的API 和SAX接口基于事件:
目标文件publication.xml
<?xml version="1.0" encoding="UTF-8"?>
<publication>
<book>
<Title>Think in C++</Title>
<Writer>Bruce Eckel</Writer>
<PublishDate>2000-08-10</PublishDate>
</book>
<book>
<Title>Think in Java</Title>
<Writer>Bruce Eckel</Writer>
<PublishDate>1999-04-01</PublishDate>
</book>
</publication>
import java.io.*;
import javax.xml.parsers.*; //
import org.w3c.dom.*; //
public class UseDomPrintElements{
public static void main(String[] args){
try{
//得到DOM解析器的工厂实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//从DOM工厂获得DOM解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//DOM解析器解析XML文档得到Document对象,Document对象代表整个XML文档
Document document = builder.parse(new File("publication.xml"));
//得到Dom树的根节点
Element element = document.getDocumentElement();
NodeList nodelist = element.getChildNodes(); //得到子节点列表
getElement(nodelist); //用递归实现DOM树的遍历
} catch(Exception e){
e.printStackTrace();}
}
public static void getElement(NodeList nodelist){
Node cnode;
String str;
if(nodelist.getLength()= =0)
{return;}
for(int i=0;i<nodelist.getLength();i++){
cnode = nodelist.item(i);//返回集合中第index项
if(cnode.getNodeType()==Node.ELEMENT_NODE){//该节点为Element
System.out.println(cnode.getNodeName());
getElement(cnode.getChildNodes());}//递归调用
else if(cnode.getNodeType()==Node.TEXT_NODE){//该节点为TEXT节点
str=cnode.getNodeValue().trim();//返回String副本忽略前后空白
if(str.length()>0)
System.out.println(" "+str);}
}
}
}使用DOM修改XML文档UseDomEditElement
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
public class UseDomEditElement{
public static void main(String[] args){
Text textMsg;
try{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("publication.xml"));
Element root = document.getDocumentElement();//获得根节点
Element book = document.createElement("book");//增加一个Element节点
Element title =document.createElement("Title");//增加一个Element节点
textMsg=document.createTextNode("MiddlewareTech");//增加一个Text节点
title.appendChild(textMsg);
book.appendChild(title);//把title节点转化为book的子节点
Element writer =document.createElement("Writer");
textMsg=document.createTextNode("wanghuadong");
writer.appendChild(textMsg);
book.appendChild(writer);//把writer节点转化为book的子节点
Element date = document.createElement("PublishDate");
textMsg=document.createTextNode("1994-02-23");
date.appendChild(textMsg);
book.appendChild(date);//把date节点转化为book的子节点
root.appendChild(book);//把book节点转化为root的子节点
//实现获得将DOM文档转化为XML文档的转化器
TransformerFactory tFactory = TransformerFactory.newInstance();
// 类Transformer 实现转化
Transformer transformer = tFactory.newTransformer();
DOMSource source = n
展开阅读全文