註解
Java SE5內置了三種標準註解:
@Override,表示當前的方法定義將覆蓋超類中的方法。
@Deprecated,使用了註解爲它的元素編譯器將發出警告,因爲註解@Deprecated是不贊成使用的代碼,被棄用的代碼。
@SuppressWarnings,關閉不當編譯器警告信息。
自定義註解
2)當我們使用@interface關鍵字定義一個註解時,該註解隱含地繼承了java.lang.annotation.Annotation接口;
3)如果我們定義了一個接口,並且讓該接口繼承自Annotation,那麼我們所定義的接口依然還是接口而不是註解;
4)Annotation本身是接口而不是註解。可以與Enum類比。
5)當註解中的屬性名爲value時,在對其賦值時可以不指定屬性的名稱,而直接寫上屬性值即可;
6)除了value以外的其他值都需要使用name=value這種賦值方式,即明確指定給誰賦值。
元註解
target說明了annotation所修飾的對象範圍:annotation可被用於packages、 types(類、接口、枚舉、annotation類型)、類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch 參數)。在annotation類型的聲明中使用了target可更加明晰其修飾的目標。
CONSTRUCTOR:構造器的聲明
FIELD:域聲明(包括enum實例)
LOCAL_VARIABLE:局部變量聲明
METHOD:方法聲明
PACKAGE:包聲明
PARAMETER:參數聲明
TYPE:類、接口(包括註解類型)或enum聲明
@Target(ElementType.CONSTRUCTOR)
public @interface ConstructorAnnotation {
String value();
}
@Target(ElementType.METHOD)
public @interface MethonAnnotation {
String value();
}
//@MethonAnnotation("test") 會報錯,該註解只能用於方法
public class TestAnnotation {
@ConstructorAnnotation("con")
public TestAnnotation(){
}
@MethonAnnotation("cmy")
public void test(){
System.out.println("--");
}
}
表示需要在什麼級別保存該註解信息。可選的RetentionPolicy參數包括:
@Retention(RetentionPolicy.SOURCE)
//註解僅存在於源碼中,在class字節碼文件中不包含
@Retention(RetentionPolicy.CLASS)
// 默認的保留策略,註解會在class字節碼文件中存在,但運行時無法獲得
@Retention(RetentionPolicy.RUNTIME)
// 註解會在class字節碼文件中存在,在運行時可以通過反射獲取到
指示註釋類型的註釋要保留多久。如果註釋類型聲明中不存在 Retention 註釋,則保留策略默認爲 RetentionPolicy.CLASS。
@Document
是一個標記註釋,表示註釋應該出現在類的javadoc中,因爲在默認情況下注釋時不包括在javadoc中的。所以如果花費了大量的時間定義一個註釋類型,並想描述註釋類型的作用,可以使用它。注意他與@Retention(RetentionPolicy.RUNTIME)配合使用,因爲只有將註釋保留在編譯後的類文件中由虛擬機加載,然後javadoc才能將其抽取出來添加至javadoc中。
@Inherited
將註釋同樣繼承至使用了該註釋類型的方法中(表達有點問題,就是如果一個方法使用了的註釋用了@inherited, 那麼其子類的該方法同樣繼承了該註釋
註解實例
public enum EnumModel {
RED;
}
public @interface AnnotationModel {
String[] value1() default "hello";
EnumModel value2();
}
public class TestAnnotation {
@AnnotationModel(value1 = {"world", "ABCD"}, value2 = EnumModel.RED)
public void method(){
System.out.println("usage of annotation");
}
public static void main(String[] args){
TestAnnotation usage = new TestAnnotation();
usage.method();
}
}
用註解處理權限過濾問題實例@Retention(RetentionPolicy.RUNTIME)//指定該註解是在運行期進行
@Target({ElementType.METHOD})//指定該註解要在方法上使用
public @interface PowerAuth {
<span style="white-space:pre"> </span>String value() default "";
}
根據方法名取得方法public class ParsePowerAuth {
public static String parseAuthentication(Class<?> clazz, String methodName,Class<?>... parameterTypes) throws NoSuchMethodException {
//根據方法名,取得方法,如果有則返回
Method method = clazz.getMethod(methodName, parameterTypes);
if (null != method) {
PowerAuth powerAuth = method.getAnnotation(PowerAuth.class);
if (null != powerAuth) {//該方法名上存在權限註解
return powerAuth.value();
}
}
return null;
}
}
Struts中攔截器配置與實現
自定義註解
@Retention(RetentionPolicy.RUNTIME)//指定該註解是在運行期進行
@Target({ElementType.METHOD})//指定該註解要在方法上使用
public @interface PowerAuth {
String value() default "";
}
根據方法名取得方法public class ParsePowerAuth {
public static String parseAuthentication(Class<?> clazz, String methodName,Class<?>... parameterTypes) throws NoSuchMethodException {
//根據方法名,取得方法,如果有則返回
Method method = clazz.getMethod(methodName, parameterTypes);
if (null != method) {
PowerAuth powerAuth = method.getAnnotation(PowerAuth.class);
if (null != powerAuth) {//該方法名上存在權限註解
return powerAuth.value();
}
}
return null;
}
}
Struts中攔截器配置與實現<interceptors>
<!--權限截器-->
<interceptor name="powerInterceptor" class="com.comm.interceptors.PowerInterceptor" />
</interceptors>
public class PowerInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
//取得方法名 判斷
ActionProxy proxy = actionInvocation.getProxy();
String methodName = proxy.getMethod();
Object action = proxy.getAction();
String powerAuthMethod =
ParsePowerAuth.parseAuthentication(action.getClass(),methodName, null);
}
}