Annotation
I want to learn is by Spring @bean,Want to know how it work.
But toke a long time in busy.
Until today,There is my notes about Annotation.

First you need create class and replace class to @interface
All Annotation implicit inheritance from java.lang.annotation.Annotation
And all your annotation can use meta-annotation
There have four meta-annotation

  1. @Target mark where your annotation can use, without @Target, your annotation can use everywhere

    • ElementType.ANNOTATION_TYPE —mark annotation type
    • ElementType.PACKAGE —above package
    • ElementType.TYPE —above class and interface
    • ElementType.METHOD — above method
    • ElementType.CONSTRUCT —above construct
    • ElementType.FIELD —member domain
    • ElementType.PARAMETER —above method or whit parameter
    • ElementType.LOCAL_VARIABLE —local variable
    • TElementType.YPE_PARAMETER —type parameter
    • ElementType.TYPE_USE —type use
  2. @Retention be used to mark a annotation keep time, without @Retention, default is RetentionPolicy.CLASS

    • RetentionPolicy.SOURCE —not include class file
    • RetentionPolicy.CLASS —include class file but JVM not load
    • RetentionPolicy.RUNTIME —include class file and JVM will load, you can get them by reflex
  3. @Document create note for archive like JavaDoc

  4. @Inherited only be used to class, if a has extend annotation, then it all child class auto have the same annotation


ok, there is a demo.
first need create a annotation by yourself.
The meta-annotation above public @interface Foo {}
you can chose which is necessary

1
2
3
4
5
6
7
8
import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Foo {
String name() default "";
int count() default 0;
}

this annotation Foo has two value, name and count.
that value type can be

  • Base-Type (int, short, long, byte, char, double, float or boolean)
  • String
  • Class (such as Class<? extend Bar>)
  • Enum
  • Annotation
  • Array (create from above type)

so this Foo can be use now

1
2
3
4
5
6
7
8
9
10
@Foo(value = "这是类注解",count = 1)
public class Bar {
@Foo(value = "这是属性注解",count = 2)
private String name;

@Foo(value = "这是方法注解",count = 3)
private void test(){
System.out.println("");
}
}

as you can see @Foo can use above class, property and method.
because of when i create it whit @Target, so Foo can use whit them.

but only annotation can not do anything.
must be have a “process” to handle.

so there is my “process”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class FooProcess{

public static void analyze(Class clazz) throws NoSuchMethodException {
//get all class annotation information
Annotation[] classAnnotation = clazz.getAnnotations();
for(Annotation annotation : classAnnotation){
Class annotationType = annotation.annotationType();
boolean equals = annotationType.equals(Foo.class);
if (equals){
System.out.println("Bar class has Foo annotation");
System.out.println("info: " + ((Foo)annotation).value() + "," + ((Foo)annotation).count());
}
//get all annotation type
System.out.println("Bar class annotation is:" + annotationType);
}

System.out.println();

//get all property annotation information
Field[] fields = clazz.getDeclaredFields();
for (Field field :fields){
String filedName = field.getName();
Annotation[] allAnnotations = field.getAnnotations();
for(Annotation an : allAnnotations){
Class annotationType = an.annotationType();
System.out.println("FiledName["+filedName+"]property annotation: " + annotationType);
}
if (field.isAnnotationPresent(Foo.class)){
Foo foo = field.getAnnotation(Foo.class);
System.out.println("FiledName["+filedName+"]property info: "+ foo.value() + "," + foo.count());
}
}

System.out.println();

//get all method annotation information
Method method = clazz.getDeclaredMethod("test", null);//get private and public method
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations){
Class annotationType = annotation.annotationType();
System.out.println("test method has annotation type: " + annotationType);
if (annotationType.equals(Foo.class)) {
Foo mode = (Foo) annotation;
System.out.println("info: " + mode.value() + "," + mode.count());
}
}
}
}

and run with :

1
2
3
4
5
6
7
public static void main(String args[]){
try {
FooProcess.analyze(Bar.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}

see console

1
2
3
4
5
6
7
8
9
Bar class has Foo annotation
info: this is class annotation,1
Bar class annotation is:interface com.eddie.annotation.Foo

FiledName[name]property annotation: interface com.eddie.annotation.Foo
FiledName[name]property info: this is property annotation,2

test method has annotation type: interface com.eddie.annotation.Foo
info: this is method annotation,3

you can do everything in process, but first you need use if to know target location
real have your annotation, if not, you will get a NullPointerException or maybe
ClassCastException. we don’t want to see them, right?
then you can get value and do what you want.