java annotation學習

來源:互聯網
上載者:User
文章目錄
  • 對Assignment的retention進行修改,看編譯後Demo1的class檔案
@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)public @interface Override {} 

@interface:聲明這是一個註解

@Retention:聲明註解的策略,可參見RetentionPolicy。SOURCE

public enum RetentionPolicy {    ###儲存在原始碼中,會被編譯器拋棄    SOURCE,    ###編譯時間生效,會對代碼最後產生的class有一定影響,在運行時則不保留。此值為預設值    CLASS,    ###編譯時間生效,會對代碼最後產生的class有一定影響,在運行時保留,通常通過反射讀取。    RUNTIME}

@Target:聲明註解可以被放在什麼樣的元素上面,詳見ElementType

如果需要加入一個叫做age的變數,則代碼如下:

@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)public @interface Override {  int age();} 


寫個RetentionPolicy=CLASS的註解,通過javac來試一下註解
@Retention(RetentionPolicy.CLASS)@Target(ElementType.TYPE)public @interface Assignment {    String assignee();} 

註解process

@SupportedSourceVersion(SourceVersion.RELEASE_6)@SupportedAnnotationTypes("Assignment")public class AssignmentProcess extends AbstractProcessor {    private TypeElement assignmentElement;     public synchronized void init(ProcessingEnvironment processingEnv) {        super.init(processingEnv);        Elements elementUtils = processingEnv.getElementUtils();        assignmentElement = elementUtils.getTypeElement("Assignment");    }     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {        Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(assignmentElement);        for (Element element : elements) {            System.out.println(element);        }        return true;    }}  

@Assignment(assignee = "123")public class Demo1 {}

執行:

javac -processor AssignmentProcess Demo1.javaDemo1

按道理來說一切正常,不過悲劇的是把註解的retention改成source還是可以執行的,按照前面的理解,source的應該在編譯器中讀不到的

@Retention(RetentionPolicy.SOURCE)

對Assignment的retention進行修改,看編譯後Demo1的class檔案挺正常的樣子@Retention(RetentionPolicy.SOURCE)

public class Demo1 extends java.lang.Object  SourceFile: "Demo1.java"

@Retention(RetentionPolicy.CLASS)

public class Demo1 extends java.lang.Object  SourceFile: "Demo1.java"  RuntimeInvisibleAnnotations: length = 0xB   00 01 00 0B 00 01 00 0C 73 00 0D 

@Retention(RetentionPolicy.RUNTIME)

public class Demo1 extends java.lang.Object  SourceFile: "Demo1.java"  RuntimeVisibleAnnotations: length = 0xB   00 01 00 0B 00 01 00 0C 73 00 0D 

問題木找到,待研究。寫個RetentionPolicy=RUNTIME的註解試一下注釋

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface RoleCheck {    String role();} 
handle,內部通過反射取得注釋資訊,驗證是否可以調用該方法
public class AccessInvocationHandler implements InvocationHandler {    final Object accessObj;    public AccessInvocationHandler(Object accessObj){        this.accessObj = accessObj;    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        RoleCheck annotation = method.getAnnotation(RoleCheck.class); // 通過反射API擷取註解        if (annotation != null) {            String role = annotation.role();            if (!StringUtil.equals(role, CurrentRoleUtil.getCurrentRole())) {                throw new AccessControlException("The user is not allowed to invoke this method.");            }            return method.invoke(accessObj, args);        } else {            throw new AccessControlException("The user is not allowed to invoke this method.");        }    }}

類比cache等工具,擷取當前執行的role

public class CurrentRoleUtil {    private static int cur = 0;    public static String getCurrentRole(){        if(cur%2==0){            ++cur;            return "guanfei";        }        ++cur;        return "hake";    }}

通過代理調用

    public static void main(String[] args) {        HelloWorld hello = new HelloWorldImpl();        InvocationHandler handler = new AccessInvocationHandler(hello);        HelloWorld proxy = (HelloWorld)Proxy.newProxyInstance(hello.getClass().getClassLoader(), hello.getClass().getInterfaces(), handler);        proxy.sayHello();        proxy.sayHello();    }

執行結果

Hello World!Exception in thread "main" java.security.AccessControlException: The user is not allowed to invoke this method.at AccessInvocationHandler.invoke(AccessInvocationHandler.java:20)at $Proxy0.sayHello(Unknown Source)at Test.main(Test.java:11)
如果把注釋的@Retention(RetentionPolicy.CLASS)
Exception in thread "main" java.security.AccessControlException: The user is not allowed to invoke this method.at AccessInvocationHandler.invoke(AccessInvocationHandler.java:24)at $Proxy0.sayHello(Unknown Source)at Test.main(Test.java:9)

通過反射不能取到該注釋

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.