积累,创造,分享!

BlogJava 首页 新随笔 联系 聚合 管理
  25 Posts :: 13 Stories :: 26 Comments :: 0 Trackbacks

2005年9月16日 #

问题现象:在做web应用时会碰到这种情况,某些地方无法通过web当中的ApplicationContext来获得springIOC容器提供的bean,比如提供给外界的webservice接口,这个时候就需要手工通过ClassPathXmlApplicationContext等方式来获取ApplicationContext,代码如下:
ApplicationContext context = new ClassPathXmlApplicationContext(
    "applicationContext-*.xml");
IXXXService xxxservice = (IXXXService ) context
    .getBean("xxxservice ");
这是一段很典型的加载。
然而,正是这种看似到处都是的加载却为后面的BUG埋下伏笔。
xxxservice是具体的业务类,它向下与DAO依赖并控制着事务,这里代表了一个经典而且简单的service,具体配置略去,值得一提的是scope,这里没有指定,默认的是单例。
一切都是那么顺利,像这样的service代码写的应该不下几百个,可能诸位写的更多,过程依然很陶醉,修改完毕。测试,再测试。什么?ORA-12519错误!见鬼,我打造的这套号称简易快速的SSH2框架已经在多个项目好评无数久经考验了,写了不下几百次的service居然报ORA-12519错误。
迅速打开PLSQL,检查数据库session,Select Count(1) From v$session t Where t.SCHEMANAME='XXX';
随着service的执行,session数在增加,没有减少的意思。是的,当时就是这样。

解决思路:这种错误出现在久经考验的框架当中,我心里是相当不安的,居然会有这种低级趣味的错误。整理思路开始分析:这段代码唯一与以前不同的地方就是,我们在web应用中,是通过容器加载提供bean的,只有容器启动的时候才会加载xml。那么重点就应该是关注XML的加载方式了。
在这里我们用的是ApplicationContext接口。注意看spring文档3.5.1.2.2 在非web应用中优雅地关闭springioc容器。它这里用到的是AbstractApplicationContext,在取得bean后,再执行一个context.registerShutdownHook();
这里实验一把,将ApplicationContext改成AbstractApplicationContext,执行context.close()。结果出来了,session已被正常回收,真相渐渐浮出水面。


结论:每次加载context的做法相当于每次都生成了一次新的spring容器,在默认单例的情况下,如果不及时关闭context。service所依赖的DAO当中创建的dataSource也一直存在(包括所有的单例情况下所生成的类),从日志看,service事务管辖中的session确实已经关闭,但SessionFactory还是存在的。只有在容器关闭的情况下,并指定了dataSource实例配置中的destroy-method="close",dataSource单例才会被释放。
spring文档当中对生命周期也描述的很清楚。通过DisposableBean或者指定destroy-method都能很好的释放单例对象。而prototype类型的对象需要客户端显式的指定释放,释放对象完全是客户端控制,spring不负责释放。
所以,要改善context的加载方式,尽量的少多次去加载,实在没办法的情况下,一定要记得关闭。
最后,写代码的随意性,图省事,不经思考,是造成这种BUG的罪恶根源。

posted @ 2009-04-16 17:27 nighthawk 阅读(2716) | 评论 (3)编辑 收藏

     摘要: 关注领域模型有一段时间了,不论是分析阶段的还是设计阶段的。
其实领域模型的概念很早就有了,但是其概念非常容易被人混淆,首先我们要明确一下这个词的语境:
它在软件开发的分析与设计的两个阶段分别代表不同的含义。
  阅读全文
posted @ 2008-03-23 00:01 nighthawk 阅读(1640) | 评论 (0)编辑 收藏

至于docbook的好处,我也不多说了,就跟吃菜一样,尝过了就知道到底有几好
趁目前有空,部门内部准备补充一下之前缺乏的技术文档。利用这次机会,我再次收想到了docbook。
记得第一次接触docbook的时候,还是3年前的时候了,可惜那个时候没有坚持使用下来。
当初抛弃它的原因是多方面的,缺乏恒心是一方面,配置烦琐也是一方面,另外还有一个很重要的原因就

是缺乏一个所见即所得的编辑器。而这次,这些烦恼彻底解决。XMLmind XML Editor!第一次发现它的时

候有点相见恨晚的感觉,它让我的文档写的如此轻松。
不过有一点要注意,在官网下载的XMLmind XML Editor个人版是不支持直接将xml生成的html,pdf等格式

的。还好,目前有xsltproc,fop,openjade这些工具支持,有了这些在windows下也可以转换的工具,生

成其他格式也不是什么难事。我目前就使用xsltproc来生成html。

附上XMLmind XML Editor的下载地址http://www.xmlmind.com/xmleditor/persoedition.html
附加上xsltproc的下载地址 http://www.zlatkovic.com/pub/libxml/
再附上docbook的地址http://www.oasis-open.org/docbook/

之前的麻烦统统消失,那么剩下的就是享受它的好处了。

不用word,文档也可以写的这么漂亮。docbook,看第二眼发现你依然还是那么好。

posted @ 2008-03-22 18:21 nighthawk 阅读(363) | 评论 (0)编辑 收藏

在目前使用的现有框架当中,利用springAOP机制来控制事务处理是目前最流行的一种控制事务的方式。

但是我们在某种使用场合的过程中,为什么有时事务处理老是不起作用呢?这里,为您道出原因之一,

首先请看一段话

Spring的事务实现采用基于AOP的拦截器来实现,如果没有在事务配置的时候注明回滚的checked exception,那么只有在发生了unchecked exception的时候,才会进行事务回滚。

有必要先解释一下checked exceptionunchecked exception

先看看EXCEPTIONJDK文档当中的结构

java.lang.Object
  继承者 java.lang.Throwable
      继承者 java.lang.Exception
          继承者 java.lang.RuntimeException
 
Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是特殊的。Exception是作为checked Exception 出现的。
所以,除了ErrorRuntimeException,其他剩下的异常都是你需要关心的,而这些异常类统称为Checked Exception
 

有了以上的基础,看看我们框架当中的事务属性

<property name="transactionAttributes">

                     <props>

                            <prop key="get*">PROPAGATION_REQUIRED,readOnly </prop>

                            <prop key="save*">PROPAGATION_REQUIRED </prop>

                            <prop key="delete*">PROPAGATION_REQUIRED</prop>

                            <prop key="update*">PROPAGATION_REQUIRED </prop>

                     </props>

 

</property>

 

此处,我们没有指定任何异常,那么它目前默认处理的就是unchecked exception了,再结合我们自身每个项目的模块,在我们的每个项目当中几乎都定义了自己的异常,这些异常都是继承自Exception,很不幸的是,我们继承的Exception包括自己定义的异常,都是checked exception

 

所以,在我们的事务处理机制当中,事务不管用了。

解决办法有2个:

1,在事务属性后面加上需要回滚的checked exception。比如<prop key="save*">PROPAGATION_REQUIRED,-XXXXException</prop>(注意那个"-",对应的是"+")

2, 不改配置文件,将需要事务回滚的异常继承自unchecked exception类,也就是RuntimeException

(nighthawk)

posted @ 2007-07-09 09:32 nighthawk 阅读(2069) | 评论 (3)编辑 收藏

现在再做2006年的总结,似乎有点晚了,毕竟现在阳历已经是2007年2月份了,不过按照老家的传统,没过春节,那还算2006年。按照总结的惯例,应该是先回顾后展望,所以我也先回顾。这个总结,只谈感受。
06年3月份,开始维护部门的一个新的项目,换了个新的环境,不过对我而言,接触的却不是新的技术。也许现在已经不是追新的阶段了。
做软件的都有个习惯,爱接触新的技术,这几年JAVA层出不穷的框架,技术太多了,让人有点应接不瑕。这些东西要是不接触,有时候还真会被人笑话,毫不例外,我也不落俗套,其实我并不是一个对新鲜事物非常敏感的人,不过有些技术,还是需要了解为好。
06年,接触的依然是struts,依然是hibernate,依然是spring。抽空看了看JSF,EJB3.0。spring和hibernate依然是那么辉煌,而struts,已经开始没落了。webwork2开始抢风头,包括现在的struts2,转眼间,已经不是我们熟悉的struts了,无非是包装过后的webwork2,转眼间,也感觉到了时间的流逝。通宵达旦培训学习struts的时候,已经是3年前了。
06年,接触了领域驱动设计,让我明白除了larman的领域模型,原来还有eric的领域模型,可惜目前,我依然是个学习者,而不是一个实践者。
06年上半年,我虔诚的捧来了martin的重构,可惜到目前为止,那本书还是新的。
06年,也接触了天书般的分析模式。它当之无愧的当选为我的最佳催眠书,以至于我现在不拿着它睡不着,因为它的确让我没看懂。
06年,我依然在看2年前买的UML和模式应用,依然偶尔翻翻1年前买的J2EE核心模式。不过这一年,J2EE核心模式似乎有点辉煌不在了。
头几年,感觉一切都是新的,一切都要学。而这一年,感觉进步远不如前2年了,也许进步更快,我没有发现而已。我一直在告戒自己,学习分析与设计不会有学习语言或者框架那种立竿见影的效果,它是一个积累,一个持续性的过程,我还在等着顿悟分析模式的那一天。
07年,我依然会追随大师们的脚步。
07年,还要继续做点什么。

posted @ 2007-02-13 09:55 nighthawk 阅读(258) | 评论 (2)编辑 收藏

          本文将不涉及EJB3.0的设计以及编码.
          主要内容是关于JBOSS下EJB3.0的第一个例子的配置与运行。
首先下载JBOSS4,并安装成功。目前JBOSS提供的ejb3有2种版本,一种是Embeddable(可嵌入),一种是直接运行。这些都可以在jboss的官方网站获得。
Embeddable版本的主要的好处是可以独立运行,方便测试,甚至无需部署在jboss环境当中,当然这是需要它提供的conf以及lib包里面的几个配置来支撑的。如果是在web应用当中运行,还需要将jboss-EJB-3.0_Embeddable_ALPHA_8\conf 里面的配置文件引入到web-inf\classes下的。
lib包里面的3个包也需要放在web-inf\lib下面。然后对web.xml进行修改,加上:
   <context-param>
      <param-name>jboss-kernel-deployments</param-name>
      <param-value>embedded-jboss-beans.xml, jboss-jms-beans.xml</param-value>
   </context-param>
   <listener>
      <listener-class>org.jboss.ejb3.embedded.ServletBootstrapListener</listener-class>
   </listener>
否则会报关于jndi方面的错误。

          前面提到的另一个版本则是需要基于JBOSS环境的完全版。它的配置相对于Embeddable来说更简单一些。   实际上针对这个版本的web应用当中调用EJB3 是无需任何额外配置的.
然而在此之前我走了一段弯路:
比如看到网上一些介绍性的文章当中提到需要将{jboss_home}\client 当中的一些包拷到web-inf\lib的下面,然后在初始化InitialContext时需要加上java.naming.factory.initial,java.naming.factory.url.pkgs等等的参数。这样反而会抛出CommunicationException: Receive timed out异常。实际上JBOSS都已经将初始化环境设置好了。
以下实例是web环境下调用jboss 下ejb3的客户端:
http://www.myjavaserver.com/~nighthawk/EJBClient.war
部署在jboss下的ejb3例子,以上2个客户端都是调用的它:
http://www.myjavaserver.com/~nighthawk/MyEJB.jar
web环境下调用Embeddable ejb的客户端的实例比较大,空间不够,不往上放了。
不过配置起来也很简单,只需将Embeddable版本当中的conf与lib包放在war包的classed与lib下即可。
以上例子均在jboss-4.0.4.GA下测试过。
                                                                                                                              ©2006 nighthawk.All rights reserved

posted @ 2006-07-28 16:21 nighthawk 阅读(759) | 评论 (1)编辑 收藏

研究spring不深,但最近在使用spring的过程中,发现它总能给人带来点惊喜。
相信大家在做程序的时候应该会碰到时序调度一类的问题,即希望在指定时刻执行某段程序,在spring之前我的第一反应便是在数据库中加job。然而现在,Spring提供了支持时序调度的整合类Quartz,它把复杂的事情完全简单化了,在此我不想再赘叙关于spring中如何去整合Quartz,具体的spring详细配置请参照http://www.jactiongroup.net/reference/html/scheduling.html。使用过程很简单,
关于Quartz的说明参照官网的一段描述
What is Quartz?
Quartz is a full-featured, open source job scheduling system that can be integrated with, or used along side virtually any J2EE or J2SE application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components or EJBs. The Quartz Scheduler includes many enterprise-class features, such as JTA transactions and clustering.
您也可以参考以下链接进行更深入的了解http://www.opensymphony.com/quartz

在使用的过程中,需要再对cronExpression的配置解释一下,如果没有使用过unix的cron,这里确实有点让人迷惑,我便在这里迷惑了一把。
Cron表达式是字符串,它由六个或七个子表达式组成,它描述了不同的调度细节。这些子表达式被白色表达式隔开,格式为* * * * * *
以下的表格对表达式做出了解释
域          是否必须 允许的值       允许的字符
Seconds      YES       0-59                   , - * /
Minutes      YES       0-59                   , - * /
Hours        YES       0-23                    , - * /
Day of month YES       1-31              , - * ? / L W C
Month        YES       1-12 or JAN-DEC, - * /
Day of week  YES   1-7 or SUN-SAT , - * ? / L C #
Year         NO         empty,1970-2099,   - * /

比如:字符串“0 0 12 ? * WEB 意味着每周三上午12:00。
特殊字符的一些说明:
* 表示的是所有的值,比如在秒的位置上有* 则表示为每一秒种。所以,你在表示每5分钟执行一次的时候便不能写成 * 0/5 * * * ? 而应该是0 0/5 * * * ?
? 表示没有指定特别的值,是允许为月的某一天或者周的某一天字段的。它被用来限定"没有限定值"。这是有用的,当你需要限定一些事情在一个或两个字段中,但不是这里的。
有一个特别需要主意的地方便是*与?的搭配使用。比如在Day of month与Day of week全是* ,那边自相矛盾了。官网中给出的例子没出现过这种情况。
- 表示范围,比如Hours域中10-12,则表示 "the hours 10, 11 and 12".
,表示指定特别的附加值,比如"MON,WED,FRI" 在 day of week 域表示"the days Monday, Wednesday, and Friday"
/ 表示指定的增长范围。比如"0/15" 在秒的区域表示"0, 15, 30, and 45"秒。

"L"字符是允许用来月某天和周某天字段。这个字符是一个"last"的缩写,但是它有不同的意义在两个字段的其中之一。例如,这个值"L"在月字段的某一天意味着" 这个月的最后一天",31或者28等等。

posted @ 2006-02-28 12:57 nighthawk 阅读(1069) | 评论 (0)编辑 收藏

看Larman的UML和模式应用,感觉浑身上下都是宝,一遍两遍都不过瘾。
这几天又在看GRASP(general responsibility assignment software patterns的缩写),把该记的都记一下,加深印象,也与大家分享。网上这方面的资料并不多。
五个基本模式:information expert,creator,High Conhersion,Low Coupling,Controller

四个扩展模式:Polymorphism,indirection,pure fabrication,protected variations

不想一一详叙,挑重点看。
1,information expert:把职责分配给具有实现这个职责所需要信息的对象。它表述的是一种“直觉”。
2,creator:顾名思义,谁应该负责产生类的实例?类B聚合,包含,记录,密切使用类A的数据。
3,high conhersion与Low coupling:应该是到了面向对象的高层境界了。高耦合:依赖性过强。内聚:功能性内聚。降低一切不稳定元素之间的耦合。
4,controller:如果直接通过UI来访问业务层,后果是不堪想像的。C/S模式的开发中它是用来接收事件的,它通常不实现职责,只是委托给其他对象。在B/S中,我把它理解为serlvet。
5,polymorphism:多态?这个词很别扭,一句话解释:多态是设计系统如何处理相似变化的基本方法。便于扩展,可嵌入。比如以下代码:

abstract class Square
{…
  
abstract void landedOn();
…}

class RegularSquare extends Square
{…
  
void landedOn()
 
{ … } // implementation
}

class IncomeTaxSquare extends Square
{…
  
void landedOn()
 
{ … } // implementation
}


6,indirection与pure fabrication:目的无非是为了降低耦合。对象的设计分为两类:表示分离与行为分解。indirection与pure fabrication都是行为分解的产物。比如说我们常见的DAO模式,我认为就是很好的pure fabrication。
7,protected variations:书中翻译为受保护变化。叫做受保护的变化似乎更容易被理解。受保护的变化机制的具体体现:多态,接口,中介,数据封装。与LSP(liskov替换原理)很相似。

posted @ 2005-11-30 14:11 nighthawk 阅读(712) | 评论 (0)编辑 收藏

今天看struts源码,发现了这么一个东西。在此是用来读取struts的XML配置文件的。以前没有大在意,现记下来,以备后用。
Digester是Jakarta 子项目Commons下的一个模块,是基于SAX接口的,它简化了SAX方法的解析过程。用的时候集中精力处理XML数据而不是花太多的时间在如何解析文件本身上。
以下是刚刚写的一个小例子:
 1import org.apache.commons.digester.*;
 2import org.xml.sax.SAXException;
 3import java.io.*;
 4
 5public class DigesterSample {
 6  public DigesterSample() {
 7    Digester digester = new Digester();
 8    digester.push(this);
 9    digester.addCallMethod("rocket/member""print"2);
10    digester.addCallParam("rocket/member/name"0);
11    digester.addCallParam("rocket/member/age"1);
12    try {
13      digester.parse(getClass().getResourceAsStream("rocket.xml"));
14    }

15    catch (SAXException e) {
16      e.printStackTrace();
17    }

18    catch (IOException ex) {
19      ex.printStackTrace();
20    }

21
22  }

23
24  public void print(String name, String age) {
25    System.out.println("name : " + name + "  age : " + age);
26  }

27
28  public static void main(String[] args) {
29    DigesterSample dig = new DigesterSample();
30  }

31}
相应的rocked.xml文件如下:
1<rocket>
2<member>
3<name>YaoMing</name>
4<age>25</age>
5</member>
6</rocket>
放在编译后的class同等目录下即可。

相关资源 http://jakarta.apache.org/commons/digester/
posted @ 2005-11-21 15:42 nighthawk 阅读(347) | 评论 (0)编辑 收藏

用同步器令牌来防止客户端的重复提交,这的确是个好注意!
特别是防止用户在浏览器当中点击后退或者刷新按钮所产生的不良影响。
道理其实很简单,大概流程为:输入请求-->比较值-->处理请求-->生成令牌-->保存令牌-->
准备响应-->外发响应。
在客户请求当中携带服务器前一次响应时发给客户端的令牌,去与服务器端保存的令牌相比较,如果相等,则说明当前是合法提交。而不过不匹配,则可能是重复提交了。
在具体的实现当中以jsp为例,在控制器当中采用servlet来负责管理令牌,将服务器端的令牌保存在session当中,通过每次的请求来更新这个令牌。然后在将要处理的业务逻辑之前判断提交上来的令牌是否合法。如果合法则继续执行,如果不合法,则避免执行正常的操作。
servlet当中生成token代码可如下:
public void saveToken(HttpServletRequest request){
         HttpSession session
=request.getSession();
         String token
=generateToken(request);
         session.setAttribute(Constants.TOKEN,token);
}
检查令牌合法性
public boolean isTokenValid(HttpServletRequest request){
        HttpSession session
=request.getSession();
        String saved
=session.getAttribute(Constants.TOKEN);
        String token
=request.getParameter(Constants.TOKEN);
if(saved.equals(token)){
      
return true;
}

     
return false;
}


在JSP端,通过助手类将当前生成的令牌保存在HTML的表单的隐含域当中。
比如
<input type="hidden" name="TOKEN" value="as8d7j3sk">

通过这种手段实现起来并不十分复杂。当然这只是防止用户提交的手段之一。其他的方法有待大家不断补充。
来源参考:Core J2ee patterns 2 


posted @ 2005-11-15 11:14 nighthawk 阅读(962) | 评论 (0)编辑 收藏

网上关于apache与tomcat整合的文章已经举不胜举。写下此文的目的只是为了整理一下刚刚配置成功后的思路。以免以后产生遗漏。经过几个小时的努力,终于能够将自己开发了几天的网站发布在互联网上了,这种感觉挺爽。
废话少说,先交代一下环境:
首先,机器的是用ADSL拨号宽带,没有固定IP,这个好办,先申请一个动态域名。网上这种资源还是比较多的,接着下载一个动态域名的客户端,将域名填上,这样每次拨号以后的动态IP便与当前的域名绑定。可以在其他网络上对本机利用申请的域名进行ping命令,看看当前域名是否有效。
解决了域名的问题以后,接下来便是重头戏。Apache与Tomcat的整合过程了。先准备好资源,下载Http server Apache2.0版本,tomcat4.1。以及Tomcat Connector也就是
mod_jk_apache_1.2.6_2.0.50.dll 。参考路径http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.6/
下载时一定要看清楚版本。在资源下载完毕后,便是开始安装了。按照提示安装完Apache2.0。在安装过程中会提示输入域名,输入刚刚申请的域名。然后将mod_jk.dll文件拷入Apache2\modules目录。接下来便是修改Apache2\conf下的httpd.conf文件了。
conf配置文件每个设置之前都有E文注释,目前还未来得急细看,有耐心的朋友可以仔细研究。我修改的地方只有如下几个:
1,ServerName XXX.XXX.XXX:80
2,DocumentRoot "盘符:/应用所在路径"
3,
4,Alias /应用所在文件夹/  "盘符:/应用所在路径"
    Options Indexes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all

5,设置index首页在index.html后面
最后加上
#connecting to tomcat using ajp13
    LoadModule jk_module modules/mod_jk.dll
    JkWorkersFile  "E:\JBuilderX\thirdparty\jakarta-tomcat-4.1.27-LE-jdk14\conf\workers.properties"
    JkMount /*.jsp ajp13
    JkMount /*.screen ajp13
    JkMount /*.do ajp13
.jsp *.screen *.do表示的是web应用中所支持的后缀名,LoadModule其实就是load Tomcat Connector。也就是mod_jk.dll。上面的JkWorkersFile后面跟的是tomcat路径下conf文件夹新建的workers.properties
内容如下:
workers.tomcat_home=E:\JBuilderX\thirdparty\jakarta-tomcat-4.1.27-LE-jdk14(我本机的tomcat路径)
workers.java_home=E:\JBuilderX\jdk1.4 (我本机的JDK)
ps=\
# worker.list=ajp13
worker.list=ajp12,ajp13 

worker.ajp12.port=8007
worker.ajp12.host=localhost
worker.ajp12.type=ajp12
worker.ajp12.lbfactor=1
            
worker.ajp13.port=8009        
worker.ajp13.host=localhost     
worker.ajp13.type=ajp13
worker.ajp13.lbfactor=1

worker.loadbalancer.type=lb
...................

接下来改tomcat的conf文件夹下的server.xml,在此无须更多修改。只需指定应用路径即可。此前网上很多文档所说的要打开Ajp13Connector处的注释,但此处并没有按此步骤做。好了,配置文件修改结束。

开始实验吧!在开始菜单处进行先对apachetest configration。测试通过。启动apache。再启动tomcat。打开动态域名的客户端。敲入申请的动态域名。本机可以访问了。顺便抓了MSN,QQ在线的好友,发给他们,集体测试了一把。得到的反馈居然是速度还可以!要知道我的是赛扬700+256M内存的古董机器。呵呵!不多说了,明天还得上班,赶紧睡了。

 

posted @ 2005-11-08 23:46 nighthawk 阅读(783) | 评论 (0)编辑 收藏

这些日子已经淹没在模式,OO,UML等概念的海洋当中了,看不到一点尽头,甚至连座灯塔都没有。
网上的资料多半是参差不齐,总希望能找到降龙十八掌。
重新装上了rose2003,希望它能给我带来一点光明。
最近看的书以及研究的东西:core j2ee patterns,UML模式与应用,sun的petstore表示层模式。
也许我应该拿本小说或散文来读一读了,自从接触了计算机以后,基本上不读这些东西了,都没什么感觉了。
posted @ 2005-10-26 15:40 nighthawk 阅读(1285) | 评论 (6)编辑 收藏

昨晚有幸进入央视演播1号大厅欣赏了梦想中国9进6的现场直播,的确精彩,比看电视感觉好多了。只是持续时间太长,从7点多一直到11点。搞得今天上班还困困的,好了,闲话少说。

我们在用JNDI来获取数据源已经不是什么新鲜事了,EJB当中的更是少不了这个东西。在看petstore时由JNDINames这个类还发现了原来JNDI所指的资源工厂不仅仅局限于以上这两种类型,我们自己定义的一些工厂类其实也可以指定,其实这也是不难想到的,但在实践过程中却还从未考虑到过。过程也不复杂。就拿petstore为例,只需在web-inf当中加入:

1<env-entry>
2    <description>This Entry Provides the name for the CatalogDAO Implementation Class so the Fast Lane Pattern may be used</description>
3    <env-entry-name>param/CatalogDAOClass</env-entry-name>
4    <env-entry-type>java.lang.String</env-entry-type>
5    <env-entry-value>com.sun.j2ee.blueprints.catalog.dao.GenericCatalogDAO</env-entry-value>
6</env-entry>
7


然后在CatalogDAOFactory类当中轻松几句。

InitialContext ic = new InitialContext();

String className 
= (String) ic.lookup(JNDINames.CATALOG_DAO_CLASS);

catDao 
= (CatalogDAO) Class.forName(className).newInstance();


便获得了工厂类的具体实例GenericCatalogDAO。这样岂不也来得痛快!

posted @ 2005-10-09 10:46 nighthawk 阅读(837) | 评论 (2)编辑 收藏

又是一年一度的国庆节,不多说什么了。祝所有人国庆节快乐!
posted @ 2005-09-30 13:21 nighthawk 阅读(157) | 评论 (0)编辑 收藏

上周末终于买下了Core J2EE Patterns的中文版,毕竟看e文版还是不怎么流畅。这两天有空看了看表现层的模式,有很多东西都似曾相见。它的一些应用在许多成熟的框架里面都得到了体现。比如Struts,在看到applicationcontroller的时候感觉真的非常棒,因为我的思路得到了它的验证,struts已经作为它的示例在说明。再比如说WAF框架,再打开PETSTORE的源码与书中提到的模式一对比,感觉真的很爽。虽然目前研究的还不够深入。但已经看到了前面的一点点光明。继续努力中......
posted @ 2005-09-28 17:45 nighthawk 阅读(454) | 评论 (0)编辑 收藏