??xml version="1.0" encoding="utf-8" standalone="yes"?>久久亚洲国产成人影院网站,无码乱人伦一区二区亚洲,亚洲精品无码不卡在线播HE http://www.tkk7.com/coolfiry/category/14260.html认认真真做h,兢兢业业做事!zh-cnFri, 12 Oct 2007 12:32:43 GMTFri, 12 Oct 2007 12:32:43 GMT60垃圾攉机制(Garbage Collection)批判http://www.tkk7.com/coolfiry/archive/2007/10/12/152260.htmlCoolfiryCoolfiryFri, 12 Oct 2007 02:43:00 GMThttp://www.tkk7.com/coolfiry/archive/2007/10/12/152260.htmlhttp://www.tkk7.com/coolfiry/comments/152260.htmlhttp://www.tkk7.com/coolfiry/archive/2007/10/12/152260.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/152260.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/152260.html在Java版发表这文章,g有点把矛头指向Java了。其实不是,GC是所有新一代语a共有的特征,
Python, EiffelQC#QRoby{无一例外地都使用了GC机制。但既然Java中的GC最名,所以天?br /> 下来自然应该抗着?/span>

q篇短文源于comp.lang.java.programmer跟comp.lang.c++上发生的一场大辩论Q支持C++和Java
的两z不同势力展开了新世纪W一场冲H,跟脓(chung)发言过350Q两zN有名角压cC++阵营的擂L
Pete BeckerQACM会员QDinkumware Ltd. 的技术副ȝ。此君精通C++和JavaQ开发过两种语言?br /> 核心cdQ但是却对C++狂热之极Q而对于Java颇不以ؓ然。^时谈到Java的时候还好,一旦有
敢用Java来批判C++Q立d不住火爆脾气跛_出来Q以坚韧不拔的毅力和大无畏精与Ҏ(gu)周旋Q?br /> 舌战儒Q哪怕只剩下一个h也要血战到底。这{奇人当真少见!我真奇怪他整天泡在usenet上,
不用工作么?他的老板P.J. Plauger如此宽宏大量QJava阵营主角是一个网名Razzi的兄弟,另外?br /> Sun公司大名鼎鼎的Peter van der Linden助阵Q妙语连珠,寸土必争Q加上h多势众,一度占据优ѝ?br /> C++阵营里大拿虽然很多,但是大多数没有Pete那么多闲工夫Q例如Greg ComeauQComeau公司老板Q?br /> 每次来个只言片语Q实在帮不了Pete多大忙。但是自从C++阵营中冒Z个无名小子,|名Courage(勇气)Q?br /> 发动对Java GC机制的批判,形势Z一变。C++阵营g处于全攻之势QJava阵营疲于防守Q只?br /> 招架_“你们没有证据Q没有统计资?#8221;QŞ势很被动?/span>

垃圾攉(GC)不是一直被Java fans用来炫耀Q引以ؓ傲的优点么?怎么成了q了?我大惑不解,定睛
一看,才觉得此中颇有道理?/span>

首先QJava Swing库存在大量资源泄漏问题,q一点SUN非常清楚Q称之ؓbugsQ正在极力修正。但是看?br /> q里的问题恐怕不仅是库编写者的疏忽Q可能根源在于深层的机制Q未必能够轻易解冻I搞不好要伤筋动骨?br /> 不过q个问题不是那么Ҏ(gu)QC++阵营觉得如果抓住Ҏ(gu)的弱Ҏ(gu)击,q是占了上风也没什么说服力。谁
没有~点呢?于是反其道而行之,猛烈dJava阵营觉得最得意的东西,Java的GC机制本n?/span>

首先来想一惻Imemory leak到底意味着什么。在C++中,new出来的对象没有deleteQ这导致了memory
leak。但是C++早就有了克服q一问题的办法——smart pointer。通过使用标准库里设计_致的auto_ptr
以及各种STL容器Q还有例如boost?差不多是个准标准库了)中的四个smart pointersQC++
E序员只?br /> ׃一个星期的旉学习最新的资料Q就可以拍着胸脯_“我写?/span>E序没有memory leak!”?/span>

相比之下QJavag更优UQ因Z一开始你׃用考虑什么特D的机制Q大胆地往前newQ自有GC替你
收拾D局。Java的GC实际上是
JVM中的一个独立线E,采用不同的算?/span>{略来收集heap中那些不再有
reference指向的垃圑֯象所占用的内存。但是,通常情况下,GCU程的优先比较低,只有在当?/span>E序
I闲的时候才会被调度Q收集垃圾。当Ӟ如果JVM感到内存紧张了,JVM会主?/span>调用GC来收集垃圾,获取
更多的内存。请注意QJava的GC工作的时机是Q?. 当前
E序不忙Q有I闲旉?. I闲内存不?br /> 现在我们考虑一U常见的情况Q?/span>E序在紧张运行之中,没哟I闲旉lGC来运行,同时机器内存很大Q?br /> JVM也没有感到内存不Il果是什么?对了QGC形同虚设Q得不到调用。于是,内存被不断吞噬,而那?br /> 早已l用不着的垃圑֯象仍在在宝贵的内存里睡大觉。例如:

class BadGc {

    public void job1() {
        String garbage = "I am a garbage, and just sleeping in your precious memory, " +
                  "how do you think you can deal with me? Daydreaming! HAHA!!!";
        ....
    }

    public void job2() {...}

    ...
    ...

    public void job1000() {...}

    public static void main(String[] args) {
        bgc = new BadGc();
 bgc.job1();
 bgc.job2();
 ...
 bgc.job1000();
    }
}

q行中,虽然garbage对象在离开job1()之后Q就再也没有用了。但是因?/span>E序忙,内存q够用,所以GC?br /> 不到调度Qgarbage始终不会被回Ӟ直到E序q行到bgc.job1000()时还w在内存里嘲W你。没辙吧Q?/span>

好了Q我承认q段E序很傻。但是你不要以ؓq只是理Z的假设,恰恰相反Q大多数实用中的JavaE序都有
cM的效应。这是Z么Java
E序狂耗内存,而且好像l它多少内存吃都不够。你׃大笔的银子把内存
?28升到256Q再升到512Q结果是Q一旦执行复杂Q务,内存q是被轻易填满,而且多出来的q些内存只是
用来装垃圾,GCq是不给面子地千g唤不出来。等C的内存终于心力交瘁,GC才姗姗来q,收拾D局。?br /> 且GC工作的方式也很不好评P一U方法是一旦有Z回收内存Q就把所有的垃圾都回收。你可以惌Q这?br /> 花很长时?几百M的垃圑֕Q?Q如果你q时侯正在压下开炮的按钮QGC却叫了暂定,好了Q你{死吧!另一
U方法,得到Z之后Q回收一些内存,让JVM感到内存不那么紧张时收手。结果呢Q内存里始终有大批垃
圾,
E序始终在半Mzȝ荡着。最后,GC可以每隔一D|间就q行一ơ,每次只回收一部分垃圾Q这是现?br /> 大部分JVM的方式,l果是内存也费了,q动不动暂停几百毫秒。难啊!

反过来看看C++利用smart pointer达成的效果,一旦某对象不再被引用,M容缓Q立d收内存。这
通常发生在关键Q务完成后的清?cleanup)时期Q不会媄响关键Q务的实时性,同时Q内存里所有的对象
都是有用的,l对没有垃圾I占内存。怎么P传统、朴素的C++是不是更胜一{?

据统计,目前的JavaE序q行期间占用的内存通常为对应C++E序?-20倍。除了其它的原因Q上面所说的是一?br /> 非常主要的因素。我们对memory leak如此愤恨Q不是因ؓ它导致大量的内存垃圾得不到清除吗Q如果有?br /> GC之后Q垃圾比以前q来势v汹,那么GC又有什么好处呢Q?/span>

当然QC++的smart pointer现在会用的Z多,所以现在的C++E序普遍存在更严重的memory leak问题?br /> 但是Q如果我奶奶跟舒马赫比赛车输掉了Q你能够埋怨那辆R子么Q?br /> http://www.594k.com/java/html/y2007m1/12051/



Coolfiry 2007-10-12 10:43 发表评论
]]>
从LiveJournal后台发展看大规模|站性能优化Ҏ(gu)http://www.tkk7.com/coolfiry/archive/2007/09/29/149681.htmlCoolfiryCoolfirySat, 29 Sep 2007 13:26:00 GMThttp://www.tkk7.com/coolfiry/archive/2007/09/29/149681.htmlhttp://www.tkk7.com/coolfiry/comments/149681.htmlhttp://www.tkk7.com/coolfiry/archive/2007/09/29/149681.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/149681.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/149681.html从LiveJournal后台发展看大规模|站性能优化Ҏ(gu)

一、LiveJournal发展历程

LiveJournal?9q始于校园中的项目,几个人出于爱好做了这样一个应用,以实C下功能:

  • 博客Q论?
  • C会性网l,扑ֈ朋友
  • 聚合Q把朋友的文章聚合在一?

LiveJournal采用了大量的开源YӞ甚至它本w也是一个开源Y件?

在上U后QLiveJournal实现了非常快速的增长Q?/p>

  • 2004q?月䆾Q?80万注册用戗?
  • 2005q?月䆾Q?80万注册用戗?
  • 2005q?月䆾Q?90万注册用戗?
  • 辑ֈ了每U钟上千ơ的面h及处理?
  • 使用了大量MySQL服务器?
  • 使用了大量通用lg?

二、LiveJournal架构现状概况

livejournal_backend.png

三、从LiveJournal发展中学?/h2>

 

LiveJournal?台服务器发展?00台服务器Q这其中l历了无数的伤痛Q但同时也摸索出了解册些问题的Ҏ(gu)Q通过对LiveJournal的学习,可以让我们避免LJ曄犯过的错误,q且从一开始就对系l进行良好的设计Q以避免后期的痛苦?/p>

下面我们一步一步看LJ发展的脚步?/p>

1、一台服务器

一 台别人捐助的服务器,LJ最初就跑在上面Q就像Google开始时候用的破服务器一P值得我们敬。这个阶D,LJ的h以惊人的速度熟?zhn)的Unix的操 作管理,服务器性能出现q问题,不过q好Q可以通过一些小修小改应付过厅R在q个阶段里LJ把CGI升CFastCGI?/p>

最l问题出CQ网站越来越慢,已经无法通过优过化来解决的地步,需要更多的服务器,q时LJ开始提供付Ҏ(gu)务,可能是想通过q些钱来购买新的服务器,以解军_时的困境?br /> 毫无疑问Q当时LJ存在巨大的单炚w题,所有的东西都在那台服务器的铁皮盒子里装着?/p>

LJ-backend-7.png

2、两台服务器

用付Ҏ(gu)务赚来的钱LJC两台服务器:一台叫做Kenny的Dell 6U机器用于提供Web服务Q一台叫做Cartman的Dell 6U服务器用于提供数据库服务?/p>

LJ-backend-8.png

LJ有了更大的磁盘,更多的计资源。但同时|络l构q是非常单,每台机器两块|卡QCartman通过内网为Kenny提供MySQL数据库服务?br />
暂时解决了负载的问题Q新的问题又出现了:

  • 原来的一个单点变成了两个单点?
  • 没有冷备份或热备份?
  • |站速度慢的问题又开始出CQ没办法Q增长太快了?
  • Web服务器上CPU辑ֈ上限Q需要更多的Web服务器?

3、四台服务器

又买了两収ͼKyle和StanQ这ơ都?U的,都用于提供Web服务。目前LJ一共有3台Web服务器和一台数据库服务器。这旉要在3台Web服务器上q行负蝲均横?/p>

LJ-backend-9.png

LJ把Kenny用于外部的网养I使用mod_backhandq行负蝲均横?/p>

然后问题又出CQ?/p>

  • 单点故障。数据库和用于做|关的Web服务器都是单点,一旦Q何一台机器出现问题将D所有服务不可用。虽然用于做|关的Web服务器可以通过保持心蟩同步q速切换,但还是无法解x据库的单点,LJ当时也没做这个?
  • |站又变慢了Q这ơ是因ؓIO和数据库的问题,问题是怎么往应用里面d数据库呢Q?

4、五台服务器

又买了一台数据库服务器。在两台数据库服务器上用了数据库同?Mysql支持的Master-Slave模式)Q写操作全部针对L据库Q通过BinlogQ主服务器上的写操作可以q速同步到从服务器上)Q读操作在两个数据库上同时进?也算是负载均横的一U吧)?/p>

LJ-backend-10.png

实现同步时要注意几个事项Q?/p>

  • L作数据库选择法处理Q要选一个当前负载轻一点的数据库?
  • 在从数据库服务器上只能进行读操作
  • 准备好应对同步过E中的gq,处理不好可能会导致数据库同步的中断。只需要对写操作进行判断即可,L作不存在同步问题?

5、更多服务器

有钱了,当然要多C服务器。部|后快了没多久,又开始慢了。这ơ有更多的Web服务器,更多的数据库服务器,存在 IO与CPU争用。于是采用了BIG-IP作ؓ负蝲均衡解决Ҏ(gu)?/p>

LJ-backend-11.png

6、现在我们在哪里Q?/h2>

LJ-backend-1.png

现在服务器基本上够了Q但性能q是有问题,原因出在架构上?/p>

数据库的架构是最大的问题。由于增加的数据库都是以Slave模式d到应用内Q这样唯一的好处就是将L作分布到了多台机器,但这样带来的后果是写操作被大量分发Q每台机器都要执行,服务器越多,费p大,随着写操作的增加Q用于服务读操作的资源越来越?/p>

LJ-backend-2.png

׃台分布到两台

LJ-backend-3.png

最l效?/p>

现在我们发现Q我们ƈ不需要把q些数据在如此多的服务器上都保留一份。服务器上已l做了RAIDQ数据库也进行了备䆾Q这么多的备份完全是对资源的费Q属于冗余极端过度。那Z么不把数据分布存储呢Q?/p>

问题发现了,开始考虑如何解决。现在要做的是把不同用L数据分布C同的服务器上q行存储Q以实现数据的分布式存储Q让每台机器只ؓ相对固定的用h务,以实现^行的架构和良好的可扩展性?/p>

?了实现用户分l,我们需要ؓ每一个用户分配一个组标记Q用于标记此用户的数据存攑֜哪一l数据库服务器中。每l数据库׃个master及几个slave l成Qƈ且slave的数量在2-3収ͼ以实现系l资源的最合理分配Q既保证数据L作分布,又避免数据过度冗余以及同步操作对pȝ资源的过度消耗?/p>

LJ-backend-4.png

׃収ͼ一l)中心服务器提供用户分l控制。所有用L分组信息都存储在q台机器上,所有针对用L操作需要先查询q台机器得到用户的组P然后再到相应的数据库l中获取数据?/p>

q样的用h构与目前LJ的架构已l很相像了?/p>

在具体的实现旉要注意几个问题:

  • 在数据库l内不要使用自增IDQ以便于以后在数据库l之间迁UȝP以实现更合理的I/OQ磁盘空间及负蝲分布?
  • useridQpostid存储在全局服务器上Q可以用自增,数据库组中的相应值必M全局服务器上的gؓ准。全局服务器上使用事务型数据库InnoDB?
  • 在数据库l之间迁Uȝh要万分小心,当迁UL用户不能有写操作?

7、现在我们在哪里

LJ-backend-5.png

问题Q?/p>

  • 一个全局L务器Q挂掉的话所有用h册及写操作就挂掉?
  • 每个数据库组一个主服务器,挂掉的话q组用户的写操作挂掉?
  • 数据库组从服务器挂掉的话会导致其它服务器负蝲q大?

对于Master-Slave模式的单炚w题,LJ采取了Master-Master模式来解冟뀂所谓Master-Master实际上是人工实现的,q不是由MySQL直接提供的,实际上也是两台机器同时是MasterQ也同时是SlaveQ互相同步?/p>

Master-Master实现旉要注意:

  • 一个Master出错后恢复同步,最好由服务器自动完成?
  • 数字分配Q由于同时在两台机器上写Q有些ID可能会冲H?

解决Ҏ(gu)Q?br />

  • 奇偶数分配IDQ一台机器上写奇敎ͼ一台机器上写偶?
  • 通过全局服务器进行分?LJ采用的做??

 

Master-Master模式q有一U用法,q种Ҏ(gu)与前一U相比,仍然保持两台机器的同步,但只有一台机器提供服务(d写)Q在每天晚上的时候进行轮换,或者出现问题的时候进行切换?/p>

8、现在我们在哪里

LJ-backend-6.png

现在插播一条广告,MyISAM VS InnoDB?/p>

使用InnoDBQ?/p>

  • 支持事务
  • 需要做更多的配|,不过值得Q可以更安全的存储数据,以及得到更快的速度?

使用MyISAMQ?/p>

  • 记录日志QLJ用它来记|络讉K日志Q?
  • 存储只读静态数据,_快?
  • q发性很差,无法同时d数据Q添加数据可以)
  • MySQL非正常关闭或L时会D索引错误Q需要用myisamchk修复Q而且当访问量大时出现非常频繁?

9、缓?/h2>

d我写q?a >一文章介lmemcachedQ它?yu)是由LJ的团队开发的一Ƅ存工P以key-value的方式将数据存储到分布的内存中。LJ~存的数据:

  • 12台独立服务器Q不是捐赠的Q?
  • 28个实?
  • 30GBd?
  • 90-93%的命中率Q用qsquid的h可能知道Qsquid内存加磁盘的命中率大概在70-80%Q?

如何建立~存{略Q?/p>

想缓存所有的东西Q那是不可能的,我们只需要缓存已l或者可能导致系l瓶颈的地方Q最大程度的提交pȝq行效率。通过对MySQL的日志的分析我们可以扑ֈ~存的对象?/p>

~存的缺点?

  • 没有完美的事物,~存也有~点Q?
  • 增大开发量Q需要针对缓存处理编写特D的代码?
  • 理隑ֺ增加Q需要更多h参与pȝl护?
  • 当然大内存也需要钱?

10、Web讉K负蝲均衡

在数据包U别使用BIG-IPQ但BIG-IPq不知道我们内部的处理机Ӟ无法判断由哪台服务器对这些请求进行处理。反向代理ƈ不能很好的vC用,不是已经够快了,是达不到我们想要的效果?/p>

所以,LJ又开发了Perlbal。特点:

  • 快,,可管理的http web 服务?代理
  • 可以在内部进行{?
  • 使用Perl开?
  • 单线E,异步Q基于事Ӟ使用epoll , kqueue
  • 支持Console理与httpq程理Q支持动态配|加?
  • 多种模式Qweb服务器,反向代理Q插?
  • 支持插gQGIF/PNG互换Q?

11、MogileFS

LJ使用开源的MogileFS作ؓ分布式文件存储系l。MogileFS使用非常单,它的主要设计思想是:

  • 文g属于c(cL最的复制单位Q?
  • 跟踪文g存储位置
  • 在不同主Z存储
  • 使用MySQL集群l一存储分布信息
  • 大容易廉L?

到目前ؓ止就q么多了Q更多文可以在http://www.danga.com/words/扑ֈ?a >Danga.com?a >LiveJournal.com?同学们拿q个文参加了两ơMySQL ConQ两ơOS ConQ以及众多的其它会议Q无U的把他们的l验分n出来Q值得我们学习。在web2.0时代快速开发得到大家越来越多的重视Q但良好的设计仍是每一个应 用的基础Q希望web2.0们在成长为Top500|站的\上,不要因ؓ架构ȝ了网站的发展?/p>  http://blog.csdn.net/xmr_gxcfe/archive/2007/09/14/1785292.aspx

 



Coolfiry 2007-09-29 21:26 发表评论
]]>?PO BO VO DTO POJO DAO概念及其作用)http://www.tkk7.com/coolfiry/archive/2007/05/17/117981.htmlCoolfiryCoolfiryThu, 17 May 2007 01:44:00 GMThttp://www.tkk7.com/coolfiry/archive/2007/05/17/117981.htmlhttp://www.tkk7.com/coolfiry/comments/117981.htmlhttp://www.tkk7.com/coolfiry/archive/2007/05/17/117981.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/117981.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/117981.htmlPO BO VO DTO POJO DAO概念及其作用Q附转换图)

   J2EE开发中大量的专业羃略语很是让hqhQ尤其是跟一些高手讨论问题的时候,三分钟就被h家满口的专业术语h了,PO VO BO DTO POJO DAOQ一大堆的就来了Q听q老罗对这U现象的批判的朋友会会心一W)?/p>

    首先声明偶也不是什么高手,以下ȝ都是自己的体会。不对之处请(zhn)多指教?/p>

POQ?br>persistant object持久对象

最形象的理解就是一个PO是数据库中的一条记录?br>好处是可以把一条记录作Z个对象处理,可以方便的{为其它对象?br>

 



BOQ?br>business object业务对象

主要作用是把业务逻辑装Z个对象。这个对象可以包括一个或多个其它的对象?br>比如一个简历,有教育经历、工作经历、社会关pȝ{?br>我们可以把教育经历对应一个POQ工作经历对应一个POQ社会关pd应一个PO?br>建立一个对应简历的BO对象处理历,每个BO包含q些PO?br>q样处理业务逻辑Ӟ我们可以针对BOd理?br>

 



VO Q?br>value object值对?br>ViewObject表现层对?br>
主要对应界面昄的数据对象。对于一个WEB面Q或者SWT、SWING的一个界面,用一个VO对象对应整个界面的倹{?br>

 



DTO Q?br>Data Transfer Object数据传输对象
主要用于q程调用{需要大量传输对象的地方?br>比如我们一张表?00个字D,那么对应的PO有100个属性?br>但是我们界面上只要显C?0个字D,
客户端用WEB service来获取数据,没有必要把整个PO对象传递到客户端,
q时我们可以用只有q?0个属性的DTO来传递结果到客户端,q样也不会暴露服务端表结?到达客户端以后,如果用这个对象来对应界面昄Q那此时它的w䆾p{为VO

 



POJO Q?br>plain ordinary java object 单java对象
个h感觉POJO是最常见最多变的对象,是一个中间对象,也是我们最常打交道的对象?br>
一个POJO持久化以后就是PO
直接用它传递、传递过E中是DTO
直接用来对应表示层就是VO

 


DAOQ?br>data access object数据讉K对象
q个大家最熟?zhn)Q和上面几个O区别最大,基本没有互相转化的可能性和必要.
主要用来装Ҏ(gu)据库的访问。通过它可以把POJO持久化ؓPOQ用POl装出来VO、DTO


      ȝ下我认ؓ一个对象究竟是什么O要看具体环境Q在不同的层、不同的应用场合Q对象的w䆾也不一P而且对象w䆾的{化也是很自然的。就像你对老婆来说是老公Q对父母来说是子女。设计这些概늚初衷不是Z唬h而是Z更好的理解和处理各种逻辑Q让大家能更好的ȝ面向对象的方式处理问?

      大家千万不要陷入q度设计Q大可不必ؓ了设计而设计一定要在代码中区分各个对象。一句话技术是为应用服务的?br>
Ƣ迎指正?br>



M个图Q感觉没有完全表辑և自己的意思。。。。。谁帮忙完善下,最好能体现各个O在MVC中的位置
snap20070108.jpg 


转自Q?a href="http://www.tkk7.com/vip01/archive/2007/01/08/92430.html">http://www.tkk7.com/vip01/archive/2007/01/08/92430.html


Coolfiry 2007-05-17 09:44 发表评论
]]>
转蝲(【服务配|】apache+tomcat配置负蝲均衡的网?http://www.tkk7.com/coolfiry/archive/2006/11/06/79441.htmlCoolfiryCoolfiryMon, 06 Nov 2006 09:20:00 GMThttp://www.tkk7.com/coolfiry/archive/2006/11/06/79441.htmlhttp://www.tkk7.com/coolfiry/comments/79441.htmlhttp://www.tkk7.com/coolfiry/archive/2006/11/06/79441.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/79441.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/79441.html阅读全文

Coolfiry 2006-11-06 17:20 发表评论
]]>
WINIZX的JDBC学习W记http://www.tkk7.com/coolfiry/archive/2006/11/03/78860.htmlCoolfiryCoolfiryFri, 03 Nov 2006 02:14:00 GMThttp://www.tkk7.com/coolfiry/archive/2006/11/03/78860.htmlhttp://www.tkk7.com/coolfiry/comments/78860.htmlhttp://www.tkk7.com/coolfiry/archive/2006/11/03/78860.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/78860.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/78860.html2004-9-13     星期一     雨

l. q接到数据库的方?br />{:1) ODBC(Open Database Connectivity)
       一个以C语言为基讉KSQL为基数据库引擎的接口Q它提供了一致的接口用于和数据库沟通以及访问数据?br />    2) JDBC
       Java版本的ODBC

2. JDBC应用~程接口
{:JDBC应用~程接口是:
    1) 标准的数据访问接口,可以q到不同的数据库;
    2) JAVA~程语言的一l类和接口?br />    JDBC应用~程接口能够Q?br />    1) q接到数据库;
    2) 发SQL查询字符串到数据?
    3) 处理l果?br />    JDBC应用~程接口有二个主要的部分Q?br />    1) JAVA应用E序开发接口面向JAVA应用E序开发?
    2) JDBC驱动E序开发接?br />    
3. JDBC Driver
{:1) 一大堆实现了JDBCcd接口的类;
    2) 提供了一个实现java.sql.Driver接口的类?br />
4. JDBC Driver的四U类?br />{:1) JDBC-ODBC?br />    由O(jin)DBC驱动提供JDBC讉K
    2) 本地API
    部分Java driver把JDBC调用转化成本地的客户端API
    3) JDBC-net
    U的Java driverQ将JDBC调用转入DBMSQ与|络协议无关。然后通过服务器将调用转ؓDBMS协议?br />    4) 本地协议
    U的java driverQ将JDBC调用直接转ؓDBMS使用的网l协?br />
5. JDBC开发者接?br />{:1) java.sql--java 2q_下JDBC的主要功能,标准?J2SE)
    2) javax.sql--java 2q_下JDBC增强功能Q企业版(J2EE)

6. 使用URL认数据?br />{:我们使用URL来确定一个数据库(正确的Driver,正确的主?正确的协议,正确的协议,正确的用户名和密?;
    语法Qprotocol:subprotocol:subname
    范例Qjdbc:db2:MyTest
          jdbc:db2://localhost:6789/MyTest

7. javax.sql包JDBC2.0的增强功?br />{:1) 数据源接?
    2) q接?
    3) 分布式交?
    4) 行集;

8. 创徏一个基本的JDBC应用
{:1) 步骤一Q注册一个driver;
    2) 步骤二:建立一个到数据库的q接;
    3) 步骤三:创徏一个statement;
    4) 步骤四:执行SQL语句;
    5) 步骤五:处理l果;
    6) 步骤六:关闭JDBC对象

9. 注册一个Driver(步骤一)
{:1) driver被用于连接到数据?
    2) JDBC应用~程接口使用W一个能成功q接到给定URL的driver;
    3) 在同一旉可以装蝲多个driver

10.注册一个driver的方法:
{:1) 使用cloader(装蝲;实例?注册入DriverManager)
       a. Class.forName("Com.ibm.db2.jdbc.app.DB2Driver");
       b. Class.forName("Com.ibm.db2.jdbc.net.DB2Driver");
       c. Class.forName("Com.microsoft.jdbc.sqlServer.SQLServerDriver);
       d. Class.forName("oracl.jdbc.driver.OracleDriver");
       e. Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    2) 实例化一个Driver
       a. Driver drv = new COM.cloudscape.core.RmiJdbcDriver();

2004-9-14     星期二     阴

1. 建立一个到数据库的q接(步骤?
{:DriverManager调用getConnection(urlString)Ҏ(gu)Q实际上调用的是driver的connect(urlString)Ҏ(gu);
    1) 当一个driver肯定地对应到一个数据库URLQDriverManager建立一个连?
    2) 当没有driver匚wQ返回null然后下一个driver被检?
    3) 假如没有建立q接Q抛Z个SQLExcepiton异常

2. l常使用的一些JDBC URL
{:1) JDBC-ODBC: jdbc:odbc:<DB>
    2) Oracle: jdbc:oracle:oci:@<sid> or jdbc:oracle:thin:@<SID>
    3) Weblogic MS-SQL: jdbc:weblogic:mssqlserver4:<DB>@<HOST>:<PORT>
    4) DB2: jdbc:db2:MyTest or jdbc.db2://localhost:6789/MyTest(需要用户名和密?

3. Driverq接Ҏ(gu)
{:1) 创徏一个到指定Driver实例的直接调?
    2) 避免一般访问的问题
       Driver drv = new COM.ibm.db2.jdbc.app.DB2Driver();
       Connection con = null;
       try {con = drv.connect("jdbc:db2:MyTest",new Properties())}
       catch(SQLException e){}

4. 创徏一个Statement(步骤?
{:1) Statement的三个接?
       a. Statement;
       b. PreparedStatement(l承自Statement);
       c. CallableStatement(l承自PreparedStatement);
    2) 使用Ҏ(gu)Connection.createStatement()得到一个Statement对象

5. PreparedStatement对象
{:1) 调用ProparedStatement比statement更ؓ高效;
    2) l承自Statement;
    3) 语法QPreparedStatement pstm = connection.prepareStatement(sqlString);

6. CallableStatement对象
{:1) 通过CallableStatement调用数据库中的存储过E?
    2) l承自PreparedStatement;
    3) CallableStatement cstm = connection.prepareCall("{call return_student[?,?]}");
       cstm.setString(1,"8623034");
       cstm.registerOutparameter(2, Types.REAL);
       cstm.execute();
       float gpa = cstm.getFloat(2);

7. Statement接口的比?br />{:             | Statement           | PreparedStatement         |  CallableStatement
    ------------------------------------------------------------------------------
    写代码位|   |   客户端            | 客户端                    |  服务器端
    ------------------------------------------------------------------------------
    写代码位|   |   客户端            | 服务器端                  |  服务器端
    ------------------------------------------------------------------------------
    ~写代码技术 |JavaQSQL操作        |JavaQSQL操作              |  数据库的E序语言Q如PL/SQL
    ------------------------------------------------------------------------------
    可配|性     |   高                |W一ơ高Q以后低           |  ?br />    ------------------------------------------------------------------------------
    可移植性     |   高                |假设支持PreparedStatement的话高   ?br />    ------------------------------------------------------------------------------
    传输效率     |   低                |W一ơ低Q以后高           |  ?br />
8. 执行SQL Statement(步骤?
{:通过接口Ҏ(gu)SQL语句传输?认的数据库连接,q回l果可能是一个数据表Q可以通过java.sql.ResultSet讉K?br />    1) Statement的接口方法:
    a. executeQuery(sqlString): 执行l定的SQL声明Q返回一个结果集(ResultSet)对象;
    b. executeUpdate(sqlString): 执行l定的SQL声明Q可以是INSERT、UPDATE或DELETE声明Q也可以是SQL DDL声明;
    c. execute(sqlString): 执行l定的SQL声明?br />
9. 处理l果(步骤?
{:1) 使用l果?ResultSet)对象的访问方法获取数?
       a. next():下一个记?br />       b. first():W一个记?br />       c. last():最后一个记?br />       d. previous():上一个记?br />    2) 通过字段名或索引取得数据
    3) l果集保持了一个指向了当前行的指针Q初始化位置为第一个记录前?br />
10. 关闭JDBC对象(步骤?
{:1) 首先关闭记录?
    2) 其次关闭声明;
    3) 最后关闭连接对象?br />
11. 数据表和cd应的三种关系Q?br />{:1) 一个表对应一个类;
    2) 一个表对应相关c?
    3) 一个表对应整个cdpd

12. c间关系的几U表设计Q?br />{:1) 多对一Q?br />    2) 一对一: 
    3) 一对多Q?br />    4) 多对多:

13. SQL数据cd及其相应的Java数据cd
{:SQL数据cd                     Java数据cd              说明
    ------------------------------------------------------------------
    INTEGER或者INT                  int                     通常是个32位整?br />    SMALLINT                        short                   通常是个16位整?br />    NUMBER(m,n) DECIMAL(m,n)        Java.sql.Numeric        合计位数是m的定点十q制敎ͼ数后面有n位数
    DEC(m,n)                        Java.sql.Numeric        合计位数是m的定点十q制敎ͼ数后面有n位数
    FLOAT(n)                        double                  q算_ֺ为n位二q制数的点?br />    REAL                            float                   通常?2位QҎ(gu)
    DOUBLE                          double                  通常?4位QҎ(gu)
    CHARACTER(n)或CHAR(n)           String                  长度为n的固定长度字W串
    VARCHAR(n)                      String                  最大长度ؓn的可变长度字W串
    BOOLEAN                         boolean                 布尔?br />    DATE                            Java.sql.Date           Ҏ(gu)具体讑֤而实现的日历日期
    TIME                            Java.sql.Time           Ҏ(gu)具体讑֤而实现的时戳
    TIMESTAMP                       Java.sql.Timestamp      Ҏ(gu)具体讑֤而实现的当日日期和时?br />    BLOB                            Java.sql.Blob           二进制大型对?br />    CLOB                            Java.sql.Clob           字符大型对象
    ARRAY                           Java.sql.Array
    

2004-9-15     星期三      阴

1. 元数?br />{:关于数据的信息,例如cd或者容量。通过JDBC API可以讉KQ?br />    1) 数据库元数据;
       a. 使用connection.getMetadataҎ(gu)q回DataMetaData引用
       b. 能够使用isReadOnly此类Ҏ(gu)获取信息
    2) l果集元数据;
       a. 使用ResultSet.getMetadataҎ(gu)q回ResultSetMetaData引用
       b. 能够使用getColumnCount此类Ҏ(gu)获取信息

2. 事务处理
{:1) 一pd的动作作Z个不可分的操?
    2) JDBC API中用事务处理步骤:
       a. 用false作ؓ参数调用setAutoCommitҎ(gu);
       b. 执行一或多个关于数据库的操?
       c. 调用commitҎ(gu)完成改变;
       d. 恢复上次提交后的改变Q调用rollbackҎ(gu).

       try
       {
          con.setAutoCommit(false);
          Statement stm = con.createStatement();
          stm.executeUpdate("insert into student(name, age, gpa) values('gzhu', 30, 4.8)");
          stm.commit();
       }
       catch(SQLException e)
       {
          try
          {
             con.rollback();
          }
          catch(Exception e)
          {
          }
       }

3. q发控制
{:1) 讄隔离U别Ҏ(gu)QsetTransactionIsolation
    2) 隔离U别静态变?br />       a. TRANSACTION_NONEQ只ȝ数据字典;
       b. TRANSACTION_READ_UNCOMMITTEDQ只L提交数据;
       c. TRANSACTION_READ_COMMITTEDQ只L提交数据;
       d. TRANSACTION_REPEATABLE_READQ重复读取数?
       e. TRANSACTION_SERIALIZABLEQ无论做什么操作都不许别h动?br />    3) CZQcon.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

4. JDBC 2.0 应用E序~程接口增强功能
{:1) ResultSet增强Q?br />       a. 可以回卷;
       b. 可以修改;
       讄CZQStatement stm = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
    2) Statement增强了批量修改能?batch updates);
    3) 更高U的数据cd(例:Struct)?br />
5. JDBC 2.0标准扩展
{:1) JNDI(Java Naming and Directory Interface): 解决L状态下Object的查?
    2) q接池:在内存中保存了一个数据库q接Q不需要注册驱动器Q提高性能的重要方法?img src ="http://www.tkk7.com/coolfiry/aggbug/78860.html" width = "1" height = "1" />

Coolfiry 2006-11-03 10:14 发表评论
]]>
java打包详解http://www.tkk7.com/coolfiry/archive/2006/10/12/74844.htmlCoolfiryCoolfiryThu, 12 Oct 2006 10:40:00 GMThttp://www.tkk7.com/coolfiry/archive/2006/10/12/74844.htmlhttp://www.tkk7.com/coolfiry/comments/74844.htmlhttp://www.tkk7.com/coolfiry/archive/2006/10/12/74844.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/74844.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/74844.html
CZ1Q将两个class文g存档C个名为?classes.jar' 的存档文件中Q?br /> & nbsp;     jar cvf& nbsp;classes.jar Foo.class Bar.class
CZ2Q用一个存在的清单QmanifestQ文件?mymanifest'  foo/& nbsp;目录下的所?br />            文g存C个名? 'classes.jar' 的存文件中Q?br />        jar cvfm  classes.jar mymanifest -C foo/ .

来个例子试试看Q?br />我们只有一个HelloWorldQ如下:
public& nbsp; class  HelloWorld{
 public& nbsp;static void main(String[] args){
 System.out.println(“Hi, Hello World!?;
}
}
我将q个java文g存到C盘跟目录下,okQ接下来Q?br />在先前打开的命令提C符?跌{到C盘提C符?Q我们输入javac HelloWorld.javaQ然后l输入:jar & nbsp;cvf  hello.jar  HelloWorld.classQ回车后M的C盘看看,多了什么,没错 hello.jar ?br />基本的步骤我们现在都知道了,你可以自己去试一下随着jar后面的参数的不同Q结果有什么变化?br />紧接着我们看看如何q行我们的jar包?br />在进入正题之前,你要先打开我们刚刚做好的jar包看看,多了什么呢QMETA-INF目录Q再看看里面是什么,q有一个MANIFEST.MF文g是不是?用文本编辑器(我这里是UltraEdit)打开它看看:
Manifest-Version:  1.0
Created-By: 1.4.2 (Sun Microsystems& nbsp;Inc.)
是q样。这里我们对它进行修改,加一句:Main-Class:  HelloWorld (在第三行)。这个就是我们之前写的那个类Q也是我们的入口类。也卻I
Manifest -Version: 1.0
Created-By: 1.4.2 (Sun& nbsp;Microsystems Inc.)
Main-Class: HelloWorld< BR>接下来,我们在命令提C符里执行:
jar umf  MANIFEST.MF app.jar
q样我们使用了我们自qMANIFEST.MF文g对原来默认的q行了更新。你不妨可以再进ȝ看是不是M了Main-Class: HelloWorldq一句?br />OkQ这个最后的一步了Q来验证我们做的一切,在命令提C符中输入:
java -jar hello.jar (执行)
出现了什么,――Hi, Hello World!
我们再来看看 jar文g在tomcat中发布,注意Q在tomcat中我们就不能再用jarq种格式Q而改war格式Q它是专门用于web应用的,其实整个q程下来基本上和jar是类似的Q?br />先准备我们要打包的资源?br />扑ֈ存放tomcat的webapps目录Q进到其中,新徏一个文件夹Q这里命名ؓhelloQ再q去新徏WEB-INF文g夹,再进L建classes文g夹,此时我们也将我们唯一的servletQ?HelloWorld.java攑ֈq里Q在与classes目录同下徏立一文gweb.xml。OkQ目前我们初步徏立了一个简单的web应用?
q是HelloWorld.javaQ?br />import java.io.*;< BR>import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends& nbsp;HttpServlet {
 public void  doGet(HttpServletRequest req, HttpServletResponse  res)
              & nbsp;               & nbsp; throws ServletException, IOException& nbsp;{
  res.setContentType("text/html");
  PrintWriter out = res.getWriter ();
  out.println("<HTML>");< BR>  out.println("<HEAD><TITLE& gt;Hello, World!</TITLE></HEAD>");< BR>  out.println("<BODY>");
& nbsp; out.println("Hello, World!");
   out.println("</BODY></HTML>");
 }
}//end here!
对它~译。下面是web.xmlQ?lt; BR><?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC
  '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
  'http://java.sun.com/j2ee/dtds/web-app_2_3.dtd&< /FONT>#39;>
<web-app>
  <servlet>
     <servlet-name>hello</servlet-name& gt;
    <servlet-class& gt;HelloWorld</servlet-class>
   </servlet>
  <servlet-mapping& gt;
 <servlet-name>hello</servlet- name>
 <url-pattern>/HelloWorld& lt;/url-pattern>
  </servlet-mapping& gt;
</web-app>
开始压~,形成war档:
在命令提C符下进到先前创制的hello目录下,执行 jar  cvf   hello.war  * Q我们便得到hello.war。将它拷贝至 webapps目录下,okQ来看最后一步,打开tomcat的目录conf中的server.xmlQ加入:
   <Context path="/hello" docBase="hello.war"& nbsp;debug="0"
    reloadable ="true"/>
大功告成Q运行它Q启动tomcatQ后在浏览器中输?img src="http://www.matrix.org.cn/images/small/url.gif" align="absmiddle" />http://localhost:8080/hello/HelloWorldQ有了吗Q?br />最后,如果你想用ant来完成以上的打包zdQ下面就告诉你:
对于jar来说。在build.xml 中,
 <target name="jar">< BR>  <jar destfile="${app_home}/hello.jar"& gt;
   <fileset dir=" ${dest}" includes="**"/>
  & nbsp;   <!--fileset dir="${dest} " includes="**/action.properties"/-->
     </jar>
 & lt;/target>

对于warQ?br /><war& nbsp;warfile="hello.war" webxml="./WEB-INF/web.xml">
    <fileset dir="html"/& gt;
    <lib  dir="lib/">
    & nbsp;   <exclude name="oracle*.jar"/& gt;
    </lib>
    <classes  dir="build/servlets">
   & nbsp;     <include& nbsp;name="**/*.class"/>
  </classes& gt;
</war> 
好了Q就q么多,希望对你有点帮助。:Q?
我上传了上面打过的两个包Qhello.jar和hello.war?img src="http://www.matrix.org.cn/images/small/download.gif" align="absmiddle" border="0" height="16" width="16" />?点击下蝲?/font>
?点击下蝲?/font>
W一rar文g对应的是hello.jar,下蝲后将其名改ؓ hello.jar
W二rar文g对应hello.warQ下载后改ؓhello.war?br />q是׃上传不了 jar格式和war格式的文Ӟ你只好照我上面说的去做了 Q)

补充Q?br /> ############
jar基本操作Q?br />############
1.& nbsp;创徏jar文g
  jar cf jar- file input-file(s)
c---want to Create& nbsp;a JAR file.
f---want the  output to go to a file  rather than to stdout.
eg: 1) jar cf myjar.jar query_maintain_insert.htm< BR>    2)jar cvf  myjar.jar query_maintain_insert.htm
       v---Produces verbose(详细? output.
    3)jar& nbsp;cvf myjar.jar query_maintain_insert.htm mydirectory< BR>    4)jar cv0f  myjar.jar query_maintain_insert.htm mydirectory
      0---don't& nbsp;want the JAR file to be& nbsp;compressed.
    5)jar& nbsp;cmf MANIFEST.MF myjar.jar yahh.txt
      m---Used& nbsp;to include manifest information  from an existing manifest file.
    6)jar cMf MANIFEST.MF& nbsp;myjar.jar yahh.txt
   & nbsp;  M---the default manifest  file should not be produced.
    7)jar cvf myjar.jar& nbsp;*
       *---create all contents in current& nbsp;directory.
2. 察看jar文g
 & nbsp;jar tf jar-file
t---want to& nbsp;view the Table of contents  of the JAR file.
eg: 1)jar& nbsp;vft yahh.jar
       v---Produces verbose(详细?  output.
3. 提取jar文g
   jar xf jar-file [archived-file(s)]
x- --want to extract files from  the JAR archive.
eg: 1)jar xf& nbsp;yahh.jar yahh.txt(仅提取文件yahh.txt)
 & nbsp;  2)jar xf yahh.jar alex/yahhalex.txt (仅提取目录alex下的文gyahhalex.txt)
   & nbsp;3)jar xf yahh.jar(提取该jar包中的所有文件或目录)
4. 修改Manifest文g
  jar  cmf manifest-addition jar-file input-file(s)< BR>m---Used to include manifest information& nbsp;from an existing manifest file.< BR>5. 更新jar文g
  jar  uf jar-file input-file(s)
u---want to update a


Coolfiry 2006-10-12 18:40 发表评论
]]>
化Java应用E序的打包和发布http://www.tkk7.com/coolfiry/archive/2006/10/12/74843.htmlCoolfiryCoolfiryThu, 12 Oct 2006 10:38:00 GMThttp://www.tkk7.com/coolfiry/archive/2006/10/12/74843.htmlhttp://www.tkk7.com/coolfiry/comments/74843.htmlhttp://www.tkk7.com/coolfiry/archive/2006/10/12/74843.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/74843.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/74843.html  
  该文章提供了打包Java code的几U方法,我们会探讨Java manifest 文gQ给出用于管理JAR文g所依赖文g、估计跨q_发布所需的CLasspath的合适方?我也会解释如何用manifest包版本特性来认包的兼容?..
  
  什么是JAR文gQ?/b>
  
  在开发过E中Q我们可以直接用Java class文g来运行程序,但这q不是一个好方式Q好在Java 提供?JAR(Java Archive)文g来提供发布和q行?br />  
  jar 文g实际上是class 文g的ZIP压羃存Q这U格式被q泛使用Q因此易与用,有很多中工具可以操作q种格式的文件。也正是因ؓq个原因Qjar文g本nq不能表达所包含应用E序的标{信息?br />  
  Manifest 因此得以出现
  
   Z要提供存的标签信息Qjar 文g指定了一个特定目录来存放标签信息QMETA-INF 目录Q其中我们来x该目录中的MANIFEST.MF文gQ他是JAR的manifest文gQ他包含了JAR文g的内Ҏ(gu)qͼq在q行时向JVM? 供应用程序的信息Q大多数JAR文g含有一个默认生成的manifest 文g,执行JAR命o或用zip工具Q都可以产生?br />  
  如果是由jar命o产生?manifest 文gQŞ?
  Manifest-Version: 1.0
  Created-By:1.4.0-beta
  (Sun Microsystems Inc.)
  
   q些信息没甚么用,仅仅告诉我们使用的是1.0的manifest文g,W一行定义manifest的格式,W二行说明?SUN 的JDK1.4的jar工具生成该文Ӟ如果manifest文g是由其他 Q如antQ?创徏的,那将会出?“Created-By: Ant 1.2?之类的内容,如果你是自己创徏manifest文gQ你可以加入自己的一些相关信?
  
  基础格式
  
  manifest 文g的格?是很单的Q每一行都?名-?对应?属性名开_接着?":" Q然后是属性|每行最?2个字W,如果需要增加,你可以在下一行箋行,l行以空格开_以空格开头的行都会被视ؓ前一行的l行?br />  
  所有在开头的属性都是全局的,你也可以定义特定class 或package的属性,E后介l这U?br />  
  把manifest文g插入JAR文g
  
  使用 m 选项Q把指定文g名的manifest文g 传入Q例?br />  jar cvfm myapplication.jar myapplication.mf -C classdir
  
  如果你用ant来创建时Q在ant 的build.xml 加入如下条目
  <target name="jar">
  <jar jarfile ="myapplication.jar"
  manifest="myapplication.mf">
  <fileset dir="classdir"
  includes="**/*.class"/>
  </jar>
  </target>
  
  q行JavaE序
  
  现在我们来体验一下manifest文g的作用,如果现在我们有一个Java 应用E序打包在myapplication.jar中, main class?com.example.myapp.MyAppMain Q那么我们可以用以下的命令来q行
  java -classpath myapplication.jar com.example.myapp.MyAppMain
  
  q显然太ȝ了,现在我们来创qmanifest文gQ如下:
  Manifest-Version: 1.0
  Created-By: JDJ example
  Main-Class: com.example.myapp.MyAppMain
  
  q样我们可以用如下的命o来运行程序了Q(明显单多了,也不会造成无谓的拼写错误)
  java -jar myapplication.jar
  
  理JAR的依赖资?/b>
  
   很少Java应用会仅仅只有一个jar文gQ一般还需?其他cd。比如我的应用程序用CSun ?Javamail classes Q在classpath中我需要包含activation.jar ?mail.jar,q样在运行程序时,相比上面的例?我们要增加一?
  java -classpath mail.jar:activation.jar -jar myapplication.jar
  
  在不同的操作pȝ?jar包间的分隔符也不一P在UNIX用“:”,在window中?“;”,q样也不方便
  
  同样Q我们改写我们的manifest文gQ如?br />  Manifest-Version: 1.0
  Created-By: JDJ example
  Main-Class: com.example.myapp.MyAppMain
  Class-Path: mail.jar activation.jar
  
  Q加入了Class-Path: mail.jar activation.jarQ用I格分隔两个jar包)
  
  q样我们仍然可以使用和上例中相同的命令来执行该程序:
  java -jar myapplication.jar
  
   Class-Path属性中包含了用I格分隔的jar文gQ在q些jar文g名中要对特定的字W用逃逸符Q比如空|要表C成"%20"Q在路径的表 CZQ都采用?”来分隔目录Q无论是在什么操作系l中Q?即在window?Q而且q里用的是相对\径(相对于本w的JAR文gQ:
  Manifest-Version: 1.0
  Created-By: JDJ example
  Main-Class: com.example.myapp.MyAppMain
  Class-Path: ext/mail.jar ext/activation.jar
  Multiple Main ClassesQ多ȝQ?br />  
   q有一UMultiple Main Classes情况Q如果你的应用程序可能有命o行版? 和GUI版本Q或者一些不同的应用却共享很多相同的代码Q这时你可能有多个Main ClassQ我们徏议你采取q样的策略:把共享的cL成lib包,然后把不同的应用打成不同的包Q分别标志主c:如下
  Manifest for myapplicationlib.jar:
  Manifest-Version: 1.0
  Created-By: JDJ example
  Class-Path: mail.jar activation.jar
  Manifest for myappconsole.jar:
  Manifest-Version: 1.0
  Created-By: JDJ example
  Class-Path: myapplicationlib.jar
  Main-Class: com.example.myapp.MyAppMain
  Manifest for myappadmin.jar:
  Manifest-Version: 1.0
  Created-By: JDJ example
  Class-Path: myapplicationlib.jar
  Main-Class: com.example.myapp.MyAdminTool
  在myappconsole.jar ?myappadmin.jar的manifest文g中分别注明各自的 Main Class
  Package Versioning
  
  完成发布后,如果使用者想了解 Q哪些代码是谁的Q目前是什么版本?使用什么版本的cdQ解决的Ҏ(gu)很多 Qmanifest提供了一个较好的Ҏ(gu)Q你可以在manifest文g中描q每一个包的信息?br />  
   Java U承了实现说明与描述分离的原则,package 的描q?定义了package 是什么,实现说明 定义了谁提供了描q的实现Q描q和实现包含 名、版本号和提供者。要得到q些信息Q可以查看JVM的系l属性(使用 java.lang.System.getProperty() Q?br />  
  在manifest文g中,我可以ؓ每个package定义描述和实现版本,声明名字Qƈ加入描述属性和实现属性,q些属性是
  
  Specification-Title
  Specification-Version
  Specification-Vendor
  Implementation-Title
  Implementation-Version
  Implementation-Vendor
  
  当要提供一个类库或~程接口Ӟ描述信息昑־是很重要Q见以下范例Q?br />  
  Manifest-Version: 1.0
  Created-By: JDJ example
  Class-Path: mail.jar activation.jar
  Name: com/example/myapp/
  Specification-Title: MyApp
  Specification-Version: 2.4
  Specification-Vendor: example.com
  Implementation-Title: com.example.myapp
  Implementation-Version: 2002-03-05-A
  Implementation-Vendor: example.com
  
  Package Version 查询
  
  在manifest文g中加入package描述后,可以用Java提供的java.lang.Package classq行Package 的信息查询,q里列D3个最基本的获取package object的方?br />  
  1.Package.getPackages():q回pȝ中所有定义的package列表
  
  2.Package.getPackage(String packagename):按名q回package
  
  3.Class.getPackage():q回l定class所在的package
  
  使用者这Ҏ(gu)可以动态的获取package信息.
  
  需要注意的是如果给定的package中没有class被加?则也无法获得package 对象
  
  Manifest 技?/b>
  
  L以Manifest-Version属性开?br />  
  每行最?2个字W,如果过的化Q采用箋?br />  
  认每行都以回Rl束Q否则改行将会被忽略
  
  如果Class-Path 中的存在路径Q?/"分隔目录Q与q_无关
  
  使用I分隔d性和package属?br />  
  使用"/"而不?."来分隔package 和class ,比如 com/example/myapp/
  
  class 要以.classl尾Qpackage 要以 / l尾

Coolfiry 2006-10-12 18:38 发表评论
]]>
插g式设计的架构模型与实?/title><link>http://www.tkk7.com/coolfiry/archive/2006/09/30/73100.html</link><dc:creator>Coolfiry</dc:creator><author>Coolfiry</author><pubDate>Sat, 30 Sep 2006 14:57:00 GMT</pubDate><guid>http://www.tkk7.com/coolfiry/archive/2006/09/30/73100.html</guid><wfw:comment>http://www.tkk7.com/coolfiry/comments/73100.html</wfw:comment><comments>http://www.tkk7.com/coolfiry/archive/2006/09/30/73100.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/coolfiry/comments/commentRss/73100.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/coolfiry/services/trackbacks/73100.html</trackback:ping><description><![CDATA[ <div id="vbxjdbb" class="guanggao"> <span id="ad3"> </span> </div> <div id="fdptltz" class="guanggao"> <span id="contentAdv"> </span> </div>  插g式设计近q来非常行Q其?a target="_blank"><font color="#4822dd">eclipse</font></a>起了推L助澜的作用,提到插g式就会不pȝ惛_<a target="_blank"><font color="#4822dd">eclipse</font></a>。其实插件式设计q不是什么新事物Q早在几十年前就有了。像X Server是Z插g式设计的Q除了核心功能外Q它所有的扩展功能和设备驱动都是以插g方式加入q来的?<br /><br />  Z插g的设计好处很多:把扩展功能从框架中剥d来,降低了框架的复杂度,让框架更Ҏ(gu)实现。扩展功能与框架以一U很杄方式耦合Q两者在保持接口不变的情况下Q可以独立变化和发布。公开插g接口Q让W三Ҏ(gu)Z扩展应用E序的功能,有胦大家一起发。另外,q可以让开源与闭源共存于一套YӞ你的插g是开源还是闭源,完全׃自己军_?<br /><br />  Z插g设计q不秘Q相反它比v一团惔的设计更单,更容易理解。各U基于插件设计的架构都有自己的特Ԍ但从M架构上看Q其模型都大同小异。这里我们介l一个简单的模型Qƈl出几个实例Q希望对新手有所启发?br /><br />  1. 基本架构<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><img alt="plugin.jpg" src="http://dev.yesky.com/imagelist/06/28/z0qt19na01c1.jpg" /></span></div></td></tr></tbody></table><br />  插g式设计的应用E序Q基本上可以用上图来表示。当Ӟ此图是一U较高层ơ的表示Q实际的设计会更复杂一些。我们在q里Z阐述方便Q不用故意搞得那么复杂?br /><br />  应用E序由应用程序框架、插件接口、插件和公共函数库四部分l成?<br /><br />  应用E序框架负责应用E序的整体运作,它清楚程序整个流E,但ƈ不知道每个过E具体要做什么。它在适当的时候调用一些插Ӟ来完成真正的功能?br /><br />  插g接口是一个协议,可能用IDL描述Q可能是头文Ӟ也可能一D|字说明。插件按照这个协议实现出来,可以加入到应用E序中来。当Ӟ对于复杂的系l,插g接口可能有多个,各自h独立的功能?br /><br />  插g是完成实际功能的实体Q实C要求的插件接口。尽实C么以及怎么实现Q完全是插g自己的自由。在实际情况来,一般还是有些限Ӟ因ؓ插g接口本n可能是一个限制。如Q实现编译功能的插gQ自然不能实现成一个聊天功能的插g?<br /><br />  公共函数库是一l函数或者类Q应用程序框架和插g都可以调用。它通常是一个独立的动态库QDLLQ。应用程序框架本w是公用的,是代码复用的一U方式。但q不是所有可复用代码都可以放在框架中Q特别是插g会用到的公共代码Q那会造成插gҎ(gu)架的依赖。把q些公共代码提取C个独立的库中Q是一U好的方法?br /><br />  另外Q值得补充说明一下的是插件接口。插件接口通常有两U:<br /><br />  通用插g接口Q这一cL件接口是通用的,你无法从接口函数看出q个插g的功能。它的接口函数通常有这些函敎ͼ<br /><br />  init : 用于初始化插Ӟ通常在插件被加蝲时调用?br /><br />  deinitQ用于反初始化插Ӟ通常在插件被卸蝲时调用?br /><br />  runQ让插g起动?br /><br />  stopQ让插g停止?br /><br />  至于插g要完成什么功能,要插到哪里,在init函数里决定,它调用公共函数库里的函数把自己注册到框架中某个位|?br /><br />  专用插g接口Q这一cL件接口是专用的,看到它的接口函数说明Q你可以大致了解它的功能了?br /><br />  加入插g的方式通常采用配置信息来实玎ͼ配置信息可以是注册表Q也可以配置文g。也可以动态注册进来,或者把插g攑ֈ指定的位|?br /><br />  下面我们来看几个实例Q?br /><br />  2. 桌面设计<br /><br />  最q一D|间完成了桌面模块的设计和实现。按照以往的经验,桌面模块通常是变化最多的一个模块,SPECL在不断的调整的效果,不同客户要求实现h个性化的桌面,直到产品快发布了Q桌面的SPECq在不停的修攏V另外,在智能手ZQ桌面占有特D的CQ很多东襉K可能往桌面里塞Q桌面不但是各种功能的大杂烩Q还是一些系l消息的中{站?br /><br />  q个d比较手Q所以在设计时就分外心。首先想到的是采用插g式设计,把外围功能独立出来,量化框架的实现?br /><br />  插gQ每一个最功能单元都是一个插Ӟ它可以是可见的,也可以是不可的,也可以是动态变化的。比如时间、电(sh)池电(sh)量、网l连接、信号强弱、新事g(如SMS、MMS、EMAL、ALARM和未接电(sh)话等)、应用程序快h式、左x作按钮和其它处理pȝ事g的功能单元。每个插仉用一?desktop来描qͼq是遵@freedesktop.org的标准的?br /><br />  桌面框架包括Q状态栏、开始菜单、操作栏、桌面区、事件管理器和主题管理器。而状态栏、开始菜单、操作栏、桌面区和事件管理器都是容器Q容U_U插件。对于可见的插gQ可以有自己的表现方式,也可以采用通用的表现方式?br /><br />  公共函数库:一些抽象的cR实现插件的辅助cM及其它一些可能被公用的类?br /><br />  插g接口Q对于不可见的插件要求实C件处理功能,可见的插件还要求实现l制功能?br /><br />  3. 模拟器设?br /><br />  一个同事负责设计另外一个^台的PC模拟环境设计。在我的下,他对架构作了调整。调整后的架构非常简单,也可以认为是插g式的设计Q它׃面几部分l成Q?br /><br />  应用E序框架Q负责模拟器基本功能Q如模拟键盘和显C备、换肤功能等?br /><br />  插gQ就是被模拟的^収ͼ如microwindow及相应的手机应用E序。尽运行时通常只有一个插件运行,q样做仍然有意义Q如果要换成minigui或者其它^台时Q模拟器不需要作M修改?br /><br />  公共函数库:它由应用E序框架初始化一些信息和回调函数Q然后供插g(即microwindow)调用Q插件利用它来实现显C和输入{驱动程序?br /><br />  插g接口Q如起动和停止模拟^台等?br /><br />  4. GIMP<br /><br />  GIMP是一个功能强大的囑Ş囑փ~辑器,典型的基于插件式的设计,在《unix~程艺术》中Q作为插件式设计CZ介绍q?br /><br />  应用E序框架QGUI<br /><br />  插gQ完成图像的各种转换和处理功能,如模p、去斑和色彩调整{?br /><br />  公共函数库:攑֜libgimp.so里?br /><br />  插g接口Q对GIMP感兴的朋友Q可以到官方|站上去阅读更多的文?<img src ="http://www.tkk7.com/coolfiry/aggbug/73100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/coolfiry/" target="_blank">Coolfiry</a> 2006-09-30 22:57 <a href="http://www.tkk7.com/coolfiry/archive/2006/09/30/73100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>插g开发框?/title><link>http://www.tkk7.com/coolfiry/archive/2006/09/30/73097.html</link><dc:creator>Coolfiry</dc:creator><author>Coolfiry</author><pubDate>Sat, 30 Sep 2006 14:53:00 GMT</pubDate><guid>http://www.tkk7.com/coolfiry/archive/2006/09/30/73097.html</guid><wfw:comment>http://www.tkk7.com/coolfiry/comments/73097.html</wfw:comment><comments>http://www.tkk7.com/coolfiry/archive/2006/09/30/73097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/coolfiry/comments/commentRss/73097.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/coolfiry/services/trackbacks/73097.html</trackback:ping><description><![CDATA[ <!-- end good artical --> <!-- content --> <table class="table" cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td valign="top"> <div id="xxjtxvv" class="wrap_m_c_up" id="div_diggs0"> <h1> </h1> </div> </td> <td> <div id="ppjvrxz" class="wrap_m_c_a_c"> <h3>原文地址Q?a id="LinkUrl" href="/BlueDavy/archive/2006/05/28/48593.html" target="_blank">http://www.tkk7.com/BlueDavy/archive/2006/05/28/48593.html</a></h3> <p> <span id="lblsummary">摘要:插g开发框架其实和目前开源界行的MVC框架之类的相同,都决定了Zq个框架的开发方式,如基于MVC框架Q就会按照MVC思想来进行开发,而插件开发框架呢Q也是同样如此,p求基于插件的方式来进行开发,不过插g开发框架和MVC框架又有不同Q插件开发框架是一个可以成为系l基架构的框Ӟ而MVC框架通常来讲不以成为,如在目前的MVC框架Webwork、Struts上我们通常都需要加上Spring、Hibernate来构成系l完整的基础架构Q这个时候由于MVC框架的实现是没有标准可参照的Q就造成了在各种pȝ中Ş成了不同的但很类似的基础架构Q但却造成了无法复用的现象Q插件开发框架则是作为统一pȝ基础架构的一U开发方式,它得系l的复用成ؓ了可能,而同时由于插件开发框架对于动态性的支持Q得系l更加的灉|和可扩展。来看看一个插件开发框Ӟ应该提供些什么东西,作ؓ改变pȝ架构思想的框Ӟ插g框架需要考虑很多斚wQ如开发、测试、部|等Qȝ下来一个插件框架应提供插g的开发规范;插g开发、调试的IDEQ?/span> </p> </div> </td> </tr> </tbody> </table> <img src ="http://www.tkk7.com/coolfiry/aggbug/73097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/coolfiry/" target="_blank">Coolfiry</a> 2006-09-30 22:53 <a href="http://www.tkk7.com/coolfiry/archive/2006/09/30/73097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Sun 收购 JRuby 目, 两创始h加入SUNhttp://www.tkk7.com/coolfiry/archive/2006/09/11/68947.htmlCoolfiryCoolfiryMon, 11 Sep 2006 05:58:00 GMThttp://www.tkk7.com/coolfiry/archive/2006/09/11/68947.htmlhttp://www.tkk7.com/coolfiry/comments/68947.htmlhttp://www.tkk7.com/coolfiry/archive/2006/09/11/68947.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/68947.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/68947.html

摘要:

q日, Sun 宣布收购 JRuby 目.Sunl于开始表露出让不仅仅是Javaq行在JVM上的兴趣?

 
q日, Sun 宣布收购 JRuby 目.

Sunl于开始表露出让不仅仅是Javaq行在JVM上的兴趣?

q日,SUNq出了重要的一?

Charles Nutter, JRuby 的核心开发者之一, 宣布: Sun 已经整体收购了JRuby 目. 他与JRuby的另外一个核心开发?br />Thomas Enobo 都将会加入Sun.

从这ơ动作看的出来Ruby在Sun战略中的C,  看来Ruby很有可能成ؓJVM支持的第一个非Java语言.

动态语a, 已经不遥q了.

官方站点:
http://jruby.sourceforge.net/
(http://www.matrix.org.cn/resource/news/JRuby+Sun_954.html)


Coolfiry 2006-09-11 13:58 发表评论
]]>
用JNI调用C或C++动态联接库入门http://www.tkk7.com/coolfiry/archive/2006/09/09/68716.htmlCoolfiryCoolfirySat, 09 Sep 2006 08:30:00 GMThttp://www.tkk7.com/coolfiry/archive/2006/09/09/68716.htmlhttp://www.tkk7.com/coolfiry/comments/68716.htmlhttp://www.tkk7.com/coolfiry/archive/2006/09/09/68716.html#Feedback0http://www.tkk7.com/coolfiry/comments/commentRss/68716.htmlhttp://www.tkk7.com/coolfiry/services/trackbacks/68716.html阅读全文

Coolfiry 2006-09-09 16:30 发表评论
]]>
վ֩ģ壺 ɫƵѹۿ| һng| Ʒmnbavվ| ڵƵ߹ۿ| þþþAVר| MV߹ۿѸ| ձaƵ| ޹߹ۿ| պƵѿ| þþƷһ| ޳AVƬ߳ˮ| Ƶ| ĻӰѹۿ| һëƬѲ| ŮƵվ| ޾ƷŮɫ| ޹Ʒ߹ۿ| ŷÿѵӰ߹ۿ| aaëƬëƬѹۿ| 91Ʒ鶹ϵ| 鶹ۺ뾫Ʒ | Ʒվ| δʮ˽˸ӰԺ| պƷav| ޾ƷƵ| ԲaëƬ| AëƬƵл| ݹѹۿ| ޾Ʒһ23Ŀ| ޹Ʒþþþվ| 뾫Ʒ˳| 18ڵվ| ѸƵ| žžžƷƵ| һ| ۺУ԰ɫ| ޻ɫѹۿ| ޾ƷëƬ| ѹۿĻƷ| ҹįһۿ| Ʒ㽶߹ۿ|