在創(chuàng)建EJB組件時(shí),必需提供一些定義,使得EJB組件使用一些服務(wù)例如:安全服務(wù),持久化服務(wù),事務(wù)服務(wù)。EJB容器可以提供這些服務(wù),這樣EJB只要實(shí)現(xiàn)業(yè)務(wù)邏輯就可以了。但是說(shuō)到底EJB容器使用EJB組件的元數(shù)據(jù)來(lái)提供這些服務(wù),在以前EJB的元數(shù)據(jù)是以XML配置文件形式出現(xiàn)的,這些配置文件與EJB源文件是分開(kāi)的。
EJB的部署人員無(wú)法了解EJB本身的信息,如果EJB組件的創(chuàng)建者用注釋(Annotation)的方法將這些配置服務(wù)的信息和代碼放在一起,這樣EJB的部署者就可以了解EJB的信息,EJB的home接口可以使用Annotation自動(dòng)生成,當(dāng)然到目前為止更好的是在簡(jiǎn)單的Java Object上使用Annotations。
一 什么是Annotation
在已經(jīng)發(fā)布的JDK1.5(tiger)中增加新的特色叫 Annotation。Annotation提供一種機(jī)制,將程序的元素如:類,方法,屬性,參數(shù),本地變量,包和元數(shù)據(jù)聯(lián)系起來(lái)。這樣編譯器可以將元數(shù)據(jù)存儲(chǔ)在Class文件中。這樣虛擬機(jī)和其它對(duì)象可以根據(jù)這些元數(shù)據(jù)來(lái)決定如何使用這些程序元素或改變它們的行為。
二 定義一個(gè)簡(jiǎn)單的Annotation并使用它
1.定義Annotation
定義一個(gè)Annotation是什么簡(jiǎn)單的,它采取的是類似于Interface的定義方式: “@+annotation類型名稱+(..逗號(hào)分割的name-value對(duì)...)”
代碼
-
??
-
??
-
package
?sz.starbex.bill.annotation; ??
-
??
-
import
?java.lang.annotation.Retention; ??
-
??
-
import
?java.lang.annotation.RetentionPolicy; ??
-
??
-
import
?java.lang.annotation.Target; ??
-
??
-
import
?java.lang.annotation.ElementType; ??
-
??
-
@Retention
(RetentionPolicy.RUNTIME) ??
-
??
-
@Target
(ElementType.METHOD) ??
-
??
-
public
?
@interface
?SimpleAnnotation?{ ??
-
??
-
String?value(); ??
-
??
-
}??
@Retention這個(gè)meta-annotation表示我們創(chuàng)建的SimpleAnnotation這個(gè)Annotation將會(huì)存儲(chǔ)在Class文件中,并在java
VM運(yùn)行時(shí)加載它。@Target這個(gè)meta-annotation表示我們創(chuàng)建的SimplwAnnotation將會(huì)為描述方法,而@interface SimpleAnnotation是我們自定義的Annotation,它有一個(gè)成員叫value,返回值是String。
2.使用Annotation
代碼
-
??
-
??
-
package
?sz.starbex.bill.annotation; ??
-
??
-
import
?sz.starbex.bill.annotation.SimpleAnnotation; ??
-
??
-
public
?
class
?UsingSimpleAnnotation?{ ??
-
??
-
@SimpleAnnotation
(value=
"Pass:This?method?will?Pass"
)
??
-
??
-
public
?
void
?pass(){ ??
-
??
-
if
(
10
>
5
)?System.out.println(
"測(cè)試通過(guò)"
); ??
-
??
-
} ??
-
??
-
@SimpleAnnotation
(
"Fail:This?method?will?Fail"
)
??
-
??
-
public
?
void
?fail(){ ??
-
??
-
if
(
10
<
5
)?System.out.println(
"測(cè)試失敗"
); ??
-
??
-
} ??
-
??
-
}??
一個(gè)Annotation用于程序元素(在本例中是method),在method方法之前用(@Annotation名稱(name=value,name=value.....)。在本例中是@SimpleAnnotation(value="Pass:This method will Pass")。每個(gè)annotation具有一個(gè)名字和成員個(gè)數(shù)>=0,當(dāng)只有一個(gè)單一的成員時(shí),這個(gè)成員就是value。我們也可以這樣寫(xiě) @SimpleAnnotation("Fail:This method will Fail")。至此@SimpleAnnotation將Pass和Fail聯(lián)系起來(lái)了。
3.在運(yùn)行時(shí)訪問(wèn)Annotation
一旦Annotation與程序元素聯(lián)系起來(lái),我們可以通過(guò)反射訪問(wèn)它們并可以取得它們的值。我們使用一個(gè)新的interface:java.lang.reflect.AnnotatedElement。java.lang.reflect.AnnotatedElement接口中的方法有:
a. boolean isAnnotationPresent(Class annotationType)
如果指定類型的注釋存在于此元素上,則返回 true,否則返回 false。
b. T getAnnotation(Class annotationType)
如果存在該元素的指定類型的注釋,則返回這些注釋,否則返回 null。
c. Annotation[] getAnnotations()
返回此元素上存在的所有注釋。
d. Annotation[] getDeclaredAnnotations()
返回直接存在于此元素上的所有注釋。
你要注意 isAnnotationPresent和getAnnotation方法,它們使用了Generics,請(qǐng)參考我的Java 范型的Blog。
下面我們列出一些實(shí)現(xiàn)了AnnotatedElement 接口的類
1. java.lang.reflect.AccessibleObject
2. java.lang.Class
3. java.lang.reflect.Constructor
4. java.lang.reflect.Field
5. java.lang.reflect.Method
6. java.lang.Package
下面的Example程序說(shuō)明了如何在運(yùn)行環(huán)境訪問(wèn)Annotation
代碼
-
package
?sz.starbex.bill.annotation; ??
-
??
-
import
?sz.starbex.bill.annotation.SimpleAnnotation; ??
-
??
-
import
?java.lang.reflect.Method; ??
-
??
-
public
?
class
?SimpleAccessAnnotation?{ ??
-
??
-
static
?
void
?accessAnnotationTest(Class?usingAnnnotationClass){ ??
-
??
-
try
?{ ??
-
??
-
??
-
??
-
Method?[]?methods=usingAnnnotationClass.getDeclaredMethods();
??
-
??
-
for
(Method?method:methods){ ??
-
??
-
System.out.println(method.getName()); ??
-
??
-
SimpleAnnotation? ??
-
??
-
simpleAnnotation=method.getAnnotation(SimpleAnnotation.
class
);
??
-
??
-
if
(simpleAnnotation!=
null
){ ??
-
??
-
System.out.print(simpleAnnotation.value()+
"=="
); ??
-
??
-
String?result=invoke(method,usingAnnnotationClass); ??
-
??
-
System.out.println(result); ??
-
??
-
} ??
-
??
-
} ??
-
??
-
}?
catch
?(Exception?e)?{ ??
-
??
-
??
-
??
-
e.printStackTrace(); ??
-
??
-
} ??
-
??
-
} ??
-
??
-
static
?String?invoke(Method?m,?Object?o)?{ ??
-
??
-
String?result?=?
"passed"
; ??
-
??
-
try
?{ ??
-
??
-
m.invoke(m,
new
?Object[]{}); ??
-
??
-
}?
catch
?(Exception?e)?{ ??
-
??
-
??
-
??
-
result?=?
"failed"
; ??
-
??
-
} ??
-
??
-
return
?result; ??
-
??
-
} ??
-
??
-
?
-
-
?
-
-
??
-
??
-
public
?
static
?
void
?main(String[]?args)?{ ??
-
??
-
??
-
??
-
accessAnnotationTest(UsingSimpleAnnotation.
class
); ??
-
??
-
} ??
-
??
-
}??
Java 中的Annotation的定義
Java中的Annotation
Java定義了幾個(gè)標(biāo)準(zhǔn)的meta-annotation,在新Package中java.lang.annotation 中包含了以下meta-annotation:
meta-annotation 說(shuō)明
@Target
1. annotation的target是一個(gè)被標(biāo)注的程序元素。target說(shuō)明了annotation所修飾的對(duì)象范圍:annotation可被用于packages、types(類、接口、枚舉、annotation類型)、類型成員(方法、構(gòu)造方法、成員變量、枚舉值)、方法參數(shù)和本地變量(如循環(huán)變量、catch參數(shù))。在annotation類型的聲明中使用了target可更加明晰其修飾的目標(biāo)。
meta-annotation 說(shuō)明
@Target 1. annotation的target是一個(gè)被標(biāo)注的程序元素。target說(shuō)明了annotation所修飾的對(duì)象范圍:annotation可被用于packages、types(類、接口、枚舉、annotation類型)、類型成員(方法、構(gòu)造方法、成員變量、枚舉值)、方法參數(shù)和本地變量(如循環(huán)變量、catch參數(shù))。在annotation類型的聲明中使用了target可更加明晰其修飾的目標(biāo)。
2. ElementType的定義
TYPE// Class, interface, or enum (but not annotation)
FIELD// Field (including enumerated values)
METHOD// Method (does not include constructors)
PARAMETER// Method parameter
CONSTRUCTOR// Constructor
LOCAL_VARIABLE// Local variable or catch clause
ANNOTATION_TYPE// Annotation Types (meta-annotations)
PACKAGE// Java package
@Retention
1. SOURCE//按照規(guī)定使用注釋,但是并不將它保留到編譯后的類文件中
2. CLASS//將注釋保留在編譯后的類文件中,但是在運(yùn)行時(shí)忽略它
3. RUNTIME//將注釋保留在編譯后的類文件中,并在第一次加載類時(shí)讀取它
@Documented Documented 表示注釋?xiě)?yīng)該出現(xiàn)在類的 Javadoc 中
@Inherited 一個(gè)Annotation將被繼承
三個(gè)標(biāo)準(zhǔn)的Annotation 在java.lang包中:
@Deprecated 對(duì)不再使用的方法進(jìn)行注釋
@Override 指明注釋的方法覆蓋超類的方法
@SuppressWarnings 阻止編譯器的警告,例:當(dāng)類型不安全時(shí)
下例來(lái)說(shuō)明這三個(gè)標(biāo)準(zhǔn)的Annotation:
代碼
-
package
?sz.starbex.bill.annotation; ??
-
??
-
import
?java.util.ArrayList; ??
-
??
-
import
?java.util.List; ??
-
??
-
public
?
class
?SimpleOverrideAnnotation?{ ??
-
??
-
public
?
static
?
void
?main(String[]?args)?{ ??
-
??
-
SimpleOverrideAnnotation?test?=?
new
?SimpleOverrideAnnotation(); ??
-
??
-
System.out.println(test.toString()); ??
-
??
-
} ??
-
??
-
@Override
??
-
??
-
public
?String?toString()?{ ??
-
??
-
return
?
"自己的類自己輸出"
; ??
-
??
-
} ??
-
??
-
@Deprecated
??
-
??
-
public
?
void
?doSomething()?{ ??
-
??
-
System.out.println(
"方法已過(guò)時(shí)"
?); ??
-
??
-
} ??
-
??
-
@SuppressWarnings
(value={
"unchecked"
}) ??
-
??
-
public
?
void
?testSuppressWarnings(){ ??
-
??
-
List?testList=
new
?ArrayList(); ??
-
??
-
testList.add(
"KKKK"
);
??
-
??
-
} ??
-
??
-
}??
二、Annotation使用實(shí)例
一個(gè)組合的Annotation,注釋類的
a. 商標(biāo)Annotation
代碼
-
package
?sz.starbex.bill.annotation; ??
-
??
-
public
?
@interface
?Trademark?{ ??
-
??
-
String?name(); ??
-
??
-
String?owner(); ??
-
??
-
}???
b.License的annotation
代碼
-
package
?sz.starbex.bill.annotation; ??
-
??
-
import
?java.lang.annotation.*; ??
-
??
-
@Retention
(RetentionPolicy.RUNTIME) ??
-
??
-
@Target
({ElementType.TYPE,?ElementType.PACKAGE}) ??
-
??
-
public
?
@interface
?License?{ ??
-
??
-
String?name(); ??
-
??
-
String?notice(); ??
-
??
-
boolean
?redistributable(); ??
-
??
-
Trademark[]?trademarks(); ??
-
??
-
}???
c.測(cè)試類
代碼
-
package
?sz.starbex.bill.annotation; ??
-
??
-
@License
(name=
"Bill"
, ??
-
??
-
notice=
"許可證"
, ??
-
??
-
redistributable=
true
, ??
-
??
-
trademarks={
@Trademark
(name=
"Mercedes"
,owner=
"Swedish"
), ??
-
??
-
@Trademark
(name=
"Daewoo"
,owner=
"Korean"
) ??
-
??
-
}? ??
-
??
-
) ??
-
??
-
public
?
class
?TestLicenseAnnotation?{ ??
-
??
-
public
?
static
?
void
?main(String[]?args)?{ ??
-
??
-
TestLicenseAnnotation?test=
new
?TestLicenseAnnotation(); ??
-
??
-
License?license=test.getClass().getAnnotation(License.
class
); ??
-
??
-
System.out.println(
"License發(fā)放人:"
+license.name()); ??
-
??
-
System.out.println(
"License注意事項(xiàng):"
+license.notice()); ??
-
??
-
System.out.println(
"License許可:"
+license.redistributable()); ??
-
??
-
Trademark?[]?marks=license.trademarks(); ??
-
??
-
for
(Trademark?mark:marks){ ??
-
??
-
System.out.println(
"商標(biāo)名稱:"
+mark.name()); ??
-
??
-
System.out.println(
"商標(biāo)的使用者:"
+mark.owner()); ??
-
??
-
} ??
-
??
-
} ??
-
??
-
}? ??
-
??
from:http://java.chinaitlab.com/EJB/519586_2.html
posted on 2007-01-22 22:26
cresposhi 閱讀(995)
評(píng)論(6) 編輯 收藏