2007年11月28日星期三

spring 配置

From: https://www6.software.ibm.com/developerworks/cn/education/java/j-spring2/index.html

1. spring bean 描述符文件

spring-service.xml
例子:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="employeeService" class="com.ibm.dw.spring2.EmployeeDAO">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<bean id="entityManagerFactory" class=
"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>

<property name="databasePlatform" value=
"oracle.toplink.essentials.platform.database.DB2Platform"/>
</bean>
</property>

<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver"/>
</property>
</bean>

<!-- Driver class -->
<!-- bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:dwspring"/>
<property name="username" value="sa" />
<property name="password" value=" " />
</bean -->

<!-- JNDI -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/dwspring2" />
</bean>

<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>

2. 在 META-INF/context.xml 文件中配置类装入器

<Context>
<Loader loaderClass="org.springframework.instrument.
classloading.tomcat.TomcatInstrumentableClassLoader"/>
...
</Context>

3. 把 Spring 2 的上下文装入器侦听器添加到 Tomcat
Spring 2 要求挂接到 Tomcat 的上下文装入管道。可以在 WAR 文件的 WEB-INF/web.xml 文件添加以下行进行这个配置:

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
必须在 <servlet> 和 <servlet-mapping> 定义之前。

4. 在 META-INF/context.xml 中配置 JNDI 资源

<Context>
...
<Resource name="jdbc/dwspring2" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="bill"
password="lotus123" driverClassName="com.ibm.db2.jcc.DB2Driver"
url="jdbc:db2://192.168.23.36:50000/dwspring"/>
</Context>

5. WEB-INF/web.xml 中添加数据源的 JNDI 资源引用
...
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/dwspring2</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

6. WEB-INF/web.xml 中配置上下文参数,这个元素需要是第一个元素

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>spring2web</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dwspring2-service.xml</param-value>
</context-param>
...


7. 如果利用了 JPA 的话还需要 META-INF/persistence.xml 文件

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="dwSpring2Jpa" transaction-type="RESOURCE_LOCAL"/>
</persistence>

8. web.xml 中的 Spring DispatcherServlet 配置

<servlet>
<description>
Spring MVC Dispatcher Servlet</description>
<display-name>DispatcherServlet</display-name>
<servlet-name>dwspring2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwspring2</servlet-name>
<url-pattern>*.cgi</url-pattern>
</servlet-mapping>

9. DispatcherServlet 配置文件

默认情况下,用以下规则形成配置文件的名称:采用 Spring DispatcherServlet 的 servlet 名称,后面加上 _servlet.xml。

Spring DispatcherServlet 类通过 Web 容器接受传入的 Web 请求,并把它分配到某个控制器。

这个示例中,DispatcherServlet 用 dwspring2 名称配置,因此,配置文件应当在 dwspring2_servlet.xml。这个配置文件如下

dwspring2-servlet.xml 描述符

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="mainController" class="com.ibm.dw.spring2.web.MainController">
<property name="employeeService">
<ref bean="employeeService"/>
</property>
</bean>

<bean name="empDetailsController" class="com.ibm.dw.spring2.web.EmpDetailsController">
<property name="employeeService">
<ref bean="employeeService"/>
</property>
</bean>

<bean id="controllermap" class=
"org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/home.cgi">mainController</prop>
<prop key="/empdet.cgi">empDetailsController</prop>
</props>
</property>
</bean>

<bean id="viewResolver" class=
"org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/" />
<property name="suffix" value=".jsp"/>
</bean>
</beans>

2007年11月19日星期一

关于静态方法是否常驻内存

这篇帖子是我们 2005-8-18 日写的

在 Java 里,静态字段是常驻内存中的,但是静态方法是否也是常驻内存中呢?

来自 comp.lang.java.programmer 的回答:
------------------------------------
John Bollinger answered:
All instance fields of every object in the JVM and all static fields of every class in the JVM are always in (possibly virtual) memory. Some version of the code for all methods, static and non-static, of all classes currently loaded in the JVM are always in (possibly virtual) memory. These are direct implications of an instance being live in a JVM and of a class being loaded in a JVM. Why do you suggest otherwise?
Methods do not run in any case. Threads run, executing methods' code in the process.
----------------------------------------
Roedy Green answered:
They hang around in RAM until there are no more references to them. Then they can be GCed like anything else.
--------------------------------------------------
那么,是不是这样呢?
在 JVM 中,所有对象的的静态字段与实例字段都是在内存中,(对于实例字段来说,只有对象实例化才在内存中)
对于方法来说,只要类已经被 load 进 JVM,则不论其是否静态,都存在于内存中,区别只是对于静态方法,所有的实例及对象都指向同一个方法。
--------------------------------------------------
following is writed by me
then,does it work like following? 1. when class isn't be loaded in JVM --all fields not in memory
2. when class is loaded in JVM --static fields are in memory,but instance fields aren't in memory,all methods not in memory
3. when class is loaded in JVM,but it isn't be initialized,and its static method is invoked --all fields are in memory,static methods in memory,but instance methods aren't in memory 4. when class is initialized --all fields are in memory,all methods are in memory 5. Whether it's true or not? and at last,I want to know when are they be GCed? I'm puzzled by Roedy,static fields can be GCed? And static methods too?
-------------------------------------------------
Chris Uppal answered:
> then,does it work like following?
> 1.[...]
No. The following is a simplification (there are exceptions in certain "advanced" situation -- all of which involve classloaders), but it's close enough for a working approximation:
When a class is loaded, the code for its instance methods and static methods are treated identically. They are copied into the JVM's memory and stay there (with the class itself) until the JVM exits. Nothing is ever GCed.
Instance fields are part of the instances, so the memory used for storing any instance's fields is allocated when the instance is created, and released when the instance is GCed. Static fields are part of the class, and their memory is allocated when the class is loaded, and never released until the JVM exits. (Or until the class is itself GCed -- but that can never happen except in special applications which make sophisticated use of classloaders)
(Actually, the JVM is at liberty to play tricks to reduce memory consumption, as long as that is never visible to application programmers. That's an implementation detail, and will vary from JVM to JVM. As far as I, personally, know the only "trick" that is used is that the JITed form of the methods' code /can/ be created lazily (when the method is used, or is used more than a certain number of times), and that the compiled machine-code representation /can/ be thrown away if it has not been used for a while.)
> I'm puzzled by Roedy,static fields can be GCed? And static methods > too?
Roedy is wrong. If he is confusing you then it's probably best just to ignore him (on this subject).
=========================
现在我基本明白了,结论如下,欢迎拍砖:
1、class 没有 load 进 JVM 前,所有的 fields ,methods 均不在内存中
2、class 被 load 进 JVM 后
 a. 对于方法
  不论是 static 或 非 static 的,都一样的,总是跟 class 本身在一起的(即存放在内存中),永远不会被回收,除非 JVM 退出。他们的区别是,静态的方法不需要实例即可使用,而非静态的方法需要实例调用。
那么,除了安全的考虑外,以于使用者来说,调用 static 方法更方便,但并不会对内存造成额外的开销。
b. 对于属性
  静态属性是跟 class 相关的,所以总是当 class 被 load 进 JVM 时即存在于内存中,并不会被垃圾回收(所以,相比于实例属性,对于内存来说是有多余的开销的)。
  静态属性被回收的唯一情况是类本身被回收,这种情况的发生只有当某个应用单独使用了一种复杂的类装载器的时候才可能出现。
  实例属性是跟实例相关的,故只有类实例化后,才会放入内存,当实例被回收后,实例属性自然也不存在了。
Roedy 依然认为 static field 与 static Method 是可以回收的(从广义上来说应该是这样,有时间我研究一下 JVM 的规范再说):
-----------------------------------------------------
Roedy answered:
>Static *methods* ?? Surely not. And what's a reference to a static method?
A piece of code that invokes a static method would be a reference to a static method, but GC is only interested in what class references point to, not which method within that class.
On the other hand, a method might be inlined, interpreted or compiled. Over a session it might even exist in all three forms. Each method of the class can be handled separately. Presumably GC scavenges discarded compilations whose "effectively final" assumptions have been ruined by a new class loaded.

Understand JRE Downloader Size

From: http://weblogs.java.net/blog/stanleyh/archive/2005/05/deployment_unde_1.html

2007年11月18日星期日

How Can Implement Anti-virus File Scan In Java

How Can Implement Anti-virus File Scan In Java


first,you must have and install a anti-virus scan engine(ex,SSE-Symantec Scan Engine) in your server,host it in application server or not

second,your app must can communicated with the SSE server

third,using SSE API for java to scan files or file bytes in memory

last,return the scaning result to client


reference: http://www.developer.com/design/article.php/10925_3711331

2007年11月16日星期五

Java Annotation Introduction

Java Annotation Introduction

Java Annotation 是 JDK1.5 引入的新特性,其实就是代码里的一些标记,它并不会影响代码本身代表的意思,但一些开发工具或部署工具会对其进行解析并处理。这些工具或程序可以生成根据它一些新的代码,或者 xml 文件等等。

1. Annotation 的类型及定义方式
Annotation 有三种方式:

a)Marker - 只有名称,没有元素
Example:
public @interface MyAnnotation {
}

Usage:
@MyAnnotation
public void mymethod() { .... }

b)Single-Element - 只有一个元素,使用的时候可以有两种方式,效果是一样的,如下

Example:
public @interface MyAnnotation
{
String doSomething();
}

Usage1:
@MyAnnotation ("What to do")
public void mymethod() { .... }

Usage2:
@MyAnnotation (doSomething="What to do")
public void mymethod() { .... }

c)multi-value - 有多个数据元素,只有一种使用方式,就是 data=value

Example:
public @interface MyAnnotation {
String doSomething();
int count();
String date();
}

Usage:
@MyAnnotation (doSomething="What to do", count=1, date="09-09-2005")
public void mymethod() { .... }

2. 定义 Annotation 的一些规则
a) 必须以 @interface 开始,再加上名字,如 public @interface MyAnnotation{}
b) 方法不能有任何参数
c) 方法也不能抛出异常
d) 方法的返回类型只能是 primitives,String,Class,enum ,以及 array of the above types

3. JDK5 有两种 Annotation
1) Simple Annotation
这是 JDK5 本身提供的几个标记,你可以用他们来标记自己的代码,但不能用它们来定义新的标记,目前只有三个这样的标记
a) Override - 这个标记标记的方法必须是对父类的方法的重写,否则编译器会报错
b) Deprecated - 表明方法过时,如果使用了该标记标记的方法,则编译会产生警告
c) Suppresswarnings - 该标记指向的类或方法不产生警告信息,该标记标记的元素会影响该元素的所有子元素

如下例,则调用 doSomeTestNow() 时,不会产生 deprecation 警告
public class TestAnnotations {
public static void main(String arg[]) throws Exception {
new TestAnnotations().doSomeTestNow();
}

@SuppressWarnings({"deprecation"})
public void doSomeTestNow() {
Test_Deprecated t2 = new Test_Deprecated();
t2.doSomething();
}
}



2) Meta Annotation
这些标记是JDK提供的用来定义自己的标记的,有四种类型:
1) Target - 表明该标记应该应用到类的哪种元素上,有以下几种:

@Target(ElementType.TYPE)—can be applied to any element of a class
@Target(ElementType.FIELD)—can be applied to a field or property
@Target(ElementType.METHOD)—can be applied to a method level annotation
@Target(ElementType.PARAMETER)—can be applied to the parameters of a method
@Target(ElementType.CONSTRUCTOR)—can be applied to constructors
@Target(ElementType.LOCAL_VARIABLE)—can be applied to local variables
@Target(ElementType.ANNOTATION_TYPE)—indicates that the declared type itself is an annotation type

如:
@Target(ElementType.METHOD)
public @interface Test_Target {
public String doTestTarget();
}

2) Retention - 表明该标记应该保持在哪里及保持多长时间,有三种类型

RetentionPolicy.SOURCE—Annotations with this type will be by retained only at the source level and will be ignored by the compiler
RetentionPolicy.CLASS—Annotations with this type will be by retained by the compiler at compile time, but will be ignored by the VM
RetentionPolicy.RUNTIME—Annotations with this type will be retained by the VM so they can be read only at run-time

3) Documented - 表明 JavaDoc 工具生成文档时,这个标记会出现在生成的文档上
4) Inherited - 表明这个标记标记的类会自动继承该标记本身代表的类

如:
@Inherited
public @interface myParentObject {
boolean isInherited() default true;
String doSomething() default "Do what?";
}

//这个类会自动继承 isInherited,及doSomething 方法
@myParentObject
public Class myChildObject { }

From: http://www.developer.com/java/other/article.php/10936_3556176_1

2007年11月8日星期四

Singleton 的一些实现方式

使用单件模式的好处主要就是为了提高效率,节省资源
有两种实现方式:
一种是 lazy initialization, 只是 Singleton 实例只有使用时才创建
另一种是 early initialization,就是 Singleton 实例所在的类初始化的时候,Singleton 实例就已经创建

1. 推荐方式(lazy intialization)
但这种方式的缺点是只能用于静态域,不能用于实例域
public class Singleton {

static class SingletonHolder {
static Singleton instance = new Singleton();
}

public static Singleton getInstance() {
return SingletonHolder.instance;
}
}


2. 比较传统的实现方式(lazy intialization)
这种方式的缺点是每次调用都会使用同步,造成较大的资源开销
public class Singleton{
static Singleton instance;

public static synchronized Singleton getInstance() {
if (instance == null)
instance == new Singleton();
return instance;
}
}

3. 最臭名照著的 DCL(double-checked-locking Model),看上去很美,但不能正常工作(lazy intialization)
在 jdk1.4 的 Java Memory Model 下不能正常工作,但在 jdk 1.5 下做改进后则可以正常工作,见下一种实现方式
这种方式从代码上看去的好处:不会每次调用都使用同步,只有第一次使用时才会使用同步
不能正常工作的原因:多线程调用时,当其中一个线程调用该引用对象上的方法时,那个方法可能会看到该对象被部分初始化的状态,从而导致灾难性的失败

对于某些编译器来说,可能会允许调用被部分实例化的对象的共享变量。这样,在多线程的时候,可能线程A正在实例化对象到一半的时候,线程B就开始调用对象的某些方法或访问变量了,这样就会导致失败。

public class Singleton{
private static Singleton instance = null;

public Singleton getInstance() {
if (instance == null) {
synchronized (this) {
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}

4. 在上一种实现方式上做了改动,区别只是变量用了 volatile 关健字(lazy initialization)
只有在 jdk1.5 下才可以正常工作
效率上,第二种实现方式中的 synchronize 会慢点,但据说如果用 volatile 的话(第 4 种),比 synchronize 更慢,第一种效率更高

public class Singleton{
static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null)
instance == new Singleton();
}
}
return instance;
}
}

5. 这种方式是 early initailization
这种方式调用速度更块,但对资源的占用来说,由于是 early initialization 不一定是最好
public class Singleton{
private static final Singleton instance = new Singleton();
public Singleton getInstance(){
return instance;
}
}


另外,关于同步方法的效率,原文是这样的:synchronizing a method can decrease performance by a factor of 100 or higher;
我理解是可能会降低一倍或更高,不知道对不对?

关于 DCL 参考:http://en.wikipedia.org/wiki/Double-checked_locking

参考文章:
http://crazybob.org/2007/01/lazy-loading-singletons.html
http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl

2007年3月8日星期四

GWT for AJAX

今天发现 Google 有一个工具可以用来以Java 的方式来开发 AJAX 应用

http://www.ibm.com/developerworks/cn/java/j-lo-gwt-intro/index.html?ca=j-t10