随笔 - 18  文章 - 0  trackbacks - 0
<2010年2月>
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213

常用链接

留言簿

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

首先引包:
    import jxl.Workbook;
代码示例:
    jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File("C:/Documents and Settings/Administrator/桌面/department.xls"));   
    jxl.Sheet rs = rwb.getSheet("部门信息"); //sheet名称,也可以getSheet(0)方法取得sheet  
    String sheetContext = rs.getCell(1, 0).getContents();
    ServletActionContext.getRequest().setAttribute("sheetName", sheetContext);

具体操作见:
    http://philos.javaeye.com/blog/90802
posted @ 2010-03-09 11:22 lucas_y 阅读(144) | 评论 (0)编辑 收藏
hibenate的面试总结.
可能现在大家常常还会遇到一个些面试的时候问一些关于hibernate的问题,我个人觉得,这些东西一般做过开发的人在使用上没有任何的问题的,但是如果是要你来说就不一定能够说好的,下面是从goole上找的一些常见的面试。
1.Hibernate session接口的get和load方法有何异同?
答: get不到实体对象时会返回null,load会抛出异常
  - get会立即加载实体对象,load默认是延迟加载
  - get会忽略二级缓存(这个没有试验过),load则是一级和二级缓存都使用

2.在持久化层,对象分为哪些状态?分别列出来.
答:瞬时态(Transient)、持久态(Persistent)、脱管态(Detached)。
瞬时态(Transient)
是对象是创建时,瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或 saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。
持久态(Persistent)
是该对象在数据库中已有对应的记录,并拥有一个持久化标识,如果是用hibernate的delete()方法,对应的持久对象就变成瞬时对象,因数据库中的对应数据已被删除,该对象不再与数据库的记录关联。
    当一个session执行close()或clear()、evict()之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有数据库识别值,但它已不在hibernate持久层的管理之下。
  持久对象具有如下特点:
     1. 和session实例关联;
     2. 在数据库中有与之关联的记录。
脱管态(Detached)
当与某持久对象关联的session被关闭后,该持久对象转变为脱管对象。当脱管对象被重新关联到session上时,并再次转变成持久对象。
       脱管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等方法,转变成持久对象。
       脱管对象具有如下特点:
  1.本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;
2. 比瞬时对象多了一个数据库记录标识值。

3.lock和update区别
答: update是把一个已经更改过的脱管状态的对象变成持久状态
lock是把一个没有更改过的脱管状态的对象变成持久状态(针对的是因Session的关闭 而处于脱管状态的po对象(2),不能针对因delete而处于脱管状态的po对象)
对应更改一个记录的内容,两个的操作不同:
update的操作步骤是:
(1)属性改动后的脱管的对象的修改->调用update
lock的操作步骤是:
(2)调用lock把未修改的对象从脱管状态变成持久状态-->更改持久状态的对象的内容-->等待flush或者手动flush

4.save 和update区别
答: save是把一个对象做为一个新的数据保存, update则是把一个脱管状态的对象或自由态对象(一定要和一个记录对应)更新到数据库,其实一个是保存一个是更新,一看都知道是有什么区别了。

5.update 和saveOrUpdate区别
答:这个是比较好理解的,顾名思义,saveOrUpdate基本上就是合成了save和update,而update只是update;引用hibernate reference中的一段话来解释他们的使用场合和区别
通常下面的场景会使用update()或saveOrUpdate():
程序在第一个session中加载对象,接着把session关闭
该对象被传递到表现层
对象发生了一些改动
该对象被返回到业务逻辑层最终到持久层
程序创建第二session调用第二个session的update()方法持久这些改动
saveOrUpdate(po)做下面的事:
如果该po对象已经在本session中持久化了,在本session中执行saveOrUpdate不做任何事
如果savaOrUpdate(新po)与另一个与本session关联的po对象拥有相同的持久化标识(identifier),抛出一个异常
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.itfuture.www.po.Xtyhb#5]
saveOrUpdate如果对象没有持久化标识(identifier)属性,对其调用save() ,否则update() 这个对象     

6.flush和update区别
答:这两个的区别好理解update操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象//updateSQL
而flush是操作的在持久状态的对象。
默认情况下,一个持久状态的对象的改动(包含set容器)是不需要update的,只要你更改了对象的值,等待hibernate flush就自动更新或保存到数据库了。hibernate flush发生在以下几种情况中:
1, 调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合
get()一个对象,把对象的属性进行改变,把资源关闭。
2,transaction commit的时候(包含了flush)
posted @ 2010-03-08 16:14 lucas_y 阅读(194) | 评论 (0)编辑 收藏
        1、Web Services. 优先支持编写 XML web service 客户端程序。你可以用过简单的annotaion将你的API发布成.NET交互的web services. Mustang 添加了新的解析和 XML 在 Java object-mapping APIs中, 之前只在Java EE平台实现或者Java Web Services Pack中提供. 
 

  2、Scripting. 现在你可以在Java源代码中混入JavaScript了,这对开发原型很有有用,你也可以插入自己的脚本引擎。  

  3、Database. Mustang 将联合绑定 Java DB (Apache Derby). JDBC 4.0 增加了许多特性例如支持XML作为SQL数据类型,更好的集成Binary Large OBjects (BLOBs) 和 Character Large OBjects (CLOBs) . 

  4、More Desktop APIs. GUI 开发者可以有更多的技巧来使用 SwingWorker utility ,以帮助GUI应用中的多线程。, JTable 分类和过滤,以及添加splash闪屏。 

  5、Monitoring and Management. Mustang 添加更多的诊断信息,绑定了不是很知名的 memory-heap 分析工具Jhat 来查看内核导出。 

  6、Compiler Access.  compiler API提供编程访问javac,可以实现进程内编译,动态产生Java代码。  

  7、Pluggable Annotation. Java tool和framework 提供商可以定义自己的 annotations ,并且内核支持自定义annotation的插件和执行处理器  

  8、Desktop Deployment. Swing拥有更好的 look-and-feel , LCD 文本呈现, 整体GUI性能的提升。Java应用程序可以和本地平台更好的集成,例如访问平台的系统托盘和开始菜单。Mustang将Java插件技术和Java Web Start引擎统一了起来。 

  9、Security. XML-数字签名(XML-DSIG) APIs 用于创建和操纵数字签名); 新的方法来访问本地平台的安全服务,例如本地Microsoft Windows for secure authentication and communicationnative 的Public Key Infrastructure (PKI) 和 cryptographic services, Java Generic Security Services (Java GSS) 和 Kerberos services for authentication, 以及访问 LDAP servers 来认证用户. 

  10、The -ilities: 质量,兼容性,稳定性。 80,000 test cases 和数百万行测试代码(只是测试活动中的一个方面). Mustang 的快照发布已经被下载15个月了,每一步中的Bug都被修复了,表现比J2SE 5还要好。
posted @ 2010-03-05 16:34 lucas_y 阅读(154) | 评论 (0)编辑 收藏

原文地址:http://sjtu.blog.sohu.com/108202346.html

 

------------------------------------------软开开发篇-------------------------
-------------------------- 
 
     在我刚进软开的时候,我想,这有什么啊,泡着茶写点儿JAVA的日子么?最多用JAVA查
个数据库,插个数据库,还有啥?取钱存钱不也就是个人帐户数据的此消彼长么?IDE会帮你
发现任何一个细小的失误,而JAVA的简单语法也不会让你担心有什么疑难杂症.我不知道
跟我想法法一致的人有多少,但这确实就是我刚开始看软开的眼光,安逸,挣闲钱的地方.
 
     然则,就类似于能量守恒的定理,你做的东西少,一定是有人帮你做的东西多,JAVA是
简单,可是那是JVM做的东西多,就如银行,银行的系统之复杂,是任何一个人无法想象的,
然而它的真正目的不是像IBM一样要向别人出卖技术,所以对人才要求很高,它只是要使成
熟的技术造福于自己特色业务的推广,造福于针对业务的系统的开发,说白了,是靠业务的
走红而不是技术的复杂来挣钱,.JAVA虽简单,但是要想彻头彻尾学明白也难,那么银行软
开不允许这种复杂性存在,它简单,但不彻底,那么我们就要让它变得彻底的简单,我们要
继续开发自己的系统,提供一套很容易的开发平台,当这套平台开发出来之后,就招一批能
够泡着茶写JAVA的人去为业务服务,所以这就是软开表面给大家造成这样一种映向的原因
,工作难度是不大,但是绝对不是说银行系统无人,只是那些平台的工作者没有浮出水面,
或者相对来说比较低调而已. 
    回到了我不屑的泡着茶写JAVA,啊,的确,难度是不大,数据库查来查去,日志记来记去
,流程可能够复杂,但不是算法的复杂,只是实现起来很烦而已.但是,这些人真的有足够的
工夫泡茶么?大家喜欢用日新月异来形容当今社会的发展,形势日新月异了,业务需求一样
也是日新月异,于是他们每天都要针对各种业务需求写出不同的程序来,这个时候,他们的
关注点应该从技术转向业务上来.业务需求给他们的压力使他们再无暇关注技术本身,所
以写JAVA的人也有写JAVA的人的难处,只是业务上的繁琐,向来被纯正的喜欢搞底层/搞算
法的人所鄙视,的确,你的脑筋可能是很活,但是物尽其才,如果真的有这样的思维,是应该
去搞一些高深的东西,研究技术的创新,写JAVA,面对各种应用需求,是有些埋没,但是话又
说回来,这样脑筋很活的人能干这样的工作么?工作再枯燥也需要有人做,他们能有耐心应
付这样的枯燥么? 
    现在满大街的小公司,没有几个是真正搞什么底层东西的,大家其实都在针对各种业
务做各种项目,银行的开发之所以显得有些乍眼,主要是因为:1,国企大氛围;2,做出的东
西不用面对销售压力.其开发从技术含量来讲,并无本质区别. 
    所以在银行软开工作,绝大部分人,绝对部分学计算机的人,需要面临的是一个方向的
调整,需要将注意力从技术的深度转到业务的广度上来,一味盲目的觉得人家的工作乏味,
没技术含量是不现实的,这也是我目前一个态度的转变. 
    技术做到最后,就是大同,惟有业务,才能使其中的努力变成钞票,大家(尤其是学计算
机的人,尤其是并不适合搞算法,搞底层的人)如果想进软开,一定要有这样的认识. 
 
----------------------------------------------------------------------------
--------------------------------- 
 
------------------------------软开的压力篇----------------------------------
--------------------------- 
    银行软开之所以有些乍眼,前面说过一条,不用面对销售的压力,是,我们做出来,业务
人员就得用,可是真的没有压力么? 
        我曾经听说过这样一个例子:一个工行网点的客户经理,费尽了口舌,花了半天工
夫,说服了两个客户买基金,终于她们被说动了,坐下来填单子准备签字了,这个时候,系统
出故障了,交易无法进行,没办法,客户经理只能含着泪,带着她们出来,把她们指给旁边的
农行/建行(本人属于工行,这些时候自然偏向工行,其他银行朋友勿怪).这个例子,体现了
银行软开的一点压力吧,不论什么时间,不论什么情况,不论你用什么手段什么方法,请你
给我保持住稳定,如果系统慢,客户经理还可以陪客户聊天,可是如果宕了,什么叫所有努
力付诸东流,这就是. 
    银行在全国的网点,大的数以万计,小的也数以千计吧,各个地方,招来的柜员,那是怎
么样素质的都有,我曾听说过这样的柜员,这辈子她就会干两件事,做取款的交易和存款的
交易,转账怎么办?不会直接转账,先给A做提现的交易,再给B做存现的交易.内部实现怎么
别扭,但是外部的易用性你可得给我做足了,要不人家网点柜员是真不明白.记得唐朝诗人
白居易还是王安石,每写一首诗,都要问老百姓能不能看懂,软开面临的情况也很类似,白
居易王安石历史上就这么两个人,然而你要求每个软开员工每个项目都能做到这样,不觉
得有压力么?尤其是心高气傲的计算机人,那 更是不屑了.可是,这是软开,如果想进来玩,
请放下你的架子,认真/细致的处理好所有细节. 
    还有一个路人皆知的压力,如何保障运营系统的安全,大家存钱的时候按完密码键盘
了,系统没有响应,柜员要求你重新输入你会怎么想?难道不是我的密码被盗了?你怎么能
保证?这样的事情只要发生,只要桶上来,整个银行总部的领导层都会开始关注这个问题,
甚至银监会也要监督你的处理方式.这个时候,软开员工身上的压力将会可想而知,一旦最
后查明是程序的问题,所有一干人等(开发/测试/小组领导/部门领导),全部要受罚,这是
肯定的.网银的运营,得有多少加密措施来保障数据的安全,且不说技术上的加密算法,就
拿业务来说,大家去办个U盾,看那个网点工作人员得填多少单子,就知道银行为保证安全
,得下多少精力了. 
    很多小公司,常年就给一个医院/一个机关做项目,每做一个,挣10几万,然后全组人出
动到现场,花几天时间,解决各种安装遇到的问题,保证没问题后再大家都撤,老总请大家
吃饭.银行是怎么样?做一个项目,全国所有省份所有网点均要投产,如果大家各自全都出
动,人手够么?各种不一致的现象报上来,就是招10倍人也解决不了,所以银行软开压力最
大的时候就是投产前夕,所有人从老总到小兵全部通宵达旦地守在电脑旁,应付各种可能
问题的出现,而且作为高风险机构,银行在投产时候遇到的问题的解决,一定要准,一次性
成功!就如密码键盘来说,出现问题是系统不响应,马上回来改了,自己测过之后没问题,再
发补丁,结果造成系统崩溃,你可以想象一下客户的愤怒和不安!全中国这么大,我们不可
能到处跑过去看问题,所以,怎么样才能保证程序在全国跑都没问题,这是问题,也是巨大
的压力. 
    银行软开的压力,不来自于有没有客户,而来自于客户太多,给我们系统造成的压力,
无人问津的悲哀和无数人目光如炬的质询,后果都一样,让你身心俱疲. 
----------------------------------------------------------------------------
------------------------------------- 
 
------------------------------银行软开的发展篇------------------------------
----------------------------- 
    银行软开的发展,对于学计算机的人来说,是一个不小的难题,也是很多人对于要不
要来这很犹豫的问题,技术和业务上的难以抉择.还有国企多少的一点特色对自己发展造
成的干扰. 
    是的,这些都是问题,值得研究,第一个关于技术和业务的问题,我不想再多说,以挣钱
为终点,那么条条大路通罗马,以境界的追求为终点,软开可能不属于一个好的地方,毕竟
你的心高高在上,不屑于一些简单的活.路是自己选的,怎么走都可以,但是有一点要注意,
软开是有一部分专搞技术的人的,只是因为银行软开的出发点是针对业务做开发,所以为
开发提供更便捷方式的平台方面的人属于少而精的配置.因为一些国企的特色,进来后可
能因为我这篇文章,一些想要进来做平台的计算机人,有可能被领导分配到业务为主的开
发部门,关于这些人我想说的是,软开属于计算机研发为主的企业性质单位,人与人之间的
关系,沾点国企的影子,却远没有那么复杂,关于自己角色的的定位,你可以跟领导好好沟
通你的长处和你希望干的内容,一般来说,领导是会多少考虑的,即便不能百分百满足你需
要,百分之三十/四十/五十等等也能满足一些,只会闷头做技术,不会与人交流的人还是不
要来了,这里不适合你,即便你不跟领导沟通,你也需要跟下面分行的人沟通,交流,是工作
需要. 
    有的人会说,银行软开不挣钱,挣钱的是那些懂业务的人,这里首先要明确,什么样算
挣钱,工资是每个人都挣的,要是拿这个说的话就没意思了.大家说的应该是提成/分红的
那一类人,的确,软开挣不到那样一些钱,那些属于业务部该挣的钱.我觉得大家在讨论这
样一些问题的时候,首先要把自己摆正,软开的人,其实也就相当于一个IT公司的人,IT公
司的那一部分分红,软开一分钱都不会少,而且软开的钱有保证,不随经济危机而起伏.平
时福利也还可以.大家在羡慕业务的人拿得多的时候,是否可曾想到自己公司的销售在谈
好一个项目的时候提成也是远胜于自己工资的呢?只要你自己肯转变思路,专心学业务,借
助于自己的技术优势,以后去业务部分挣钱也不是没可能,关键就在于自己怎么看,不能既
不想作出改变现状的努力,又觉得人家挣钱挣那么多不公平.再者如果你实在干不了业务,
那么就干技术,转管理或者技术做到死当技术经理,总之就是成为领导,软开领导同样挣不
少钱,他们地位也和HP/IBM的高管地位一样,也许钱一年比人家的少些,但是国企有国企的
福利,这个是外企不能比的.每个人都该知足,生活提高一点,抱怨就该少一点,自己已经挣
了30W一年,够花了,听说别的部门一年年终奖拿了20W,全年工资50W也该把心态放平和些,
不就是钱么,又不是不够花,何不知足长乐呢?(注:业务部门不包括那些网点的柜员,他们
工资很少的). 
     软开的发展空间最大的难处在我看来,是这里虽然由业务指导开发,但是开发量很大
,导致你也不能完全放下你的技术,这样技术和业务之间徘徊不定,最终会有碍人的成长,
而且他的技术为了业务开发的便捷,被很好的简化了最后有可能技术没学成技术,业务也
没懂多少.这个是确实,一个地方不可能十全十美. 
    我的意见是,你一生比较想过安稳的生活可以来这,你如果是一个有追求的人,并且脑
筋可以变通的人,也可以来这,你如果是是一个有追求的人,并且好学的人(无论是业务还
是技术,都多得让你学不完,当你学得够多就有资格提前成为领导了),也可以来这.一个有
追求的人,并且勤勉踏实的人也可以来,有这么两类人,技术的大牛人不要来,你应该去百
度/GOOGLE发挥你的优势所在,有追求,但是没有什么魄力改变现状的人,就不要来,免得一
辈子平庸的现状可能让你万分苦恼. 
    还有一个难处我也提一下,它终归是国企,它注重能力,毕竟银行的系统不能瞎来,同
时也要求年限,年限一到才能往上升,所以不能忍的人也不要来了吧,当然也可以来了再走
~呵呵 
   最后我说一下薪资发展空间吧,现在银行软开一般待遇都不差,但是升值空间,在你没
成为领导之前涨幅不大,其实任何地方都一样,只有当领导,工资才能有质的变化,只是软
开要当上领导的周期比外企要长一些,也不会长得不可理喻,大家有的总说想来这,觉得稳
定但是又嫌工资涨得不快,这就是典型的鱼和熊掌都想得到的心理了,选择了软开,选择了
国企的稳定,必然要放弃一部分收入的增幅,既然思想不够纯粹,要为追求奋斗一生,而是
选择既有保障也要有追求的奋斗,那么你的生命里必将在别的地方付出一些代价,怎么样
都能成功,问题还是在于个人吧. 
    我简单说明一下,工行软开,属于总行编制,恩,就这么多了. 

posted @ 2010-03-01 11:25 lucas_y 阅读(1274) | 评论 (0)编辑 收藏

 代理模式


代理模式的作用是:

      为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。


代理模式一般涉及到的角色有:


抽象角色:声明真实对象和代理对象的共同接口;

代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

以下以《Java与模式》中的示例为例:

代码: //抽象角色:
abstract public class Subject{
abstract public void request();
}

//真实角色:实现了Subject的request()方法。
public class RealSubject extends Subject{
public RealSubject(){
}
public void request(){
System.out.println("From real subject.");
}
}

//代理角色:
public class ProxySubject extends Subject{
private RealSubject realSubject; //以真实角色作为代理角色的属性
public ProxySubject(){
}
public void request(){ //该方法封装了真实对象的request方法
preRequest();
if( realSubject == null ){
realSubject = new RealSubject();
}
realSubject.request(); //此处执行真实对象的request方法
postRequest();
}
private void preRequest(){
//something you want to do before requesting
}
private void postRequest(){
//something you want to do after requesting
}
}

//客户端调用:
Subject sub=new ProxySubject();
Sub.request();


      由以上代码可以看出,客户实际需要调用的是RealSubject类的request()方法,现在用ProxySubject来代理RealSubject类,同样达到目的,同时还封装了其他方法(preRequest(),postRequest()),可以处理一些其他问题。

      另外,如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。

2.动态代理

Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:

(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。

(2).Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。

Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。

所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。(参见文献3)

在使用动态代理类时,我们必须实现InvocationHandler接口,以第一节中的示例为例:

代码: //抽象角色(之前是抽象类,此处应改为接口):

public interface Subject{
public void request();
}

//具体角色RealSubject:实现了Subject接口的request()方法。
public class RealSubject implements Subject{
public RealSubject(){

}
public void request(){
System.out.println("From real subject.");
}
}

//代理角色:
import java.lang.reflect.Method;
import java.lang.reflect.InvocationHandler;
public class DynamicSubject implements InvocationHandler{
private Object sub;
public DynamicSubject(Object sub){
this.sub = sub;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before calling " + method);
method.invoke(sub,args);
System.out.println("after calling " + method);
return null;
}
}

该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object sub)对其赋值;此外,在该类还实现了invoke方法,该方法中的"method.invoke(sub,args)" 其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,args为执行被代理对象相应操作所需的参数。通过动态代理类,我们可以在调用之前或之后执行一些相关操作。

客户端:
代码: import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Client{
static public void main(String[] args) throws Throwable{
RealSubject rs = new RealSubject(); //在这里指定被代理类
InvocationHandler ds = new DynamicSubject(rs); //初始化代理类
Class cls = rs.getClass();
//以下是分解步骤
/*
Class c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces());
Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class});
Subject subject =(Subject) ct.newInstance(new Object[]{ds});
*/

//以下是一次性生成

Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),ds);
subject.request();
}

通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。

3.代理模式使用原因和应用方面

(1)授权机制 不同级别的用户对同一对象拥有不同的访问权利,如Jive论坛系统中,就使用Proxy进行授权机制控制,访问论坛有两种人:注册用户和游客(未注册用户),Jive中就通过类似ForumProxy这样的代理来控制这两种用户对论坛的访问权限.

(2)某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.
举例两个具体情况:
如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片.

如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.

总之原则是,对于开销很大的对象,只有在使用它时才创建,这个原则可以为我们节省很多宝贵的Java内存. 所以,有些人认为Java耗费资源内存,我以为这和程序编制思路也有一定的关系.

(3)现实中,Proxy应用范围很广,现在流行的分布计算方式RMI和Corba等都是Proxy模式的应用

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/goodHabit/archive/2009/11/08/4784461.aspx

posted @ 2010-02-04 17:52 lucas_y 阅读(196) | 评论 (0)编辑 收藏
JAVA反射机制
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
1. 得到某个对象的属性

1 public Object getProperty(Object owner, String fieldName) throws Exception {
2     Class ownerClass = owner.getClass();

4     Field field = ownerClass.getField(fieldName);

6     Object property = field.get(owner);

8     return property;
9 }
Class ownerClass = owner.getClass():得到该对象的Class。

Field field = ownerClass.getField(fieldName):通过Class得到类声明的属性。

Object property = field.get(owner):通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。

2. 得到某个类的静态属性

 1 public Object getStaticProperty(String className, String fieldName)
 2             throws Exception {
 3     Class ownerClass = Class.forName(className);
 4 
 5     Field field = ownerClass.getField(fieldName);
 6 
 7     Object property = field.get(ownerClass);
 8 
 9     return property;
10 }

Class ownerClass = Class.forName(className) :首先得到这个类的Class。

Field field = ownerClass.getField(fieldName):和上面一样,通过Class得到类声明的属性。

Object property = field.get(ownerClass) :这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取。

3. 执行某对象的方法

 1 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
 2 
 3     Class ownerClass = owner.getClass();
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Method method = ownerClass.getMethod(methodName, argsClass);
12 
13     return method.invoke(owner, args);
14 }
Class owner_class = owner.getClass() :首先还是必须得到这个对象的Class。

5~9行:配置参数的Class数组,作为寻找Method的条件。

Method method = ownerClass.getMethod(methodName, argsClass):通过Method名和参数的Class数组得到要执行的Method。

method.invoke(owner, args):执行该Method,invoke方法的参数是执行这个方法的对象,和参数数组。返回值是Object,也既是该方法的返回值。

4. 执行某个类的静态方法

 1 public Object invokeStaticMethod(String className, String methodName,
 2             Object[] args) throws Exception {
 3     Class ownerClass = Class.forName(className);
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Method method = ownerClass.getMethod(methodName, argsClass);
12 
13     return method.invoke(null, args);
14 }

基本的原理和实例3相同,不同点是最后一行,invoke的一个参数是null,因为这是静态方法,不需要借助实例运行。

5. 新建实例
 1 
 2 public Object newInstance(String className, Object[] args) throws Exception {
 3     Class newoneClass = Class.forName(className);
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Constructor cons = newoneClass.getConstructor(argsClass);
12 
13     return cons.newInstance(args);
14 
15 }

这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用newoneClass.newInstance()来实现。

Class newoneClass = Class.forName(className):第一步,得到要构造的实例的Class。

第5~第9行:得到参数的Class数组。

Constructor cons = newoneClass.getConstructor(argsClass):得到构造子。

cons.newInstance(args):新建实例。

6. 判断是否为某个类的实例

1 public boolean isInstance(Object obj, Class cls) {
2     return cls.isInstance(obj);
3 }

7. 得到数组中的某个元素
1 public Object getByArray(Object array, int index) {
2     return Array.get(array,index);
3 }
posted @ 2010-02-04 17:00 lucas_y 阅读(164) | 评论 (0)编辑 收藏