Atomic Consistent? Isolated? Durable
An atomic
database transaction is one which is guaranteed to complete successfully or not at all. If an error prevents a partially-performed transaction from proceeding to completion, it must be "backed out" to prevent the database being left in an inconsistent state.
ACID?is?an?acronym?used?to?describe?the?properties?that?a?transaction?should?have?in?an?enterprise?environment.?A?transaction?should?be?Atomic,?and?its?results?should?be?Consistent,?Isolated,?and?Durable.?A?transaction?is?Atomic?if?it?either?completes?itself?or?is?completely?undone.?The?results?of?a?transaction?should?consistently?change?the?system?from?one?state?to?another,?be?isolated?or?independent?of?one?another,?and,?once?completed,?be?durable?or?permanent. 什么是事務(wù)
???事務(wù)是應(yīng)用程序中一系列嚴(yán)密的操作,所有操作必須成功完成,否則在每個(gè)操作中所作的所有更改都會(huì)被撤消。也就是事務(wù)具有原子性,一個(gè)事務(wù)中的一系列的操作要么全部成功,要么一個(gè)都不做。???
???事務(wù)的結(jié)束有兩種,當(dāng)事務(wù)中的所以步驟全部成功執(zhí)行時(shí),事務(wù)提交。如果其中一個(gè)步驟失敗,將發(fā)生回滾操作,撤消撤消之前到事務(wù)開(kāi)始時(shí)的所以操作。
事務(wù)的ACID
事務(wù)具有四個(gè)特征:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持續(xù)性(Durability)。這四個(gè)特性簡(jiǎn)稱(chēng)為ACID特性。
????
1、原子性
??? 事務(wù)是數(shù)據(jù)庫(kù)的邏輯工作單位,事務(wù)中包含的各操作要么都做,要么都不做
2、一致性
?????事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)。因此當(dāng)數(shù)據(jù)庫(kù)只包含成功事務(wù)提交的結(jié)果時(shí),就說(shuō)數(shù)據(jù)庫(kù)處于一致性狀態(tài)。如果數(shù)據(jù)庫(kù)系統(tǒng)運(yùn)行中發(fā)生故障,有些事務(wù)尚未完成就被迫中斷,這些未完成事務(wù)對(duì)數(shù)據(jù)庫(kù)所做的修改有一部分已寫(xiě)入物理數(shù)據(jù)庫(kù),這時(shí)數(shù)據(jù)庫(kù)就處于一種不正確的狀態(tài),或者說(shuō)是不一致的狀態(tài)。?
3、隔離性
??? 一個(gè)事務(wù)的執(zhí)行不能其它事務(wù)干擾。即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)其它并發(fā)事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。
4、持續(xù)性
?? 也稱(chēng)永久性,指一個(gè)事務(wù)一旦提交,它對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)的改變就應(yīng)該是永久性的。接下來(lái)的其它操作或故障不應(yīng)該對(duì)其執(zhí)行結(jié)果有任何影響。
事務(wù)的屬性
???
一個(gè)事務(wù)的屬性控制了事務(wù)的使用范圍。EJB、Spring以及.net下的事務(wù)屬性都很類(lèi)似的,事務(wù)屬性有如下幾種:
???Required:
??????如果在一個(gè)事務(wù)中調(diào)用,就把該方法加到此事務(wù)中來(lái),如果還沒(méi)有啟動(dòng)事務(wù),就啟動(dòng)一個(gè)新事務(wù)。
?? RequiredNew:
不管當(dāng)前有沒(méi)有事務(wù),都會(huì)啟動(dòng)一個(gè)新事務(wù),如果當(dāng)前有事務(wù),會(huì)被掛起直到方法結(jié)束。
NotSupported:
不能在事務(wù)中執(zhí)行此方法。如果有事務(wù),將會(huì)被掛起直到方法結(jié)束。
Supports:
如果當(dāng)前有事務(wù),此方法會(huì)加到當(dāng)前事務(wù),如果沒(méi)有,容器也不會(huì)啟動(dòng)新事務(wù)。
Mandatory:
必須在事務(wù)中調(diào)用此方法,否則拋出異常。
Never:
必須不在事務(wù)中調(diào)用此方法,否則拋出異常。
三.事務(wù)的回滾
CMT在以下兩中情況下,事務(wù)將回滾。第一,如果產(chǎn)生一個(gè)系統(tǒng)異常,容器將自動(dòng)回滾該事務(wù)。第二,通過(guò)調(diào)用EJBContext接口SetRollbackOnly方法,Bean方法通知容器回滾該事務(wù)。如果Bean拋出一個(gè)應(yīng)用異常,事務(wù)將不會(huì)自動(dòng)回滾,但可以調(diào)用SetRollbackOnly回滾。
五.隔離級(jí)別
事務(wù)不僅保證事務(wù)界限內(nèi)的數(shù)據(jù)庫(kù)操作全部完成(或回滾)同時(shí)還隔離數(shù)據(jù)庫(kù)更新語(yǔ)句。隔離級(jí)別描述被修改的數(shù)據(jù)對(duì)其他事物的可見(jiàn)度。隔離級(jí)別的控制會(huì)跟具體的DBMS廠商不同而不同。
??? ?隔離級(jí)別與并發(fā)性是互為矛盾的:隔離程度越高,數(shù)據(jù)庫(kù)的并發(fā)性越差;隔離程度越低,數(shù)據(jù)庫(kù)的并發(fā)性越好。
通過(guò)一些現(xiàn)象,可以反映出隔離級(jí)別的效果。這些現(xiàn)象有:
l???????? 更新丟失(lost update):當(dāng)系統(tǒng)允許兩個(gè)事務(wù)同時(shí)更新同一數(shù)據(jù)是,發(fā)生更新丟失。
l???????? 臟讀(dirty read):當(dāng)一個(gè)事務(wù)讀取另一個(gè)事務(wù)尚未提交的修改時(shí),產(chǎn)生臟讀。
l???????? 非重復(fù)讀(nonrepeatable read):同一查詢(xún)?cè)谕皇聞?wù)中多次進(jìn)行,由于其他提交事務(wù)所做的修改或刪除,每次返回不同的結(jié)果集,此時(shí)發(fā)生非重復(fù)讀。
l???????? 幻像讀(phantom read):同一查詢(xún)?cè)谕皇聞?wù)中多次進(jìn)行,由于其他提交事務(wù)所做的插入操作,每次返回不同的結(jié)果集,此時(shí)發(fā)生幻像讀。
?
SQL-99 標(biāo)準(zhǔn)定義了下列隔離級(jí)別:
l???????? 未提交讀(read uncommitted)(隔離事務(wù)的最低級(jí)別,只能保證不讀取物理上損壞的數(shù)據(jù))
l???????? 已提交讀(read committed)(數(shù)據(jù)庫(kù)引擎?的默認(rèn)級(jí)別)當(dāng)一個(gè)事務(wù)運(yùn)行在這個(gè)隔離級(jí)別時(shí),一個(gè) SELECT 查詢(xún)只能看到查詢(xún)開(kāi)始之前提交的數(shù)據(jù),而永遠(yuǎn)無(wú)法看到未提交的數(shù)據(jù),或者是在查詢(xún)執(zhí)行時(shí)其他并行的事務(wù)提交做的改變。
l???????? 可重復(fù)讀(repeatable read),不會(huì)臟讀和非重復(fù)讀,可能發(fā)生幻像讀
l???????? 可序列化(serializable)(隔離事務(wù)的最高級(jí)別,事務(wù)之間完全隔離)
posted @
2006-03-28 23:30 北國(guó)狼人的BloG 閱讀(333) |
評(píng)論 (0) |
編輯 收藏
啟動(dòng)Weblogic服務(wù)器,由于JMS,需要一個(gè)消息中間件,Tuxedo。本文使用的是WebLogic 9.1,與8.1的有所不同。
登錄

創(chuàng)建JMS servers

設(shè)置完JMS服務(wù)器以后,要設(shè)置JMS的Modules,以便JMS客戶(hù)端和接受端能查找相應(yīng)的JMSFactory和JMSdestination。

C:\bea\user_projects\domains\base_domain\config\
jms會(huì)出現(xiàn)配置相關(guān)的配置文件
建立兩個(gè)資源
一個(gè)是ConnectionFactory,配置一個(gè)JNDI。
另外一個(gè)是Queue-0,配置一個(gè)JNDI。

import?javax.jms.*;
import?java.util.Hashtable;
import?javax.naming.*;
import?java.io.*;

public?class?QueueSend


{
????
????public?static?void?main(String[]?args)?throws?Exception

????
{
????????Hashtable?hash?=?new?Hashtable();
????????hash.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
????????hash.put(Context.PROVIDER_URL,"t3://localhost:7001");
????????
????????InitialContext?ic?=?new?InitialContext(hash);
????????
????????//找工廠
????????QueueConnectionFactory?factory?=?(QueueConnectionFactory)ic.lookup("jms/factory");
????????
????????System.out.println(factory.getClass());
????????
????????
????????//找文件夾,也就是目的地
????????Queue?queue?=?(Queue)ic.lookup("queue");
????????
????????System.out.println(queue.getClass());
????????
????????
????????//查API,接口有什么方法阿????????
????????QueueConnection?conn?=?(QueueConnection)factory.createQueueConnection();
????????
????????
????????//消息的接受者,是否給消息中間件回復(fù),否則重復(fù)發(fā)送。第二參數(shù)使用自動(dòng)確認(rèn)
????????QueueSession?session?=?conn.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
????????
????????//根據(jù)目的地,確定發(fā)送者
????????QueueSender?sender?=?session.createSender(queue);
????????
????????
????????//Message的創(chuàng)建要使用Session
????????
????????BufferedReader?buffer?=?new?BufferedReader(new?InputStreamReader(System.in));
????????
????????while(true)

????????
{
????????????String?line?=?buffer.readLine();
????????????if(line.equals("quit"))

????????????
{
????????????????TextMessage?message?=?session.createTextMessage("over");
????????????????sender.send(message);?????????
????????????????break;????????????????
????????????}
????????????TextMessage?message?=?session.createTextMessage(line);
????????????sender.send(message);?????????
????????}
????????
??????????????
????????
????}


}察看一下Queue資源,就能看到自己發(fā)送的TextMessage。
下回分解MDB。
posted @
2006-03-25 21:34 北國(guó)狼人的BloG 閱讀(425) |
評(píng)論 (0) |
編輯 收藏
為了解決RMI無(wú)法解決的分布式事務(wù)控制,安全,并發(fā)等問(wèn)題。
EJB解決訪問(wèn)就是一種可以高校的開(kāi)發(fā)分布式應(yīng)用的解決方案。
編寫(xiě)EJB,其實(shí)只需要編寫(xiě)2個(gè)接口和一個(gè)Bean類(lèi),和一個(gè)部屬描述就可以了。
服務(wù)接口:
import?javax.ejb.*;
import?java.rmi.*;
//business???remote

public?interface?Compute?extends?EJBObject
{
????public?double?add(double?a,double?b)?throws?RemoteException;
}

Home接口:
import?javax.ejb.*;
import?java.rmi.*;


public?interface?ComputeHome?extends?EJBHome
{
????public?Compute?create()?throws?RemoteException,CreateException;
}Bean,業(yè)務(wù)邏輯實(shí)現(xiàn)的地方
import?javax.ejb.*;

public?class?ComputeBean?implements?SessionBean


{
????public?void?setSessionContext(SessionContext?ctx)
???????????????????????throws?EJBException,

??????????????????????????????java.rmi.RemoteException
{
????}
????public?void?ejbRemove()
???????????????throws?EJBException,

??????????????????????java.rmi.RemoteException
{
????}
????public?void?ejbActivate()
?????????????????throws?EJBException,

????????????????????????java.rmi.RemoteException
{
????}
????public?void?ejbPassivate()
??????????????????throws?EJBException,

?????????????????????????java.rmi.RemoteException
{
????}

????public?void?ejbCreate()?throws?CreateException
{
????}

????public?double?add(double?a,double?b)
{
????????return?a*b;
????}
}

<?xml?version="1.0"?encoding="UTF-8"?>
<!DOCTYPE?ejb-jar?PUBLIC?"-//Sun?Microsystems,?Inc.//DTD?Enterprise?JavaBeans?2.0//EN"?"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
????<enterprise-beans>
????????<session>
????????????<display-name>Compute</display-name>
????????????<ejb-name>abc</ejb-name>

????????????<home>ComputeHome</home>
????????????<remote>Compute</remote>
????????????<ejb-class>ComputeBean</ejb-class>

????????????<session-type>Stateless</session-type>
????????????<transaction-type>Container</transaction-type>?????
????????</session>
????</enterprise-beans>
????<assembly-descriptor>
????????<container-transaction>
????????????<method>
????????????????<ejb-name>abc</ejb-name>
????????????????<method-name>*</method-name>
????????????</method>
????????????<trans-attribute>Required</trans-attribute>
????????</container-transaction>
????????
????</assembly-descriptor>
</ejb-jar>JNDI的實(shí)現(xiàn)各個(gè)服務(wù)器的實(shí)現(xiàn)不同,所以需要依賴(lài)于服務(wù)器的一個(gè)xml。
JNDI也是一種面向接口編程,工廠模式的典范。
<?xml?version="1.0"?encoding="UTF-8"?>
<!DOCTYPE?weblogic-ejb-jar?PUBLIC?'-//BEA?Systems,?Inc.//DTD?WebLogic?8.1.0?EJB//EN'?'http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
????<weblogic-enterprise-bean>
????????<ejb-name>abc</ejb-name>????????
????????<jndi-name>efg</jndi-name>
????</weblogic-enterprise-bean>
</weblogic-ejb-jar>
想編譯EJB,需要j2ee jar,那就用\bea\weblogic81\server\lib\weblogic.jar
做一個(gè)META-INF放置兩個(gè)xml文件
jar -cvf Compute.jar *.class META-INF/*.xml
c創(chuàng)建,v看到它創(chuàng)建的過(guò)程,f文件名
部屬EJB,看看Weblogic幫助吧。
=============================
那么會(huì)發(fā)現(xiàn)jar文件中并沒(méi)有出現(xiàn)_stub或者_(dá)skeleton文件阿,那是因?yàn)橛扇萜髟谶\(yùn)行EJB時(shí)動(dòng)態(tài)創(chuàng)建在容器內(nèi)部了。
那么怎么才能看到呢?我們要分析阿。
java weblogic.appc ejb.jar
如果抱錯(cuò),在classpath中添加\jdk142_04\lib\tools.jar
如果想看原文件的話,就是-keepgenerated

===============================
開(kāi)始分析EJB工作原理
看下面一張圖,就清楚了,實(shí)際就是兩次RMI 調(diào)用。

要細(xì)致來(lái)說(shuō)。
基本是這樣的。
定義Home接口,主要是為讓客戶(hù)端有可能在創(chuàng)建EJB Bean對(duì)象時(shí),給予初始化。
import?javax.ejb.*;
import?java.rmi.*;


public?interface?ComputeHome?extends?EJBHome
{
????public?Compute?create()?throws?RemoteException,CreateException;
}
這只是一個(gè)接口,weblogic.appc會(huì)生成一個(gè)HomeImpl,并生成Stub和Skeleton對(duì)象。在客戶(hù)端JNDI查找時(shí),返回就是這個(gè)HomeImpl的Stub對(duì)象,注意類(lèi)文件也會(huì)動(dòng)態(tài)下載的。
create()與ejbcreate()方法是對(duì)應(yīng)的。
可有參數(shù)。
//Bean


???public?void?ejbCreate(String?param)?throws?CreateException?
{
????????//?TODO?Auto-generated?method?stub
????????this.userName?=?param;
????}


//Home

public?com.infogo.interfaces.Shopping?create(java.lang.String?param)
??????throws?javax.ejb.CreateException,java.rmi.RemoteException;===========
那么客戶(hù)端實(shí)際調(diào)用的是HomeImpl的Stub對(duì)象的方法,通過(guò)網(wǎng)絡(luò)傳送到服務(wù)器上的Skeleton,Skeleton再調(diào)用真正的HomeImpl對(duì)象的方法,創(chuàng)建一個(gè)創(chuàng)建Bean對(duì)象放入實(shí)例池,Impl調(diào)用Bean的ejbcreate方法,初始化參數(shù)。
并且HomeImpl,還要?jiǎng)?chuàng)建一個(gè)業(yè)務(wù)業(yè)務(wù)接口的實(shí)現(xiàn)類(lèi),并把業(yè)務(wù)接口實(shí)現(xiàn)類(lèi)(EOImpl)對(duì)象的Stub返回給客戶(hù)端。
客戶(hù)端拿到Stub,調(diào)用響應(yīng)服務(wù)方法(別忘了,真正的服務(wù)方法實(shí)現(xiàn)可是在Bean類(lèi)里),所以調(diào)用Stub方法,通過(guò)網(wǎng)絡(luò)傳遞EOImpl的Skeleton對(duì)象,然后調(diào)用EOImpl的響應(yīng)方法。
這是注意,EOImpl被稱(chēng)為請(qǐng)求攔截器,因?yàn)樗鼤?huì)在這時(shí)察看ejb-jar.xml,看一看方法聲明的事務(wù)類(lèi)型,并調(diào)用容器提供的API(安全、事務(wù)等)。所以這種服務(wù)器或者容器叫做隱式容器,它有工具生成的類(lèi)來(lái)調(diào)用容器相關(guān)API。而不是用戶(hù)直接調(diào)用。
在EOImpl調(diào)用完容器API之后,就會(huì)調(diào)用Bean的業(yè)務(wù)方法。
最后將接口-Skeleton-Stub-客戶(hù)端。
所以是兩次RMI調(diào)用。
這就是EJB工作原理。
import?javax.naming.*;
import?java.util.*;
import?javax.rmi.*;


public?class?Client


{
????public?static?void?main(String[]?args)?throws?Exception

????
{
????????Hashtable?hash?=?new?Hashtable();
????????hash.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
????????hash.put(Context.PROVIDER_URL,"t3://localhost:7001");
????????InitialContext?ic?=?new?InitialContext(hash);
????????
????????ComputeHome?home?=?(ComputeHome)ic.lookup("efg");
????????
????????//(ComputeHome)ProtableRemoteObject.narrow(ic.lookup("efg"),ComputeHome.class);

???????/**//*
????????*?客戶(hù)端從服務(wù)器獲得HomeImpl_stub?.class文件,并獲得HomeImpl_stub的對(duì)象
????????*?
????????*?home.create()-->HomeImpl_stub.create()-->網(wǎng)絡(luò)發(fā)送-->HomeImpl_skel.create()-->HomeImpl創(chuàng)建ComputeBean對(duì)象-->ComputeBean.ejbcreate()&&HomeImpl還要?jiǎng)?chuàng)建EOImpl_stub對(duì)象,返回HomeImpl_skel--->[網(wǎng)絡(luò)往回傳輸]--->HomeImpl_stub--->客戶(hù)端拿到EOImpl_stub對(duì)象。
????????*
????????*?這時(shí)完成了第一次rmi
????????*
????????*?c獲得了EOImpl_Stub對(duì)象,
????????*?
????????*?c.add(32,32)---->?EOImpl_Stub.add()--->網(wǎng)絡(luò)發(fā)送--->EOImpl_Skel.add()--->EOImpl--->[根據(jù)xml描述的事務(wù),進(jìn)行事務(wù)描述]--->判斷add方法是否開(kāi)始事務(wù)--->調(diào)用創(chuàng)建好Bean對(duì)象的add方法---->方法結(jié)果給EOImpl_Skel---->網(wǎng)絡(luò)往回傳輸---->EOImpl_Stub----客戶(hù)端拿到結(jié)果。
????????*
????????*?第二次rmi完成。
????????*/
????????
????????
????????
????????Compute?c?=?home.create();
????????System.out.println(c.add(32,32));
????????
????}???
}
posted @
2006-03-19 23:45 北國(guó)狼人的BloG 閱讀(977) |
評(píng)論 (0) |
編輯 收藏
簡(jiǎn)單來(lái)說(shuō),要實(shí)現(xiàn)A機(jī)器上JVM上運(yùn)行的Java程序,遠(yuǎn)程調(diào)用B機(jī)器上JVM上的Java程序,計(jì)算完畢,返回給A機(jī)器。
在沒(méi)有RMI的情況下,我們使用普通的網(wǎng)絡(luò)傳輸技術(shù)能完成么?當(dāng)然,兩種選擇,Socket直接通訊,將參數(shù)傳給B,B在通過(guò)Socket返還給調(diào)用者。或者通過(guò)Servlet也可以遠(yuǎn)程調(diào)用阿。
那么這樣解決問(wèn)題時(shí)沒(méi)有問(wèn)題,但對(duì)于A和B來(lái)說(shuō),代碼量、程序復(fù)用程序、維護(hù)性都不會(huì)太理想。
如果能讓調(diào)用者不知道網(wǎng)絡(luò)操作,實(shí)現(xiàn)對(duì)于用戶(hù)透明,也就是像調(diào)用本地一樣,對(duì)象名.方法名。
那么就是RMI規(guī)范涉及到一些接口。
面向接口的編程方式,就可以達(dá)到代碼的實(shí)現(xiàn)與聲明分離。
這樣用戶(hù)就只關(guān)心接口了。很多細(xì)節(jié)讓遵守規(guī)范(也就是一些編寫(xiě)好的工具)的實(shí)現(xiàn)類(lèi)去完成吧。[就是Stub和Skeleton]
那么就先定一個(gè)用戶(hù)A要知道怎么用,B要知道方法簽名完成實(shí)現(xiàn),的同一接口吧。
import?java.rmi.*;


public?interface?Compute?extends?Remote
{
????
????public?double?add(double?a,double?b)?throws?RemoteException;
????
}兩點(diǎn)要求
1,繼承標(biāo)記接口Remote。
identify interfaces whose methods may be invoked from a non-local virtual machine.
標(biāo)識(shí)該接口可以被非本地VM調(diào)用唄。
2,里面每個(gè)方法都要拋出RemoteException
業(yè)務(wù)接口的實(shí)現(xiàn)類(lèi),也就是做實(shí)事的類(lèi)
import?java.rmi.server.*;
import?java.rmi.*;

public?class?ComputeImpl?extends?UnicastRemoteObject?implements?Compute


{
????//要在構(gòu)造方法拋出異常

????public?ComputeImpl()?throws?RemoteException
{}
????

????public?double?add(double?a,double?b)
{
????????return?a+b;
????}
}=====================
javac *.class
rmic -keep ComputeImpl
帶參數(shù),可以保留Stub和Skeleton源碼。
通過(guò)ComputeImpl的實(shí)現(xiàn)類(lèi)來(lái)生成負(fù)責(zé)通訊的Stub(存根)和Skeleton(框架)
======================
那么就是要把這個(gè)對(duì)象綁定到一個(gè)端口上。
以便別人來(lái)使用
編寫(xiě)一個(gè)Server
import?java.rmi.*;

public?class?Server


{

????public?static?void?main(String[]?args)?throws?Exception

????
{
????????ComputeImpl?c?=?new?ComputeImpl();
????????Naming.bind("rmi://localhost:8888/compute",c);//compute別名
????}

}客戶(hù)端
import?java.rmi.*;

public?class?Client


{
????public?static?void?main(String[]?args)?throws?Exception

????
{
????????Compute?c?=?(Compute)Naming.lookup("rmi://localhost:8888/compute");//rmiregistry首先響應(yīng)
????????//實(shí)際c是Stub對(duì)象
????????System.out.println(c.getClass());
????????System.out.println(c.add(12.3,34));
????}???
}?看到?jīng)]有,客戶(hù)端通過(guò)rmi協(xié)議到服務(wù)器上尋找/compute資源對(duì)象。那個(gè)Naming是RMI專(zhuān)用,不是JNDI。
那么Server類(lèi)并沒(méi)有負(fù)責(zé)監(jiān)聽(tīng)阿。
哦,最后有一個(gè)強(qiáng)大的工具在JAVA_HOME/bin/下,叫做rmiregistry,專(zhuān)門(mén)負(fù)責(zé)監(jiān)聽(tīng)固定端口上,rmi協(xié)議的請(qǐng)求。
=================
rmiregistry 8888
=================
啟動(dòng)Server,綁定遠(yuǎn)程對(duì)象阿
java Server
=================
啟動(dòng)一個(gè)Client,調(diào)用一下
java Client
=================

===============
另外一些小問(wèn)題
由于rmiregistry 工具的不斷強(qiáng)大,jdk1.4已經(jīng)可以不再使用skeleton,到1.5,根本就不生成skeleton了。
rmiregistry可以充當(dāng)skeleton角色完成功能。
記住EJB中,還不行,因?yàn)闆](méi)有rmiregistry工具了。呵呵,明白了?
=========================
所以什么呢,RMI就是一種代理模式的應(yīng)用Stub,就是實(shí)際實(shí)現(xiàn)類(lèi)的客戶(hù)代理。
但需要統(tǒng)一的接口,才能對(duì)于用戶(hù)、調(diào)用者透明啊!
------------------------
我說(shuō)的比較通俗。還有很多深刻的東西。
posted @
2006-03-19 22:42 北國(guó)狼人的BloG 閱讀(1343) |
評(píng)論 (0) |
編輯 收藏
摘要: public
?
class
?ValidatorPlugIn????
implements
?PlugIn
{.????
public
?String?getPathnames()????
...
閱讀全文
posted @
2006-03-12 18:14 北國(guó)狼人的BloG 閱讀(1543) |
評(píng)論 (1) |
編輯 收藏
^ |
輸入或行的起始部分。 |
^T 匹配"This good earth"中的"T",但與"Uncle Tom's Cabin"中的"T"不匹配
|
$ |
輸入或行的結(jié)尾部分。 |
h$ 匹配"teach"中的"h",但與"teacher"中的"h"不匹配
|
* |
0 個(gè)或多個(gè)前置字符。 |
um* 匹配"rum"中的"um"、"yummy"中的"umm"和"huge"中的"u"
|
+ |
1 個(gè)或多個(gè)前置字符。 |
um+ 匹配"rum"中的"um"和"yummy"中的"umm",但在"huge"中沒(méi)有任何匹配項(xiàng)
|
? |
前置字符最多出現(xiàn)一次(即,指示前置字符是可選的)。 |
st?on 匹配"Johnson"中的"son"和"Johnston"中的"ston",但在"Appleton"或"tension"中沒(méi)有任何匹配項(xiàng)
|
. |
除換行符外的任何單字符。 |
.an 匹配短語(yǔ)"bran muffins can be tasty"中的"ran"和"can"
|
x|y |
x 或 y。 |
FF0000|0000FF 匹配 bgcolor="#FF0000" 中的"FF0000"和 font color="#0000FF" 中的"0000FF"
|
{n} |
恰好 n 個(gè)前置字符。 |
o{2} 匹配"loom"中的"oo"和"mooooo"中前兩個(gè)"o",但在"money"中沒(méi)有任何匹配項(xiàng)
|
{n,m} |
至少 n 個(gè)、至多 m 個(gè)前置字符。 |
F{2,4} 匹配"#FF0000"中的"FF"和"#FFFFFF"中的前四個(gè)"F"
|
[abc] |
用括號(hào)括起來(lái)的字符中的任何一個(gè)字符。用連字符指定某一范圍的字符(例如,[a-f] 等效于 [abcdef])。 |
[e-g] 匹配"bed"中的"e"、"folly"中的"f"和"guard"中的"g"
|
[^abc] |
未在括號(hào)中括起來(lái)的任何字符。用連字符指定某一范圍的字符(例如,[^a-f] 等效于[^abcdef])。 |
[^aeiou] 最初匹配"orange"中的"r"、"book"中的"b"和"eek!"中的"k"
|
\b |
詞邊界(例如空格或回車(chē)符)。 |
\bb 匹配"book"中的"b",但在"goober"或"snob"中沒(méi)有任何匹配項(xiàng)
|
\B |
詞邊界之外的任何內(nèi)容。 |
\Bb 匹配"goober"中的"b",但在"book"中沒(méi)有任何匹配項(xiàng)
|
\d |
任何數(shù)字字符。等效于 [0-9]。 |
\d 匹配"C3PO"中的"3"和"apartment 2G"中的"2"
|
\D |
任何非數(shù)字字符。等效于 [^0-9]。 |
\D 匹配"900S"中的"S"和"Q45"中的"Q"
|
\f |
換頁(yè)符。 |
|
\n |
換行符。 |
|
\r |
回車(chē)符。 |
|
\s |
任何單個(gè)空白字符,包括空格、制表符、換頁(yè)符或換行符。 |
\sbook 匹配"blue book"中的"book",但在"notebook"中沒(méi)有任何匹配項(xiàng)
|
\S |
任何單個(gè)非空白字符。 |
\Sbook 匹配"notebook"中的"book",但在"blue book"中沒(méi)有任何匹配項(xiàng)
|
\t |
制表符。 |
|
\w |
任何字母數(shù)字字符,包括下劃線。等效于 [A-Za-z0-9_]。 |
b\w* 匹配"the barking dog"中的"barking"和"the big black dog"中的"big"和"black" |
\W |
任何非字母數(shù)字字符。等效于 [^A-Za-z0-9_]。 |
\W 匹配"Jake&Mattie"中的"&"和"100%"中的"%" |
<script>
function testfn(str)

{
var ex = "^\\w+$";
var re = new RegExp(ex,"i");
alert(re.test(str));
}
</script>

<script>
testfn("dfda");
testfn("123");
testfn(",");
testfn(".");
testfn("123.3");
</script>自己試驗(yàn)一下
實(shí)際應(yīng)用,Email驗(yàn)證
<script>
function testmail(str)

{
var ex = "^\\w+@[\\w]+\\.+[a-z]{2,3}$";
var re = new RegExp(ex,"i");
alert(re.test(str));
}
</script>

<script>
testmail("aacom@fda.com");
</script>
注意.的轉(zhuǎn)義處理,因?yàn)?本身在正則表達(dá)式中有含義,代表非換行的單個(gè)字符
而我們想要的是.的實(shí)際標(biāo)點(diǎn)
<script>
function spliturl(str)

{
var ex = "\\w{3}\.\\w+\.\\w{2,3}\\.\\w{2,3}";
var re = new RegExp(ex);
var arr = re.exec(str);
alert(arr[0]);
}
</script>

<script>
spliturl("www.itnow.com.cn");
</script>
<script>
function spliturl(str)

{
var ex = "(\\w{3})\.(\\w+)\.(\\w{2,3})\\.(\\w{2,3})";
var re = new RegExp(ex);
var arr = re.exec(str);
alert(arr);
alert(RegExp.$1);
alert(RegExp.$2);
}
</script>

<script>
spliturl("www.itnow.com.cn");
</script>加了小括號(hào)就是定義了一個(gè)變量,可以使用,js中保存在RegExg.$1 ---- RegExg.$9中
posted @
2006-03-11 13:23 北國(guó)狼人的BloG 閱讀(293) |
評(píng)論 (0) |
編輯 收藏
準(zhǔn)備使用IBM收購(gòu)Rational以后的最新產(chǎn)品RSA 6.0,作為開(kāi)發(fā)建模工具。
人寫(xiě)程序與類(lèi)在打交道,而在程序運(yùn)行時(shí),是對(duì)象在運(yùn)行。
人寫(xiě)的是類(lèi)型,而動(dòng)態(tài)的是對(duì)象,使機(jī)器在運(yùn)行代碼。
OO是一種系統(tǒng)建模的技術(shù),是一個(gè)過(guò)程!
對(duì)對(duì)象進(jìn)行描述。
在這個(gè)過(guò)程中,要使用UML語(yǔ)言進(jìn)行類(lèi)型的描述。
========================================
比如模擬達(dá)內(nèi),可以說(shuō)有很多老師對(duì)象和學(xué)生對(duì)象,但在達(dá)內(nèi),關(guān)注學(xué)生這個(gè)個(gè)體什么呢?只關(guān)心姓名,性別,背景,而絕對(duì)不關(guān)心它的婚姻情況。
可以對(duì)這些對(duì)象進(jìn)行共性的提取,變?yōu)槔蠋燁?lèi)型和學(xué)生類(lèi)型。而運(yùn)行時(shí)就是一個(gè)個(gè)有特性的實(shí)例。
========================================
什么是對(duì)象,就是一個(gè)屬性確定的實(shí)體。比如找對(duì)象,這個(gè)對(duì)象在你心中早就有特定的要求,那么這樣的一個(gè)對(duì)象肯定是有確定屬性的對(duì)象。是單個(gè)的,唯一的,識(shí)別的實(shí)體。
那么由于成員變量的值不同,方法調(diào)用的結(jié)果不同。
所以對(duì)象是構(gòu)建系統(tǒng)的基石。
它包括:<1>標(biāo)識(shí)也就是引用名
<2>數(shù)據(jù)
<3>方法
什么是Class,它是對(duì)對(duì)象的定義。對(duì)于在某一個(gè)環(huán)境下的對(duì)于對(duì)象關(guān)心屬性的提取和抽象。
====================================
面向?qū)ο缶幊痰奶攸c(diǎn)
1抽象,就是一個(gè)提煉過(guò)程
2封裝,隱藏細(xì)節(jié)(屬性和私有方法)
3繼承,上下層次
4多態(tài)
--------------------------------------------
5,關(guān)聯(lián),對(duì)象的依賴(lài)程度
6,聚合
7,組合
8,內(nèi)聚&耦合
1,抽象的目的,主要是隱藏細(xì)節(jié),可以簡(jiǎn)化信息,看到顯著特征。
2,封裝的目的,隱藏?cái)?shù)據(jù)和行為,
注意,類(lèi)有兩個(gè)視圖,對(duì)外視圖(別人使用此類(lèi),不關(guān)心實(shí)現(xiàn))
內(nèi)視圖(自己拿著代碼,要知道實(shí)現(xiàn))
3,關(guān)聯(lián)
一個(gè)類(lèi)型使用其他類(lèi)型對(duì)象的服務(wù)。
4,聚合
一種強(qiáng)關(guān)聯(lián),一個(gè)是另外一個(gè)的組成部分,而不是必要部分。
一個(gè)汽車(chē)和一個(gè)音響。
5,組合
一個(gè)對(duì)象包含另外一個(gè)對(duì)象
一個(gè)是另外一個(gè)組成部分
大的東西決定著組成部分的生命周期
6,繼承,是一種實(shí)現(xiàn)代碼復(fù)用的手段,語(yǔ)言的特性。另外一種代碼復(fù)用的方式就是組合。
減少代碼量,維護(hù)方便。
組件的開(kāi)發(fā)
在開(kāi)發(fā)過(guò)程中,要遵循高內(nèi)聚,低耦合的規(guī)律。
組件內(nèi)部要相互的調(diào)用,來(lái)統(tǒng)一對(duì)外實(shí)現(xiàn)一個(gè)功能,而外界為實(shí)現(xiàn)這個(gè)功能,基本不需要再做什么,那么這個(gè)組件的重用性,就愈高。依賴(lài)于別人的越少,那么組件的復(fù)用價(jià)值也就愈高。
多態(tài)
有統(tǒng)一的接口,而行為有它的子類(lèi)型的行為確定。
運(yùn)行時(shí)多態(tài),就是子類(lèi)型重寫(xiě)了父類(lèi)型virtual方法。
能使用編譯時(shí)多態(tài)就是用編譯時(shí)多態(tài)。
================
所以可以將上面的幾個(gè)特點(diǎn)按類(lèi)別分類(lèi),比如,單個(gè)類(lèi)型、類(lèi)型之間、層次結(jié)構(gòu)、編程規(guī)則。
posted @
2006-02-28 23:57 北國(guó)狼人的BloG 閱讀(564) |
評(píng)論 (1) |
編輯 收藏
摘要: 在繼承于HttpServlet,進(jìn)行實(shí)際的HTTP開(kāi)發(fā)中,可以獲得很多來(lái)自父類(lèi)功能的封裝。來(lái)自于GenericServlet的部分函數(shù)getInitParameter(java.lang.String name)相當(dāng)于ServletConfig.getInitParameter(String name)。public ServletConfig getServletConfig()拿到S...
閱讀全文
posted @
2006-02-25 22:11 北國(guó)狼人的BloG 閱讀(253) |
評(píng)論 (0) |
編輯 收藏
摘要: 容器就是負(fù)責(zé)運(yùn)行和銷(xiāo)毀servlet的一組類(lèi)的程序,一組代碼的運(yùn)行環(huán)境。為了開(kāi)發(fā)方便,可以從javax.servlet.GenericServlet 繼承實(shí)現(xiàn)主要業(yè)務(wù)方法。注意幾點(diǎn),1.有一個(gè)無(wú)參數(shù)的init()方法,是GenericServlet實(shí)現(xiàn)的,它不是Servlet接口中的方法,所以不會(huì)由容器調(diào)用,而是因?yàn)镚enericServlet本身已經(jīng)覆蓋了帶參數(shù)的init方法,并且在方法的最后調(diào)...
閱讀全文
posted @
2006-02-11 12:10 北國(guó)狼人的BloG 閱讀(451) |
評(píng)論 (0) |
編輯 收藏
javax.servlet
Interface Servlet
是規(guī)范的接口,為了深入了解Servlet原理,要實(shí)際開(kāi)發(fā)一個(gè)實(shí)現(xiàn)該接口的類(lèi),來(lái)作為第一個(gè)Servlet。
public void init(ServletConfig config)
throws ServletException
這個(gè)方法,是由容器在實(shí)例化一個(gè)Servlet實(shí)例后,確切會(huì)調(diào)用該方法一次。通過(guò)判斷是否拋出異常來(lái)確認(rèn)Servlet是否被正確初始化。
public void service(ServletRequest req,
ServletResponse res)
throws ServletException,
java.io.IOException
這個(gè)方法,是我們實(shí)現(xiàn)業(yè)務(wù)邏輯的方法,req和res就是由Web服務(wù)器對(duì)于請(qǐng)求和相應(yīng)的有效封裝。
沒(méi)有什么神秘的,java網(wǎng)絡(luò)編程中,ServerSocket的accept方法返回之后,會(huì)獲得相應(yīng)的一個(gè)Socket對(duì)象,通過(guò)該對(duì)象可以進(jìn)而獲得對(duì)應(yīng)客戶(hù)端的輸入流和輸出流。在對(duì)其進(jìn)行封裝就進(jìn)而到Request和Response對(duì)象。
傳入service方法,req可以獲得請(qǐng)求的頭部信息,res.getWriter,獲得一個(gè)輸出,進(jìn)行輸出信息,作為真正響應(yīng)。
public void destroy()
This method is only called once all threads within the servlet's service
method have exited or after a timeout period has passed.
只有在service方法運(yùn)行完,或者一個(gè)timeout后,會(huì)被調(diào)用。
After the servlet container calls this method, it will not call the service
method again on this servlet.
一旦調(diào)用它,就不會(huì)再提供服務(wù)。
public ServletConfig getServletConfig()
返回傳入init方法的那個(gè)ServletConfig,也就是服務(wù)器的ServletConfig。這個(gè)方法主要為了其他實(shí)例來(lái)使用ServletConfig實(shí)例。
public java.lang.String getServletInfo()
好比普通的toString()方法,返回注冊(cè)信息。
編譯注意事項(xiàng):
要在環(huán)境變量的classpath中將servlet-api.jar的路徑加上,這樣編譯才能通過(guò)。
所以最好先準(zhǔn)備好tomcat服務(wù)器,以便利用它內(nèi)置的jar文件。
D:\jakarta-tomcat-5.0.19\common\lib\servlet-api.jar
======================================
編譯好后,是一個(gè)帶包結(jié)構(gòu)的.class文件目錄層次。
如何部署呢?
很簡(jiǎn)單,在D:\jakarta-tomcat-5.0.19\webapps中建立一個(gè)自己的應(yīng)用文件夾,例如:imshark
這時(shí)就可以將靜態(tài)網(wǎng)頁(yè)放入該文件夾了,然后要按照java web 應(yīng)用的規(guī)范,建立一個(gè)WEB-INF的文件夾,然后里面放置一個(gè)標(biāo)準(zhǔn)的web.xml文件,就可以訪問(wèn)了。
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">

</web-app>
然后部署servlet,在WEB-INF文件夾中,建立一個(gè)classes的目錄,然后,將帶目錄結(jié)構(gòu)的.class文件放入該文件夾,然后修改web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>TimeServlet</servlet-name>
<servlet-class>imshark.servlet.basic.TimeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TimeServlet</servlet-name>
<url-pattern>/getTime.jsp</url-pattern>
</servlet-mapping>

</web-app>

http://localhost:8080/imshark/getTime.jsp
所以可看出getTime.jsp是一個(gè)虛擬的路徑地址,并不實(shí)際存在,完全有web.xml構(gòu)造的。
以上就是最基本的Servlet的知識(shí)點(diǎn)。
posted @
2006-02-09 00:01 北國(guó)狼人的BloG 閱讀(1738) |
評(píng)論 (0) |
編輯 收藏