Archive for the ‘Java’ Category

oracle锁表

如果一个用户正在更新某张表但没有提交,另一个用户就不能对同一张表使用update命令操作

        SimpleDateFormat sdfParse = new SimpleDateFormat(”MMMMM dd, yyyy”, Locale.ENGLISH);        SimpleDateFormat sdfFormat = new SimpleDateFormat(”yyyy-MM-dd”);        SimpleDateFormat comFormat = new SimpleDateFormat(”yyyyMMdd”);                long start = System.currentTimeMillis();        Config.init(”app.properties”);                //prepare db        StringBuilder sql = null;        Statement st = null;        Connection conn = null;        try{            [...]

1:选择或者创建一个新的套接字。(可以参看SUN´S的”创建一个典型的套接字”)。
2:创建一个服务器端的套接字
3:创建一个RMIClientSocketFactory
4:创建一个RMIServerSocketFactory
5:创建一个继承了UnicastRemoteObjec的远程对象,从而使用新的factories
根据这一大致的想法,我们来看每一步如何具体的实现。
步骤1: 创建ZipSocket
由于要进行Zip压缩,我们重新创建这样的套接字
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import java.net.Socket;
public class ZipSocket extends Socket {
private InputStream in;
private OutputStream out;
public ZipSocket() { super(); }
public ZipSocket(String host, int port) throws IOException {
super(host, port);
}
public InputStream getInputStream() throws IOException {
if (in == null) {
in = new ZipInputStream(super.getInputStream());
}
return in;
}
public OutputStream getOutputStream() throws IOException {
if (out [...]

Java多线程设计要点

1.多线程中有主内存和工作内存之分, 在JVM中,有一个主内存,专门负责所有线程共享数据;而每个线程都有他自己私有的工作内存, 主内存和工作内存分贝在JVM的stack区和heap区。
2.线程的状态有’Ready’, ‘Running’, ‘Sleeping’, ‘Blocked’, 和 ‘Waiting’几个状态,’Ready’ 表示线程正在等待CPU分配允许运行的时间。
3.线程运行次序并不是按照我们创建他们时的顺序来运行的,CPU处理线程的顺序是不确定的,如果需要确定,那么必须手工介入,使用setPriority()方法设置优先级。
4.我们无从知道一个线程什么时候运行,两个或多个线程在访问同一个资源时,需要synchronized
5. 每个线程会注册自己,实际某处存在着对它的引用,因此,垃圾回收机制对它就“束手无策”了。
6. Daemon线程区别一般线程之处是:主程序一旦结束,Daemon线程就会结束。
7. 一个对象中的所有synchronized方法都共享一把锁,这把锁能够防止多个方法对通用内存同时进行的写操作。synchronized static方法可在一个类范围内被相互间锁定起来。
8. 对于访问某个关键共享资源的所有方法,都必须把它们设为synchronized,否则就不能正常工作。
9. 假设已知一个方法不会造成冲突,最明智的方法是不要使用synchronized,能提高些性能。
10. 如果一个\”同步”方法修改了一个变量,而我们的方法要用到这个变量(可能是只读),最好将自己的这个方法也设为 synchronized。
11. synchronized不能继承, 父类的方法是synchronized,那么其子类重载方法中就不会继承“同步”。
12. 线程堵塞Blocked有几个原因造成:
(1)线程在等候一些IO操作
(2)线程试图调用另外一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。
13.原子型操作(atomic), 对原始型变量(primitive)的操作是原子型的atomic. 意味着这些操作是线程安全的, 但是大部分情况下,我们并不能正确使用,来看看 i = i + 1 , i是int型,属于原始型变量:
(1)从主内存中读取i值到本地内存.
(2)将值从本地内存装载到线程工作拷贝中.
(3)装载变量1.
(4)将i 加 1.
(5)将结果给变量i.
(6)将i保存到线程本地工作拷贝中.
(7)写回主内存.
注意原子型操作只限于第1步到第2步的读取以及第6到第7步的写, i的值还是可能被同时执行i=i+1的多线程中断打扰(在第4步)。
double 和long 变量是非原子型的(non-atomic)。数组是object 非原子型。
14. 由于13条的原因,我们解决办法是:

class xxx extends Thread…{

//i会被经常修改
private int i;

public synchronized int read()…{ return i;}

public synchronized void update()…{ i = i + [...]

http状态码的含义:
1**:请求收到,继续处理
2**:操作成功收到,分析、接受
3**:完成此请求必须进一步处理
4**:请求包含一个错误语法或不能完成
5**:服务器执行一个完全有效请求失败
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求
也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下
一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本
==========================================================
英文版:
100:Continue
101:Switching Protocols
102:Processing
200:OK
201:Created
202:Accepted
203:Non-Authoriative Information
204:No Content
205:Reset Content
206:Partial Content
207:Multi-Status
300:Multiple Choices
301:Moved Permanently
302:Found
303:See Other
304:Not Modified
305:Use Proxy
306:(Unused)
307:Temporary Redirect
400:Bad Request
401:Unauthorized
402:Payment Granted
403:Forbidden
404:File Not Found
405:Method Not Allowed
406:Not Acceptable
407:Proxy Authentication Required
408:Request Time-out
409:Conflict
410:Gone
411:Length Required
412:Precondition Failed
413:Request Entity Too Large
414:Request-URI Too Large
415:Unsupported Media Type
416:Requested range not satisfiable
417:Expectation Failed
422:Unprocessable Entity
423:Locked
424:Failed Dependency
500:Internal Server Error
501:Not Implemented
502:Bad Gateway
503:Service Unavailable
504:Gateway Timeout
505:HTTP Version Not Supported
507:Insufficient Storage
1.httpclient实现.
HttpClient client = new HttpClient();
GetMethod get = new GetMethod(”http://the.page.you.want.to.get”);
UsernamePasswordCredentials [...]

使用dom4j的xPath解析XML

books.xml: <?xml version=”1.0″ encoding=”UTF-8″?> <books>     <!–This is a test for dom4j, jakoes, 2007.7.19–>     <book show=”yes” url=”lucene.net”>         <title id=”456″>Lucene Studing</title>     </book>     <book show=”yes” url=”dom4j.com”>         <title id=”123″>Dom4j Tutorials</title>     </book>     <book show=”no” url=”spring.org”>         <title id=”789″>Spring in Action</title>     </book>     <owner>O’Reilly</owner> </books>
下面我们使用dom4j的xPath来解析:
segment of ParseXML.java:
[...]

J2EE架构分析

J2EE架构是当前主流的架构之一,目前大多数企业采用J2EE技术的结构设计与解决方案。J2EE体系结构提供中间层集成框架用来满足无需太多费用而 又需要高可用性、高可靠性以及可扩展性的应用的需求。通过提供统一的开发平台,J2EE降低了开发多层应用的费用和复杂性,同时提供对现有应用程序集成强 有力支持,完全支持Enterprise JavaBeans,有良好的向导支持打包和部署应用,添加目录支持,增强了安全机制,提高了性能。
高效的开发: J2EE允许公司把一些通用的、很繁琐的服务端任务交给中间件供应商去完成。这样开发人员可以集中精力在如何创建商业逻辑上,相应地缩短了开发时间。高级中间件供应商提供以下这些复杂的中间件服务:

状态管理服务 – 让开发人员写更少的代码,不用关心如何管理状态,这样能够更快地完成程序开发。
持续性服务 – 让开发人员不用对数据访问逻辑进行编码就能编写应用程序,能生成更轻巧,与数据库无关的应用程序,这种应用程序更易于开发与维护。

分布式共享数据对象CACHE服务 – 让开发人员编制高性能的系统,极大提高整体部署的伸缩性。

支持异构环境: J2EE能够开发部署在异构环境中的可移植程序。基于J2EE的应用程序不依赖任何特定操作系统、中间件、硬件。因此设计合理的基于 J2EE的程序只需开发一次就可部署到各种平台。这在典型的异构企业计算环境中是十分关键的。J2EE标准也允许客户订购与J2EE兼容的第三方的现成的 组件,把他们部署到异构环境中,节省了由自己制订整个方案所需的费用。
可伸缩性: 企业必须要选择一种服务器端平台,这种平台应能提 供极佳的可伸缩性去满足那些在他们系统上进行商业运作的大批新客户。基于J2EE平台的应用程序可被部署到各种操作系统上。例如可被部署到高端UNIX与 大型机系统,这种系统单机可支持64至256个处理器。J2EE领域的供应商提供了更为广泛的负载平衡策略。能消除系统中的瓶颈,允许多台服务器集成部 署。这种部署可达数千个处理器,实现可高度伸缩的系统,满足未来商业应用的需要。

J2EE使用多层的分布式应用模型,应用逻辑按功能划分为组件,各个应用组件根据他们所在的层分布在不同的机器上。传统的J2EE多层企业级应用模型将 两层化模型中的不同层面切分成许多层。一个多层化应用能够为不同的每种服务提供一个独立的层,以下是 J2EE 典型的四层结构:
Ø    运行在客户端机器上的客户层组件
Ø    运行在J2EE服务器上的Web层组件
Ø    运行在J2EE服务器上的业务逻辑层组件
Ø    运行在EIS服务器上的企业信息系统(Enterprise information system)层软件
通常认为,J2EE平台就广泛的认为是这个架构,运行在J2EE服务器上的EJB容器可以认为是此结构的核心,EJB容器管理着所有EJB的执行,以及EJB的生命周期,并且为EJB提供所有系统级的服务。EJB组件则负责接受,处理WEB容器的客户请求和连接提供整个企业使用的数据,服务的EIS层。
此“经典”架构中,所有的数据访问都要通过entity bean,业务对象都是带远程接口的无状态session bean,运行在EJB容器中。 EJB中包含了各种服务(比如声明式的事务管理),而且提供了一个共享的中间层,可支持可支持各种类型的J2EE客户端。但结构中应用性能和开发开销的负 担很重,一些负载来在于EJB,而很大还是与分布式架构的特性有关。此外为了分布化,牺牲了OO原则,并且难以测试,因为业务逻辑通常编写在EJB的实现 类中,而这些类完全依赖于EJB容器的。
此“经典”架构的一种改进,便是把远程EJB替换为本地EJB,实现了架构的重用,解决了分布化的种种问题。但架构还是相当的复杂。EJB的很多负担还是存在,从EJB中获得益处反而不多。

所以随着企业级应用开发的不断复杂,对架构设计的要求也会提出新的要求:

架构简单,但功能强大。
架构可以通过配置WEB容器集群来达到横向扩展。
在不同的应用服务器之间具有高移植性。

便于在应用服务器之外进行业务对象的单元测试,而且,一些集成测试甚至可以让一些轻量级容器(如Junit)来完成。

为了解决经典架构中有EJB引起的一系列问题以及满足不断发展的企业应用,提出了非EJB架构的“轻量级容器”。轻量级容器与EJB架构都是有容器管理业 务服务对象,然后再围绕着这个服务层组织整个架构。但是业务对象不是运行在EJB容器中,而是运行在“轻量级容器”中。轻量级容器并没有和J2EE绑定, 所以它既可以运行在WEB容器里,也可以在一个标准应用程序中运行,如必要也可以运行在EJB容器中。这个容器也没有和servlet API绑 定?D?D这一点与MVC结构的WEB框架不同。轻量级容器的启动开销很小,而且无需EJB的部署。
轻量级容器提供了一种 管理、定位业务对象的办法。用不着JNDI寻址、定制服务器之类的额外辅助;轻量级容器为应用对象提供注册服务。其较之EJB容器而言,不仅功能强大,而 且避免了容器强制业务对象采用特定的接口,最低程度的降低了侵入性,实现了效果极佳的架构重用。
轻量级容器中所有的Java类都运行在同一个虚拟机中。
WEB层是由MVC框架提供的(Struts或WebWork,或Spring架构的MVC结构)
业务对象是POJO,运行在轻量级容器里。AOP的拦截机制能够增强业务对象,从而实现企业级服务。与EJB容器不同,业务对象不依赖于容器的API, 所以这些对象在容器外也可以使用,更利于单元测试。业务对象仅仅通过接口来访问,当更改具体业务对象的实现类后,业务对象无需修改。实现了面向接口编程。
数据访问机制可以通过轻量级的O/R Mapping,该层能提供透明的持久化,该持久层实现了对数据访问方式JDBC的轻量级封装。

用J2EE架构企业级应用 (2)

◆ Web容器 服务器端容器,包括两种组件JSP和Servlet,JSP和Servlet都是Web服务器的功能扩展,接受Web请求,返回动态的Web页面。Web容器中的组件可使用EJB容器中的组件完成复杂的商务逻辑。
◆ EJB容器 服务器端容器,包含的组件为EJB(Enterprise
JavaBeans),它是J2EE的核心之一,主要用于服务器端的商业逻辑的实现。EJB规范定义了一个开发和部署分布式商业逻辑的框架,以简化企业级
应用的开发,使其较容易地具备可伸缩性、可移植性、分布式事务处理、多用户和安全性等。
◆ Applet容器
客户端容器,包含的组件为Applet。Applet是嵌在浏览器中的一种轻量级客户端,一般而言,仅当使用Web页面无法充分地表现数据或应用界面的时
候,才使用它。Applet是一种替代Web页面的手段,我们仅能够使用J2SE开发Applet,Applet无法使用J2EE的各种Service和
API,这是为了安全性的考虑。
◆ Application Client容器 客户端容器,包含的组件为Application Client。Application Client相对Applet而言是一种较重量级的客户端,它能够使用J2EE的大多数Service和API。
通过这四个容器,J2EE能够灵活地实现前面描述的企业级应用的架构。
在View部分,J2EE提供了三种手段:Web容器中的JSP(或
Servlet)、Applet和Application
Client,分别能够实现面向浏览器的数据表现和面向桌面应用的数据表现。Web容器中的Servlet是实现Controller部分业务流程控制的
主要手段;而EJB则主要针对Model部分的业务逻辑实现。至于与各种企业资源和企业级应用相连接,则是依靠J2EE的各种服务和API。
在J2EE的各种服务和API中,JDBC和JCA用于企业资源(各种企业信息系统和数据库等)的连接,JAX-RPC、JAXR和SAAJ则是实现Web Services和Web Services连接的基本支持。
J2EE的各种组件
我们就J2EE的各种组件、服务和API,进行更加详细的阐述,看看在开发不同类型的企业级应用时,根据各自需求和目标的不同,应当如何灵活使用并组合不同的组件和服务。
· Servlet
Servlet是Java平台上的CGI技术。Servlet在服务器端运行,动态
地生成Web页面。与传统的CGI和许多其它类似CGI的技术相比,Java
Servlet具有更高的效率并更容易使用。对于Servlet,重复的请求不会导致同一程序的多次转载,它是依靠线程的方式来支持并发访问的。
· JSP
JSP(Java Server
Page)是一种实现普通静态HTML和动态页面输出混合编码的技术。从这一点来看,非常类似Microsoft
ASP、PHP等技术。借助形式上的内容和外观表现的分离,Web页面制作的任务可以比较方便地划分给页面设计人员和程序员,并方便地通过JSP来合成。
在运行时态,JSP将会被首先转换成Servlet,并以Servlet的形态编译运行,因此它的效率和功能与Servlet相比没有差别,一样具有很高
的效率。
· EJB
EJB定义了一组可重用的组件:Enterprise
Beans。开发人员可以利用这些组件,像搭积木一样建立分布式应用。在装配组件时,所有的Enterprise
Beans都需要配置到EJB服务器(一般的Weblogic、WebSphere等J2EE应用服务器都是EJB服务器)中。EJB服务器作为容器和低
层平台的桥梁管理着EJB容器,并向该容器提供访问系统服务的能力。所有的EJB实例都运行在EJB容器中。EJB容器提供了系统级的服务,控制了EJB
的生命周期。EJB容器为它的开发人员代管了诸如安全性、远程连接、生命周期管理及事务管理等技术环节,简化了商业逻辑的开发。EJB中定义了三种
Enterprise Beans:
◆ Session Beans
◆ Entity Beans
◆ Message-driven Beans
· JDBC
JDBC(Java Database
Connectivity,Java数据库连接)API是一个标准SQL(Structured Query
Language,结构化查询语言)数据库访问接口,它使数据库开发人员能够用标准Java API编写数据库应用程序。JDBC
API主要用来连接数据库和直接调用SQL命令执行各种SQL语句。利用JDBC
API可以执行一般的SQL语句、动态SQL语句及带IN和OUT参数的存储过程。Java中的JDBC相当与Microsoft平台中的
ODBC(Open Database Connectivity)。
· JMS
JMS(Java Message
Service,Java消息服务)是一组Java应用接口,它提供创建、发送、接收、读取消息的服务。JMS
API定义了一组公共的应用程序接口和相应语法,使得Java应用能够和各种消息中间件进行通信,这些消息中间件包括IBM
MQ-Series、Microsoft MSMQ及纯Java的SonicMQ。通过使用JMS
API,开发人员无需掌握不同消息产品的使用方法,也可以使用统一的JMS
API来操纵各种消息中间件。通过使用JMS,能够最大限度地提升消息应用的可移植性。
JMS既支持点对点的消息通信,也支持发布/订阅式的消息通信。
· JNDI
由于J2EE应用程序组件一般分布在不同的机器上,所以需要一种机制以便于组件客户
使用者查找和引用组件及资源。在J2EE体系中,使用JNDI(Java Naming and Directory
Interface)定位各种对象,这些对象包括EJB、数据库驱动、JDBC数据源及消息连接等。JNDI
API为应用程序提供了一个统一的接口来完成标准的目录操作,如通过对象属性来查找和定位该对象。由于JNDI是独立于目录协议的,应用还可以使用
JNDI访问各种特定的目录服务,如LDAP、NDS和DNS等。
· JTA
JTA(Java Transaction
API)提供了J2EE中处理事务的标准接口,它支持事务的开始、回滚和提交。同时在一般的J2EE平台上,总提供一个JTS(Java
Transaction Service)作为标准的事务处理服务,开发人员可以使用JTA来使用JTS。
· JCA
JCA(J2EE Connector
Architecture)是J2EE体系架构的一部分,为开发人员提供了一套连接各种企业信息系统(EIS,包括ERP、SCM、CRM等)的体系架
构,对于EIS开发商而言,它们只需要开发一套基于JCA的EIS连接适配器,开发人员就能够在任何的J2EE应用服务器中连接并使用它。基于JCA的连
接适配器的实现,需要涉及J2EE中的事务管理、安全管理及连接管理等服务组件。
· JMX
JMX(Java Management
Extensions)的前身是JMAPI。JMX致力于解决分布式系统管理的问题。JMX是一种应用编程接口、可扩展对象和方法的集合体,可以跨越各种
异构操作系统平台、系统体系结构和网络传输协议,开发无缝集成的面向系统、网络和服务的管理应用。JMX是一个完整的网络管理应用程序开发环境,它同时提
供了厂商需要收集的完整的特性清单、可生成资源清单表格、图形化的用户接口;访问SNMP的网络API;主机间远程过程调用;数据库访问方法等。
· JAAS
JAAS(Java Authentication and
Authorization Service)实现了一个Java版本的标准Pluggable Authentication
Module(PAM)的框架。JAAS可用来进行用户身份的鉴定,从而能够可靠并安全地确定谁在执行Java代码。同时JAAS还能通过对用户进行授
权,实现基于用户的访问控制。
· JACC
JACC(Java Authorization Service Provider Contract for [...]

用J2EE架构企业级应用 (1)

企业级应用是指那些为商业组织、大型企业而创建并部署的解决方案及应用。这些大型企业级应用的结构复杂,涉及的外部资源众多、事务密集、数据量大、用户数多,有较强的安全性考虑。

当代的企业级应用决不可能是一个个的独立系统。在企业中,一般都会部署多个彼此连接
的、相互通过不同集成层次进行交互的企业级应用,同时这些应用又都有可能与其它企业的相关应用连接,从而构成一个结构复杂的、跨越Intranet和
Internet的分布式企业应用群集。其中,连接企业内部各种应用的技术称为EAI(Enterprise Application
Integration, 企业应用集成),而连接企业间各种应用的技术称为B2BI(Business-To-Business
Integration, 企业间集成),采用EAI、B2BI技术及早先的N层体系架构就是当今企业级应用的最大特征。

此外,作为企业级应用,其不但要有强大的功能,还要能够满足未来业务需求的变化,易于升级和维护。

企业级应用架构
下面我们使用一个图示来简单地解析一下企业级应用的架构,见图1。

图1 企业级应用的体系架构
这个体系架构的主体是MVC架构。MVC是Model/View/Control的缩写。
Model/View/Control是软件设计的典型结构。在这种设计结构下,一个应用被分为三个部分:Model、View和Controller,
每个部分负责不同的功能。Model是指对业务数据/信息的处理模块,包括对业务数据的存取、加工、综合等;View是指用户界面,也就是面向用户的数据
表示;Controller则负责View和Model之间的流程控制,也就是完成两个方向的动作:1.将用户界面(View)的操作映射到具体的
Model,以完成具体的业务逻辑;2. 将通过Model处理完的业务数据及时反应到用户界面(View)上。

MVC架构使得应用程序的结构更加清晰,通过将代码按照层次划分为业务逻辑/数
据、用户界面和应用流程控制这三个层次,增强代码稳定性。我们知道,对于Model、View、Controller这三部分功能来讲,View的实现一
般是由界面设计人员和界面程序员来完成,Model则是由业务逻辑程序员来完成,Controller则一般由负责整体控制的程序员来完成。
Controller部分的代码比较稳定,一般会实现一个通用的架构;而Model则跟随商务流程的变化而变化;View的更改则是随着用户需求的更改而
更改。这种模块功能的划分有利于在代码修改过程中进行模块的隔离,而不需要把具有不同功能的代码混杂在一起造成混乱。对于项目开发而言,有利于在项目小组
内按照小组成员各自的擅长进行分工,有利于三个部分并行开发、加快项目进度。

企业级资源连接
对于Model部分,也就是业务逻辑的处理部分,一般总是对商务数据进行处理、加工、综合等。对于企业级应用而言,商务数据有两种来源,一种是数据库,另一种则是其它的企业级应用系统。

对于数据库而言,这应当是大家熟悉的领域。我们通过使用数据库驱动程序,利用SQL来查询、操纵数据库。而对于其它的企业级应用而言,一般这些应用都会提供API,通过这些API,其它的应用就能够存取访问其中的数据,甚至是触发这些企业级应用中的一些业余流程。

企业级平台的特征
企业级应用需要使用优秀的企业级应用体系结构,而优秀的企业级应用体系结构通常来自于优秀的
解决方案。应用程序设计开始就要考虑其体系结构的合理性、灵活性、健壮性,从而既可满足企业级应用的复杂需求,也能为今后系统的调整和升级留有余地。体系
结构影响了整个应用的生命周期,实际上能够延长整个应用的生命周期,同时增强了用户在多变的商业社会中的适应性,减少了系统维护的开销和难度,从而给用户
带来最大的利益。

一个理想的企业级应用系统平台应该具有如下特征:

◆ 部署、开发和维护的有效性;

◆ 系统运行的健壮性和可靠性;

◆ 具备失败恢复的能力;

◆ 能够处理海量的数据;

◆ 能够同时支持数百个用户;

◆ 具备很高的安全性;

◆ 数据的高可用性;

◆ 可以迅速地开发和部署新的应用程序;

◆ 简化组件重用;

◆ 直观的编程模型;

◆ 支持行业标准和通用编程接口;

◆ 适用与小、中、大各种规模的应用系统;

◆ 系统费用随系统规模的增长而线性增长;

◆ 不断进行技术升级,以满足不断涌现的需求。

使用J2EE架构企业级应用
为了满足架构企业级应用的需求,Java的创始人Sun公司在早期的J2SE(Java
2 Platform Standard Edition)基础上,针对企业级应用的各种需求,主导并创造了J2EE(Java 2 Platform
Enterprise Edition)。

那么到底什么是J2EE呢?从整体上讲,J2EE是使用Java技术开发企业级应
用的一种事实上的工业标准(Sun公司出于其自身利益的考虑,至今没有将Java及其相关技术纳入标准化组织的体系),它是Java技术不断适应和促进企
业级应用过程中的产物。目前,Java平台有三个版本:适用于小型设备和智能卡的J2ME(Java 2 Platform Micro
Edition)、适用于桌面系统的J2SE和适用于企业级应用的J2EE。Sun推出J2EE的目的是为了克服传统Client/Server模式的弊
病,迎合Browser/Server架构的潮流,为应用Java技术开发服务器端应用提供一个平台独立的、可移植的、多用户的、安全的和基于标准的企业
级平台,从而简化企业应用的开发、管理和部署。J2EE是一个标准,而不是一个现成的产品。各个平台开发商按照J2EE规范分别开发了不同的J2EE应用
服务器,J2EE应用服务器是J2EE企业级应用的部署平台。由于它们都遵循了J2EE规范,因此,使用J2EE技术开发的企业级应用可以部署在各种
J2EE应用服务器上。

为了推广并规范化使用J2EE架构企业级应用的体系架构,Sun同时给出了一个建
议性的J2EE应用设计模型:J2EE Blueprints。J2EE
Blueprints提供了实施J2EE企业级应用的体系架构、设计模式和相关的代码,通过应用J2EE
Blueprints所描述的体系模型,能够部分简化架构企业级应用这项复杂的工作。J2EE
Blueprints是开发人员设计和优化J2EE组件的基本原则,同时为围绕开发工作进行职能分工给出了指导性策略,以帮助应用开发设计人员合理地分配
技术资源。

下面我们参照J2EE Blueprints,结合最新版的J2EE规范(J2EE 1.4),从整体上阐述如何使用J2EE架构企业级应用。

图2 使用J2EE架构企业级应用的体系架构
图2给出了使用J2EE架构企业级应用的体系架构。J2EE将组成一个完整企业级应用的不同
部分纳入不同的容器(Container),每个容器中都包含若干组件(这些组件是需要部署在相应容器中的),同时各种组件都能使用各种J2EE
Service/API。J2EE容器包括:

SwingUtilities中invokeLater和invokeAndWait介绍
在Java中Swing是线程不安全的,是单线程的设计,这样的造成结果就是:只能从事件派发线程访问将要在屏幕上绘制的Swing组件。事件派发线程
是调用paint和update等回调方法的线程,它还是事件监听器接口中定义的事件处理方法,例如,ActionListener中的
actionPerformed方法在事件派发线程中调用。
Swing是事件驱动的,所以在回调函数中更新可见的GUI是很自然的事情,比如,有一个按钮被按下,项目列表需要更新时,则通常在与该按钮相关联的事
件监听器的actionPerformed方法中来实现该列表的更新,从事件派发线程以外的线程中更新Swing组件是不正常的。
有时需要从事件派发线程以外的线程中更新Swing组件,例如,在actionPerformed中有很费时的操作,需要很长时间才能返回,按钮激活后
需要很长时间才能看到更新的列表,按钮会长时间保持按下的状态只到actionPerformed返回,一般说来耗时的操作不应该在事件处理方法中执行,
因为事件处理返回之前,其他事件是不能触发的,界面类似于卡住的状况,所以在独立的线程上执行比较耗时的操作可能更好,这会立即更新用户界面和释放事件派
发线程去派发其他的事件。
SwingUtilities类提供了两个方法:invokeLate和invoteAndWait,它们都使事件派发线程上的可运行对象排队。当可运
行对象排在事件派发队列的队首时,就调用其run方法。其效果是允许事件派发线程调用另一个线程中的任意一个代码块。
只有从事件派发线程才能更新组件。
程序示例:更新组件的错误方法
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
GetInfoThread t = new GetInfoThread(Test.this);
t.start();
startButton.setEnabled(false);
}
});
class GetInfoThread extends Thread {
Test applet;
public GetInfoThread(Test applet) {
this.applet = applet;
}
public void run() {
while (true) {
try {
Thread.sleep(500);
applet.getProgressBar().setValue(Math.random() * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

误分析:在actionPerformed中,监听器把按钮的允许状态设置为false,由于是在事件派发线程上调用actionPerformed,所
以setEnabled是一个有效的操作,但是在GetInfoThread中设置进度条是一个危险的做法,因为事件派发线程以外的线程更新了进度条,所
以运行是不正常的。
1、invokeLater使用
class GetInfoThread extends Thread {
Test applet;
Runnable runx;
int value;
public GetInfoThread(final Test applet) {
this.applet = applet;
runx = new Runnable() {
public void [...]

分类

 

3月 2010
« 7    
1234567
891011121314
15161718192021
22232425262728
293031  

Blogroll