Eclipse Ganymede (Eclipse 3.4)版本出来很久了,一直没有在这个版本上搞定离线安装subclipse插件,不论是link,还是copy到dropins目录,却无法识别插件,今天在Mac上捣鼓时无意间问了Roy一句,他说3.4版本下的插件似乎不能有site.xml文件,否则好象会被认为在线安装。我随手删除掉site.xml,重新启动eclipse,居然装好了 ![]()
在Java中,有两种初始化块:静态初始化块和非静态初始化块。
静态初始化块:使用static定义,当类装载到系统时执行一次。若在静态初始化块中想初始化变量,那仅能初始化类变量,即static修饰的数据成员。
非静态初始化块:在每个对象生成时都会被执行一次,可以初始化类的实例变量。
非静态初始化块会在构造函数执行时,且在构造函数主体代码执行之前被运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package com.tiandinet.studyjava; public class TestInitiateBlock { { System.out.println("In non-static initialization block!"); }; static { System.out.println("In static initialization block!"); }; public TestInitiateBlock() { System.out.println("In Constructor1!"); } public void show() { System.out.println("In show()!"); } /** * @param args */ public static void main(String[] args) { TestInitiateBlock ti = new TestInitiateBlock(); ti.show(); } } |
运行结果:
In static initialization block!
In non-static initialization block!
In Constructor1!
In show()!
虽然之前一直做PHP的开发,但一直没有用过memcache,仅是知道一些简单的原理。今天突然来兴趣,想试一下memcache,和PHP下的调用。
1. 安装memcached (服务器版本1.2.6)
服务器OS是RHEL5(Red Hat Linux Enterprise 5),之前已经装好LAMP环境,这是我们的一台测试服务器,LAMP均位于/opt/lamp下。准备将memcached安装在/opt/cache/memcached目录下。
memcached需要libevent(http://monkey.org/~provos/libevent/)的支持,所以需要先安装libevent,安装目录位于/opt/cache/libevent,下载最新版本的libevent(此例中为1.4.8),解压后进入源代码目录,进行配置和安装。
./configure --prefix=/opt/cache/libevent make make install
接着安装memcached,使用的版本是1.2.6,进入解压后的源代码目录,
./configure --prefix=/opt/cache/memcached --with-libevent=/opt/cache/libevent
–with-libevent指令指定libevent的目录 (阅读全文……)
在原项目中,对文件上传的处理并不是使用Spring的MultipartResolver,而是使用自定义的MultiPartFilter和HttpServletRequestWrapper结合来进行处理。
MultiPartFilter是一个定义在web.xml中的<filter>,原理是通过判断HttpServletRequest中的contentType是否包含”multipart/form-data”,若代码中包含此字符品,则表明是一个File Upload请求,就使用JakartaMultiPartRequest来对HttpServletRequest对其进行包装。
其代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class MultiPartFilter extends GenericFilterBean { public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; String content_type = request.getContentType(); if (content_type != null && content_type.indexOf("multipart/form-data") != -1) { JakartaMultiPartRequest jakartaMultiPartRequest = new JakartaMultiPartRequest(request, getFilterConfig().getInitParameter("saveDir"), Integer.valueOf( getFilterConfig().getInitParameter("maxUploadSize")).intValue()); request = jakartaMultiPartRequest; } filterChain.doFilter(request, servletResponse); } } |
JakartaMultiPartRequest类继承自HttpServletRequestWrapper,在其构造方法中,我们对Request进行分析,并且保存用户上传的文件,将文件名等信息放到Request的attribute中,从而在后续的代码中可以对上传的文件进行处理。
但在后来客户进出的对产品图片处理的新需求中,因为JakartaMultiPartRequest的问题,没有办法满足我们的要求,所以考虑到使用Spring的MultipartResolver来进行上传处理,但之前的代码不能再进行改动,否则所有处理文件上传的Controller必须更改,代价很大。但如果在Spring中进行配置MultipartResolver的配置后,发现我们旧的文件上传代码都失效了,无法上传文件。 (阅读全文……)
折腾了两天,终于在JBoss Seam中搞定了JSF Converter。
在这个程序中,产品(Product)和分类(Category)是多对多的关系,关系维护方为产品,在创建产品时,允许选择多个分类,因为Product.categories是一个List属性,同时产品选择<select />标签也是由从Action中查询出来的所有Category的List,所以在页面上,需要在页面渲染、用户提交后的category进行转换。
显示时,我们以Category.id为<option />的value值,而Category.title为label。
Entity如下(省略setter和getter):
Category.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @Entity @Table(name = "category") public class Category extends BaseEntity { @Id @GeneratedValue @Column(name = "id", unique = true, nullable = false, length = 10) private Integer id; @Column(name = "title") @NotNull @Length(min = 4, max = 64, message = "{invalid.length}") private String title; @ManyToMany(mappedBy = "categories") private List<product> products = new ArrayList</product><product>(); } </product> |
享元模式的宗旨:通过共享来为大量的细粒度对象提供有效支持。
避免大量拥有相同类型的小类(细粒度,小类中的不可变部份)的开销(如耗费内存),使所有客户代码共享一个实例(元类)。
怎么使用?(以人力资源系统中的公司员工为例): (阅读全文……)
一般来说,在需要对某个员工进行访问的时候,我们都会new一个员工类,如果两个客户代码同时访问同一个员工,则会产生两个相同(或部份相同)的同一员工实例,这样,对于一个员工来说,内存中就可能有该员工的多个实例存在,如果一个企业有10000个员工,那内存中实际的员工实例可能就不止10000个。在这种情况下,我们就可以用享元模式来解决这个问题。
模板方法模式的目的就是在一个方法中实现一个算法,并将算法中某些步骤的定义推迟,从而使得其他类可以重新定义这些步骤。
在编写一个方法的时候,考虑到算法的某些步骤可能会有不同的实现方式,我们可能会首先定出算法的框架。这样,在定义方法的时候,我们可以将某些步骤定义为抽象方法,或者是将它们定义为存根方法,也可以将它们定义为某个单独接口中的方法,这就是模板方法模式的实现。
模板方法的典型例子就是排序。java.util.Collections类将sort()方法定义为一个模板方法,而将其中的比较交给用户来实现,sort()方法所接受的List中的对象需要实现Comparator接口,这就是将实际算法推迟并交给其它类来实现的模板方法模式。
并不是能创建并返回一个新的对象的方法都是工厂方法模式的实例。
工厂方法模式不仅要求有一个能够创建新对象的方法,还要求能够使得客户代码无需了解应该具体实例化哪个类。工厂方法模式通常会包含有若干个类,这些类实现了相同的操作,返回了相同的抽象类型,然而,这些类的操作在内部实际上实例化了不同的类,不过这些类都实现了上述抽象类型。
工厂方法模式的特征:
1. 该方法创建了一个新的对象。
2. 该方法的返回类型为一个抽象类或接口。
3. 有若干个类实现了上述抽象类或接口。
比如我们要实现一个在线客户服务系统,若客服人员在线的时候,客户提交的问题将会直接传送给客服人员;若客服人员不在线,则将客户提交的问题发送至客服信箱。
(阅读全文……)
观察者模式的宗旨:在多个对象之间定义一个一对多的关系,当一个对象状态改变的时候,其他所有的依赖于这个对象的对象能够得到通知,并自动更新。
观察者模式在Swing中得到了广泛应用。当客户单击按钮时,程序中许多对象都会对此做出反应。在Swing中,关注Swing组件变化的类被称为“监听器”,这就是观察者模式的应用。
为了支持观察者模式,Java类库中的java.util包中提供了Observable类和Observer接口。
我们现在举一个例子来说明观察者模式。
在网上商店的应用中,如果我们希望产品的名称被更改了后,系统会自动在控制台打印新名称,则就可以使用观察者模式。此时,产品类Product就需要继承Observable类,产品观察者类NameObserver则需要实现Observer接口。
单体模式的宗旨就是:使一个类只有一个实例。
我们可以将类的constructor的可见性设置为私有来避免创建多个实例。当其他类调用该类的时候,我们可以利用getInstance()之类的方法来返回给调用者该类的实例。
比如:
1 2 3 4 5 6 7 8 9 | private Factory factory = null; public static Factory getFactory() { if (factory == null) { factory = new Facotry(); } return factory; } |
上面的例子实现了单体模式,但如果在多线程环境中采用此方式,仍然可能产生多个实例,最好的办法,用synchronized来控制Factory实例的生成。