日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java反射--注解的定义与运用以及权限拦截

發布時間:2023/12/9 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java反射--注解的定义与运用以及权限拦截 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自定義注解類編寫的一些規則:

1. Annotation型定義為@interface, 所有的Annotation會自動繼承java.lang.Annotation這一接口,并且不能再去繼承別的類或是接口.

2. 參數成員只能用public或默認(default)這兩個訪問權修飾

3. 參數成員只能用基本類型byte,short,char,int,long,float,double,boolean八種基本數據類型和String、Enum、Class、annotations等數據類型,以及這一些類型的數組.

4. 要獲取類方法和字段的注解信息,必須通過Java的反射技術來獲取 Annotation對象,因為你除此之外沒有別的獲取注解對象的方法

5. 注解也可以沒有定義成員, 不過這樣注解就沒啥用了

自定義注解類時, 可以指定目標 (類、方法、字段, 構造函數等) , 注解的生命周期(運行時,class文件或者源碼中有效), 是否將注解包含在javadoc中及是否允許子類繼承父類中的注解, 具體如下:

1. @Target 表示該注解目標,可能的 ElemenetType 參數包括:

ElemenetType.CONSTRUCTOR 構造器聲明
ElemenetType.FIELD 域聲明(包括 enum 實例)?
ElemenetType.LOCAL_VARIABLE 局部變量聲明?
ElemenetType.METHOD 方法聲明?
ElemenetType.PACKAGE 包聲明?
ElemenetType.PARAMETER 參數聲明?
ElemenetType.TYPE 類,接口(包括注解類型)或enum聲明

2.?@Retention 表示該注解的生命周期,可選的 RetentionPolicy 參數包括

RetentionPolicy.SOURCE 注解將被編譯器丟棄?
RetentionPolicy.CLASS 注解在class文件中可用,但會被VM丟棄?
RetentionPolicy.RUNTIME VM將在運行期也保留注釋,因此可以通過反射機制讀取注解的信息

3. @Documented 指示將此注解包含在 javadoc 中

4.??@Inherited 指示允許子類繼承父類中的注解

類注解的定義:

[java]?view plaincopy
  • import?java.lang.annotation.ElementType;??
  • import?java.lang.annotation.Retention;??
  • import?java.lang.annotation.RetentionPolicy;??
  • import?java.lang.annotation.Target;??
  • ??
  • /**?
  • ?*?注解類?
  • ?*?@author?Owner?
  • ?*/??
  • @Retention(RetentionPolicy.RUNTIME)??
  • @Target(ElementType.TYPE)??
  • public?@interface?MyClassAnnotation?{??
  • ????String?uri();??
  • ????String?desc();??
  • }??
  • 構造方法注解定義:

    ?

    [java]?view plaincopy
  • import?java.lang.annotation.ElementType;??
  • import?java.lang.annotation.Retention;??
  • import?java.lang.annotation.RetentionPolicy;??
  • import?java.lang.annotation.Target;??
  • ??
  • /**?
  • ?*?構造方法注解?
  • ?*?@author?Owner?
  • ?*?
  • ?*/??
  • @Retention(RetentionPolicy.RUNTIME)?????
  • @Target(ElementType.CONSTRUCTOR)???
  • public?@interface?MyConstructorAnnotation?{??
  • ??
  • ????String?uri();??
  • ????String?desc();??
  • }??

  • 方法注解定義:

    ?

    ?

    [java]?view plaincopy
  • import?java.lang.annotation.ElementType;??
  • import?java.lang.annotation.Retention;??
  • import?java.lang.annotation.RetentionPolicy;??
  • import?java.lang.annotation.Target;??
  • ??
  • /**?
  • ?*?我的方法注解?
  • ?*?@author?Owner?
  • ?*?
  • ?*/??
  • @Retention(RetentionPolicy.RUNTIME)?????
  • @Target(ElementType.METHOD)??
  • public?@interface?MyMethodAnnotation?{??
  • ??
  • ????String?uri();??
  • ????String?desc();??
  • }??

  • 字段注解定義:

    ?

    ?

    [java]?view plaincopy
  • import?java.lang.annotation.ElementType;??
  • import?java.lang.annotation.Retention;??
  • import?java.lang.annotation.RetentionPolicy;??
  • import?java.lang.annotation.Target;??
  • ??
  • /**?
  • ?*?字段注解定義?
  • ?*?@author?Owner?
  • ?*?
  • ?*/??
  • @Retention(RetentionPolicy.RUNTIME)?????
  • @Target(ElementType.FIELD)???
  • public?@interface?MyFieldAnnotation?{??
  • ??
  • ????String?uri();??
  • ????String?desc();??
  • }??

  • 最后定義一個測試類

    ?

    ?

    [java]?view plaincopy
  • import?java.lang.reflect.Constructor;??
  • import?java.lang.reflect.Field;??
  • import?java.lang.reflect.Method;??
  • ??
  • @MyClassAnnotation(desc="The?class?name",?uri="com.annotation.MySample")??
  • public?class?MyTest?{??
  • ??
  • ????@MyFieldAnnotation(desc="The?class?field",?uri="com.annotation.MySample#id")??
  • ????private?int?id;??
  • ??????
  • ????@MyConstructorAnnotation(desc="The?class?constructor",?uri="com.annotation.MySample#MySample")??
  • ????public?MyTest(){}??
  • ??
  • ????public?int?getId()?{??
  • ????????return?id;??
  • ????}??
  • ??
  • ????@MyMethodAnnotation(desc="The?class?method",?uri="com.annotation.MySample#setId")??
  • ????public?void?setId(int?id)?{??
  • ????????this.id?=?id;??
  • ????}??
  • ??????
  • ??????
  • ????public?static?void?main(String[]?args)?throws?Exception?{??
  • ??????????
  • ????????Class<MyTest>?clazz?=?MyTest.class;??
  • ??????????
  • ????????//得到類注解??
  • ????????MyClassAnnotation?myClassAnnotation?=?clazz.getAnnotation(MyClassAnnotation.class);??
  • ??????????
  • ????????System.out.println(myClassAnnotation.desc()+"?"+myClassAnnotation.uri());??
  • ??????????
  • ????????//得到構造方法注解??
  • ????????Constructor<MyTest>?cons?=?clazz.getConstructor(new?Class[]{});??
  • ??????????
  • ????????MyConstructorAnnotation?myConstructorAnnotation?=?cons.getAnnotation(MyConstructorAnnotation.class);??
  • ??????????
  • ????????System.out.println(myConstructorAnnotation.desc()+"?"+myConstructorAnnotation.uri());??
  • ??????????
  • ????????//獲取方法注解??
  • ????????Method?method?=?clazz.getMethod("setId",?new?Class[]{int.class});??
  • ??????????
  • ????????MyMethodAnnotation?myMethodAnnotation?=?method.getAnnotation(MyMethodAnnotation.class);??
  • ??????????
  • ????????System.out.println(myMethodAnnotation.desc()+"?"+myMethodAnnotation.uri());??
  • ????????//獲取字段注解??
  • ????????Field?field?=?clazz.getDeclaredField("id");??
  • ??????????
  • ????????MyFieldAnnotation?myFieldAnnotation?=?field.getAnnotation(MyFieldAnnotation.class);??
  • ??????????
  • ????????System.out.println(myFieldAnnotation.desc()+"?"+myFieldAnnotation.uri()?);??
  • ????}??
  • ??????
  • }??

  • 輸出:

    ?

    The class name com.annotation.MySample
    The class constructor com.annotation.MySample#MySample
    The class method com.annotation.MySample#setId
    The class field com.annotation.MySample#id

    ?

    好了,上面是基本學習,我們在實際的項目中用在什么地方呢?我想我們都做過關于細粒度權限攔截的問題,在Struts2中可以根據登錄用戶所具有的的權限進行任一一個action方法的攔截,可以定義一個自定義方法注解,例如

    ?

    [java]?view plaincopy
  • @Retention(RetentionPolicy.RUNTIME)//代表Permission注解保留在的階段??
  • @Target(ElementType.METHOD)//標注在方法上面??
  • public?@interface?Permission?{??
  • ??
  • ????/**?模塊?*/??
  • ????String?module();??
  • ????/**?權限值?*/??
  • ????String?privilege();??
  • ??????
  • }??

  • 比如有一個部門action,Department.action,有一個方法public String departmentlistUI(){}

    ?

    ?

    可以這樣定義方法

    ?

    [java]?view plaincopy
  • @Permission(module="department",privilege="view")??
  • ????public?String?departmentlistUI(){??
  • }??

  • 然后自定定義一個權限攔截器PrivilegeInterceptor.java并在struts.xml中注冊,

    ?

    在實現interceptor接口后,實現方法public String intercept(ActionInvocation invocation) throws Exception {}

    ?

    在這里調用任一個action方法都會經過該攔截方法,通過invocation可以獲取當前調用的action的名字,以及調用的action的哪個方法,

    ?

    通過這段代碼可以獲取action名字和方法名

    ?

    [java]?view plaincopy
  • String??actionName=invocation.getProxy().getActionName();??
  • ????????String??methodName=invocation.getProxy().getMethod();??
  • ??????????
  • ????????System.out.println("攔截到:action的名字:"+actionName+"方法名:"+methodName);??

  • 然后通過反射技術,獲取該方法上的自定義權限注解,獲取當前登錄的用戶(從session中),遍歷當前用戶的所擁有的權限組,并且遍歷任一個權限組下的所有的權限,看是否包括該方法上注解所需的權限。這樣就可以完成細粒度的action方法權限攔截了。

    ?

    ?

    這只是個大體的思路

    下面看一下,攔截器的具體實現該功能的代碼

    ?

    [java]?view plaincopy
  • private?boolean?validate(ActionInvocation?invocation)?throws?SecurityException,?NoSuchMethodException?{??
  • ??????????
  • ????????String??methodName=invocation.getProxy().getMethod();??
  • ??????????
  • ????????Method?currentMethod?=?invocation.getAction().getClass().getMethod(methodName);??
  • ??????????
  • ????????if(currentMethod?!=?null?&&?currentMethod.isAnnotationPresent(Permission.class)){??
  • ????????????//得到方法上的注解??
  • ????????????Permission?permission?=?currentMethod.getAnnotation(Permission.class);??
  • ????????????//該方法上的所需要的權限??
  • ????????????SystemPrivilege?methodPrivilege?=?new?SystemPrivilege(new?SystemPrivilegePK(permission.module(),?permission.privilege()));??
  • ????????????//得到當前登錄的用戶??
  • ????????????Employee?e?=?(Employee)?ActionContext.getContext().getSession().get("loginUser");??
  • ????????????//遍歷當前用戶下的所有的權限組??
  • ????????????for(PrivilegeGroup?group?:?e.getGroups()){??
  • ????????????????//如果該權限組下包含,要訪問該方法所需要的權限,就放行??
  • ????????????????if(group.getPrivileges().contains(methodPrivilege)){??
  • ????????????????????return?true;??
  • ????????????????}??
  • ??????????????????
  • ????????????}??
  • ????????????//說明遍歷的該用戶所有的權限組,沒有發現該權限,說明沒有該權限??
  • ????????????return?false;??
  • ???????????????
  • ????????}??
  • ????????//沒有標注注解,表示誰都可以調用該方法??
  • ????????return?true;??
  • ????} ?
  • 轉載于:https://www.cnblogs.com/chengJAVA/p/3649909.html

    總結

    以上是生活随笔為你收集整理的java反射--注解的定义与运用以及权限拦截的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。