原文地址:http://stackoverflow.com/questions/18189980/how-do-annotations-work-internally

The first main distinction between kinds of annotation is whether they're used at compile time and then discarded (like @Override) or placed in the compiled class file and available at runtime (like Spring's @Component). This is determined by the @Retention policy of the annotation. If you're writing your own annotation, you'd need to decide whether the annotation is helpful at runtime (for autoconfiguration, perhaps) or only at compile time (for checking or code generation).

When compiling code with annotations, the compiler sees the annotation just like it sees other modifiers on source elements, like access modifiers (public/private) or final. When it encounters an annotation, it runs an annotation processor, which is like a plug-in class that says it's interested a specific annotation. The annotation processor generally uses the Reflection API to inspect the elements being compiled and may simply run checks on them, modify them, or generate new code to be compiled. @Override is an example of the first; it uses the Reflection API to make sure it can find a match for the method signature in one of the superclasses and uses the Messagerto cause a compile error if it can't.

There are a number of tutorials available on writing annotation processors; here's a useful one. Look through the methods on the Processor interface for how the compiler invokes an annotation processor; the main operation takes place in the process method, which gets called every time the compiler sees an element that has a matching annotation.

附录:

Writing an Annotation Based Processor in Java

原文地址http://travisdazell.blogspot.hk/2012/10/writing-annotation-based-processor-in.html

The code for this tutorial is on GitHub: https://github.com/travisdazell/Annotation-Based-Processor

Annotations have been around since Java 5. They provide a way to mark (i.e. annotate) Java code in a clean and concise manner. With Java 6 and 7, we can do even more with annotations. The most exciting of which, in my opinion, is the ability to write our own annotations and even process our own annotations to detect code issues or even generate source code at compile time.

In this example, we'll create an annotation named @Metrics. We'll be able to mark Java classes with @Metrics and at compile-time, generate a report of all methods defined in the class. To create your own annotation and its corresponding processor, follow these steps.

  1. Define the annotation. This is done by defining the annotation with @interface.

public @interface Metrics {
     }
  
     2. We can now annotate any class in our project with our new annotation.

import net.travisdazell.annotations.Metrics;

@Metrics
     public class CustomerDaoImpl implements CustomerDao {
        public Customer getCustomer(int customerId) {
           // return Customer record
        }
     }

3. The next step is to write a processor that, at compile time, will report all of the methods defined in CustomerDaoImpl.java. Here's our processor in its entirety.

package net.travisdazell.annotations.processors;

import java.lang.reflect.Method;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;

import net.travisdazell.annotations.Metrics;

@SupportedAnnotationTypes("net.travisdazell.annotations.Metrics")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class MetricsProcessor extends AbstractProcessor {
    
    @Override
    public boolean process(Set<? extends TypeElement> arg0,
            RoundEnvironment roundEnv) {

StringBuilder message = new StringBuilder();

for (Element elem : roundEnv.getElementsAnnotatedWith(Metrics.class)) {
            Metrics implementation = elem.getAnnotation(Metrics.class);

message.append("Methods found in " + elem.getSimpleName().toString() + ":\n");

for (Method method : implementation.getClass().getMethods()) {
                message.append(method.getName() + "\n");
            }

processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message.toString());
        }

return false; // allow others to process this annotation type
    }
}

4. Next, we need to package our annotation processor and annotation in a JAR file. We must also include a META-INF\services directory in our JAR file. Within the services directory, include a file named javax.annotation.processing.Processor. In that file, type the fully qualified name of the annotation processor.

Here's what my JAR file looks like when exploded in Eclipse.

5. Next, to test our annotation processor, create a class and annotate it with @Metrics.

package net.travisdazell.projects.testproject.dao.impl;

import net.travisdazell.annotations.Metrics;

@Metrics
public class CustomerDaoImpl {
}

6.When we compile this class, we'll get a message displaying the list of methods in the class. As expected, we see what's been inherited from java.lang.Object.

How do annotations work internally--转的更多相关文章

  1. How those spring enable annotations work--转

    原文地址:http://blog.fawnanddoug.com/2012/08/how-those-spring-enable-annotations-work.html Spring's Java ...

  2. Android注解使用之使用Support Annotations注解优化代码

    前言: 前面学习总结了Java注解的使用,博客地址详见Java学习之注解Annotation实现原理,从本质上了解到什么注解,以及注解怎么使用?不要看见使用注解就想到反射会影响性能之类,今天我们就来学 ...

  3. Scala Macros - scalamela 1.x,inline-meta annotations

    在上期讨论中我们介绍了Scala Macros,它可以说是工具库编程人员不可或缺的编程手段,可以实现编译器在编译源代码时对源代码进行的修改.扩展和替换,如此可以对用户屏蔽工具库复杂的内部细节,使他们可 ...

  4. [Android]使用自定义JUnit Rules、annotations和Resources进行单元测试(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5795091.html 使用自定义JUnit Rules.ann ...

  5. EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射

    I.EF里的默认映射 上篇文章演示的通过定义实体类就可以自动生成数据库,并且EF自动设置了数据库的主键.外键以及表名和字段的类型等,这就是EF里的默认映射.具体分为: 数据库映射:Code First ...

  6. Multiple annotations found at this line

    Multiple annotations found at this line 在使用MyEclipse的时候,通过MVN导入项目时候,webapp下面的JSP页面报了如下的错误: 这种情况通常的原因 ...

  7. How Do Annotations Work in Java?--转

    原文地址:https://dzone.com/articles/how-annotations-work-java Annotations have been a very important par ...

  8. 使用Android Annotations开发

    使用Android Annotations框架gradle配置1.修改Module下的build.gradle apply plugin: 'com.android.application' appl ...

  9. Entity Framework Code First (三)Data Annotations

    Entity Framework Code First 利用一种被称为约定(Conventions)优于配置(Configuration)的编程模式允许你使用自己的 domain classes 来表 ...

随机推荐

  1. Hibernate快照

    l当session加载了某个对象后,会为该对象的值类型的属性复制一份快照.当刷出缓存时,通过比较对象的当前属性和快照,来判断对象的哪些属性发生了变化. 代码如下: /** * 修改学生信息 */ @T ...

  2. 设置UIButton或者UILabel显示文字的行数

    需要在UIButton的titleLabel或者UILabel的text 字符串里面添加换行符号 “\n”,并且设置 UILabel的numberOfLines属性 栗子:行数要和“\n”的个数对应, ...

  3. 5.webService拦截器

    CXF为什么要设计拦截器? 为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器. 拦截器分类 1.按所处的位置分:服务器端拦截器,客户端拦截器 2.按消息的方向分:入 ...

  4. redmine中创建项目与跟踪标签(原创)

    今天来说下本公司所用到的项目管理工具redmine,总体来说还是比较好用的.redmine中可以记录项目的整个过程,可创建跟踪标签(里程碑.需求用例.功能.任务.缺陷)来进行对项目的管控.跟踪标签根据 ...

  5. 问题:无法获得锁 /var/lib/dpkg/lock - open (11: 资源临时不可用)

    无法获得锁 /var/lib/dpkg/lock - open (11: 资源临时不可用) 问题: 运行程序更新时出现报错: 无法获得锁 /var/lib/dpkg/lock - open (11: ...

  6. Deploying JRE (Native Plug-in) for Windows Clients in Oracle E-Business Suite Release 12 (文档 ID 393931.1)

    In This Document Section 1: Overview Section 2: Pre-Upgrade Steps Section 3: Upgrade and Configurati ...

  7. await之后的线程问题

    之前看了园子里的一篇文章「async & await的前世今生」,收益颇多.而其中有句话被博主特意用红色标注,所以留意多看了几眼,「await 之后不会开启新的线程(await 从来不会开启新 ...

  8. node(邮件发送特性)

    1.安装 npm install nodemailer https://github.com/andris9/Nodemailer 2.配置发邮件的账户开启SMTP功能: 3.程序样例如下: var ...

  9. Android多线程分析之四:MessageQueue的实现

    Android多线程分析之四:MessageQueue的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前面两篇文章<Androi ...

  10. [ZigBee] 13、ZigBee基础阶段性回顾与加深理解——用定时器1产生PWM来控制LED亮度(七色灯)

    引言:PWM对于很多软件工程师可能又熟悉又陌生,以PWM调节LED亮度为例,其本质是在每个周期都偷工减料一些,整体表现出LED欠压亮度不同的效果.像大家看到的七色彩灯其原理也类似,只是用3路PWM分别 ...