loading …

Archive

Posts Tagged ‘Java’

Java Code for Christmas

十二月 24th, 2009 edikud 5 Comments/222 hits

      刚刚和恺哥在Q上聊了一下关于Lonely Christmas的事,突然发现对于一个工科男生来说,使用程序代码来描述这个该死的鬼佬节日完全是可行的,于是乎就顺手敲出一段Java Code:

package edu.scut.emos.joke;

import java.util.Vector;
import edu.scut.emos.joke.human.Boy;
import edu.scut.emos.joke.human.Girl;


public class Christmas {
    public static void main(String[] args) {
        Boy me = new Boy("Haipeng");
        try {
            Vector<Girl> girls = me.findSomeGirls(); // Find the available girls
            Girl girl = girls.firstElement(); // Find the girl with highest priority
            me.niceChristmas(girl);
        } catch (NullPointerException e) { // It means the boy can not find a girl
            me.lonelyChristmas();
        } finally {
            me.christmasOver();
        }
    }
}

 

通常来讲,该程序的运行结果会是:

Lonely Christmas!! T_T
Christmas Over!! =_=

 

大家一起来YY~~哇咔咔~~

摆弄Hibernate3.X

六月 11th, 2009 edikud 0 Comments/164 hits

      最近几天在摆弄Hibernate3.X,体会一下Hibernate3.X和2.X版本不同的地方。使用的是一些在2.X版本下可以正常运行的程序和配置文件。发现要从2.X升级到3.X还是需要解决蛮多问题的。

      例如Hibernate2.X所使用的类似于hbm2java这样从映射文件生成java代码的工具已经从Hibernate Extensions包中移到了HibernateTools包里面,该包是作为eclipse发布的,所以如果要使用ant的话,就必须自己在那个包中找到hibernate-tools.jar,放入编译环境的classpath。具体的使用就看HibernateTools的指南吧。但是Hibernate3.0依然把SchemaExporter保留了,但是还是建议使用HibernateTools里面的工具,因为这些工具用统一的接口HibernateToolTask,感觉更好管理。

      其次就是发现Hibernate3.3.1GA里面附带的依赖库不够完整,首先是只带了slf4j-api库而没有slf4j-simple或者slf4j-log4j12(选择前者可以使Hibernate用JDK1.4 logging,而后者则可以使用log4j),这在从hbm文件生成java代码的时候会遇到问题;然后还发现少了一个库:Apache的commons-logging,这个库是使用hbm文件导出schema到数据库和文件的时候所需要的……让人无奈的是,HibernateTools需要的是这两个库提供的log功能,为啥不能统一一下呢,这可不是对外接口哦….

      顺便提醒一下教育网的同学们,由于使用HibernateTools的时候,在解析XML文件时会先校验XML格式,所以会链接http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd , 但是由于我们的网络环境比较封闭,可以直接在hibernate3.jar中获取到这个文件以及hibernate-configuration-3.0.dtd文件放到本地某个地方,之后将所有hbm.xml文件的DOCTYPE都指向那里,这样就不需要连接外网也能检验hbm.xml文件了。

      而且在生成schema的过程中,发现HSQLDB会丢失生成的数据表(我使用的是HSQLDB-1.8),而MySQL没有这个问题。在网上找了一些相关的文章发现,这都是拜HSQLDB的缓存机制所赐的,如果放任hsqldb随jvm关闭,一定会丢失数据,我们在url上加入了特殊标记"shutdown=true",就能保证每次conn.close()都会关闭数据,将数据写入file.script,相对的也使缓存完全丧失了效果,例:"jdbc:hsqldb:file:${data.dir}/music;shutdown=true”。相关引用文献:http://hi.baidu.com/hxzon/blog/item/1c607dcb0eb88a1abf09e6ca.html

      Hibernate3.X与Hibernate2.X不同的地方还是挺多的,例如在3.X里面就不能用session.find方法了,只能使用Query或Criteria接口进行数据查询。但是总体上大同小异,主要区别还是在于Hibernate3.X对旧版本的功能扩展,如加上自定义持久化实现机制等,从向后兼容性上来看,还可以。

使用Guice玩依赖注入

四月 21st, 2009 edikud 1 Comments/126 hits

        Guice是Google的一个轻量级的依赖注入框架,使用这个框架可以很容易的实现模块间的依赖注入,有效提高模块之间的解耦和程度,使模块之间的交互更灵活、更容易维护。

      下面先来看一下Guice的运行机制:

        guice

      然后通过一个非常简单的例子来说明Guice的使用:

      首先,建立一个接口,这个接口的实现就是需要被注入的服务:

1 public interface Im {
2      public void say(String s);
3      public boolean connect();
4      public boolean disconnect();
5 }

      然后,我们编写来个实现该接口的具体实现:

实现1,ImImpl:

01 public class ImImpl implements Im {
02     @Override
03     public boolean connect() {
04           System.out.println("ImImpl connected!");
05           return true;
06     }  
07    
08     @Override
09     public boolean disconnect() {
10           System.out.println("ImImpl disconnected!");
11           return true;
12     }
13       
14     @Override
15     public void say(String s) {
16           System.out.println("ImImpl say:"+s);
17     }  
18 }

 

实现2,ImMock:

01 public class ImMock implements Im {
02   
03     @Override
04     public boolean connect() {
05         System.out.println("ImMock connected!");
06         return true;
07     }
08
09     @Override
10     public boolean disconnect() {
11         System.out.println("ImMock disconnected!");
12         return true;
13     }
14  
15     @Override
16     public void say(String s) {
17         System.out.println("ImMock say:"+s);
18     } 
19 }

 

      接下来,我们编写一个依赖于Im接口的类,MyIm:

01 import com.google.inject.Inject;
02 import edu.scut.emos.im.Im;
03  
04 public class MyIm{   
05
06     Im impl;
07     
08     @Inject
09     public MyIm(Im impl){
10         this.impl = impl;
11     }
12
13     public void doit(String detail){
14         impl.connect();
15         impl.say(detail);
16         impl.disconnect();
17     }
18     
19 }

 

      在第8行处,我们使用了@Inject注解,该注解用来告诉Guice框架,这里是一个注入点。

      接着,我们要编写一个配置模块,用来配置被注入的具体服务以及注入的目标:

01 import com.google.inject.Binder;
02 import com.google.inject.Module;
03 import com.google.inject.Scopes;
04 import edu.scut.emos.im.Im;
05 import edu.scut.emos.im.ImImpl;
06 import edu.scut.emos.im.ImMock;
07
08 public class MyModule implements Module {
09
10     Class<? extends Im> theClass = ImImpl.class;
11     
12     public void setInstance(int i){
13         if(i>0){
14              theClass = ImImpl.class;
15         }else{
16              theClass = ImMock.class;
17         }
18     } 
19
20     @Override
21     public void configure(Binder binder) {
22         binder.bind(Im.class).to(theClass).in(Scopes.SINGLETON);      
23     }
24    
25 }

 

      该配置模块实现了Guice的Module接口,实现它的cofigure,根据之前给出的时序图,我们知道Guice就是通过这个方法来实现注入的,所以能通过重写这个方法来绑定输入的具体服务和注入点。第22行代码详细描述了这个情况:将Im接口(Im.class)和具体的实现(theClass)绑定,范围指定是Scopes.SINGLETON,也就是说,每一次注入都是使用最初生成的那个服务实体对象,而不用另外再新建一个实体对象来注入,除非我们改变了被注入的服务。

        最后来一个演示程序:

01 import com.google.inject.Guice;
02 import com.google.inject.Injector;
03
04 public class Main {
05     public static void main(String[] args) {
06         MyModule module = new MyModule();
07         module.setInstance(1);
08         Injector inj = Guice.createInjector(module);
09         MyIm myIm = inj.getInstance(MyIm.class);
10         myIm.doit("test");
11        
12         module.setInstance(0);
13         inj = Guice.createInjector(module);
14         myIm = inj.getInstance(MyIm.class);
15         myIm.doit("test");
16     }
17 }

        程序的执行结果就是:

ImImpl connected!
ImImpl say:test
ImImpl disconnected!
ImMock connected!
ImMock say:test
ImMock disconnected!

      前三行是由ImImpl输出的,后三行是由ImMock生成的,我们在程序的执行流程中,通过改变配置模块(myModule)的内容,通过Guice来为MyIm注入具体的Im实现,得到我们想要的MyIm对象。这就是Guice可以带给我们的最基本的注入功能,可以很方便很快捷地实现依赖注入,Guice还提供了很多的注入类型和配置选项,建议大家都去试试看。

      Guice官方网站:http://code.google.com/p/google-guice/

使用pojo实现enum

三月 20th, 2009 edikud 3 Comments/235 hits

      enum是java1.5的新特性,可以实现在C/C++中的枚举功能,但是这种特性要JDK1.5才有,对于一些要使用JDK1.5以下的的JDK版本进行开发的项目 来说就不得不寻求其他的方案了。

      之前我做的项目要在JDK1.3的虚拟机上面运行,而我用的JDK是1.6的版本,所以在最终整合的时候出现了一些问题,后来经师兄指点,结合网上的资料,利用java本身最 础的类特性(pojo)实现了enum。

      举个例子,下面先来看一段 enum 的代码:

         enum Color{

                red,blue,yellow,black,white;

         } 

       声明了一个含有五个枚举量的枚举Color,这是在JDK1.3下面是运行不了的,我们给他来个重构:

          class Color{

                  public static final Color red = new Color(0);

                  public static final Color blue = new Color(1);

                  public static final Color yellow = new Color(2);

                  public static final Color black = new Color(3);

                  public static final Color white = new Color(4);

                  int value ;

                  private Color(int value){
                          this.value = value;
                  } 

                  public int getValue(){
                          return this.value;
                  }

          }

      经过这样的改造,两种Color其实已经在使用上有很强的兼容性了,至少在java中的类C形式的代码中,实现了行为的一致。无论Color是使用enum还是class定义,我们都可以使用下面的代码:

          Color r = Color.red;

          Color b = Color.blue;

          Color color = Color.red;

          if(r != b){......}

          if(color == b){......}

    我在JDK1.5下面编写的代码经过这样的重构,就可以在JDK1.5下面运行了。