java中的meta-annotation

练习,根据对类的声明初始化对象,并根据输入初始化对应的属性

Info.java

1 import java.lang.annotation.*;
2 
3 @Target(ElementType.TYPE)
4 @Retention(RetentionPolicy.RUNTIME)
5 @Documented
6 public @interface Info {
7     String[] fields();
8 }

InitUtil.java

 1 import java.lang.reflect.*;
 2 
 3 public class InitUtil {
 4     
 5     public static <T> T initObj(Class<T> c, final Object... values) {
 6         String[] fl= c.getAnnotation(Info.class).fields();//use meta-annotation
 7         Field[] fs = c.getDeclaredFields();
 8         T obj = null;
 9         try {
10             obj = c.newInstance();
11             int index = 0;
12             for (Field f : fs) {
13                 f.setAccessible(true);
14                 if(f.getName().equals(fl[index])) {
15                     f.set(obj, values[index]);
16                     index++;
17                 }
18             }
19         } catch (Exception e) {
20             return null;
21         } 
22         return obj;
23     }
24 
25 }

Person.java

 1 @Info(fields = {"name","age","gender"})
 2 public class Person {
 3 
 4     private String name;
 5     private int age;
 6     private boolean gender;
 7     public String getName() {
 8         return name;
 9     }
10     public void setName(String name) {
11         this.name = name;
12     }
13     public int getAge() {
14         return age;
15     }
16     public void setAge(int age) {
17         this.age = age;
18     }
19     public boolean getGender() {
20         return gender;
21     }
22     public void setGender(boolean gender) {
23         this.gender = gender;
24     }
25 }

Test:

1     public static void main(String[] args) {
2         Person p;
3         p=InitUtil.initObj(Person.class, "qwerty", 12, true);//call custom init
4         System.out.println(p.getName()+p.getAge()+p.getGender());
5     }

练习,根据对域的声明初始化对应域

InitAuto.java

1 import java.lang.annotation.*;
2 
3 @Target(ElementType.FIELD)
4 @Retention(RetentionPolicy.RUNTIME)
5 @Documented
6 public @interface InitAuto {
7 
8 }

InitUtil.java

 1 import java.lang.reflect.*;
 2 
 3 public class InitUtil {
 4     
 5     public static void initObj(Object o) {
 6         Class<?> c = o.getClass();
 7         Field[] fs = c.getDeclaredFields();
 8         for(Field f : fs) {
 9             if(f.isAnnotationPresent(InitAuto.class)) {//get field annotated by InitAuto
10                 f.setAccessible(true);
11                 try {
12                     Class<?> cc = f.getType();
13                     if(cc.getName().endsWith("Person")) {
14                         Object obj = cc.newInstance();//init Person
15                         Field ff = cc.getDeclaredField("name");
16                         ff.setAccessible(true);
17                         ff.set(obj, "test name");//set custom properties
18                         f.set(o, obj);
19                     } else {
20                         //other type of field
21                     }
22                 } catch (Exception e) {
23                     e.printStackTrace();
24                 }
25             } else {
26                 //other type of annotation
27             }
28         }
29     }
30 }

Person.java

same as above

Group.java

 1 public class Group {
 2     @InitAuto
 3     private Person p1;
 4     @InitAuto
 5     private Object o1;
 6     
 7     public Person getP1() {
 8         return p1;
 9     }
10     public Object getO1() {
11         return o1;
12     }
13 }

Test:

1     public static void main(String[] args) {
2         Group ps = new Group();
3         InitUtil.initObj(ps);//真正实现的时候使用decorator模式
4         System.out.println(ps.getP1().getName()+ps.getO1());
5     }

 练习,根据注释调用方法

DataSource.java

1 import java.lang.annotation.*;
2 
3 @Target(ElementType.METHOD)
4 @Retention(RetentionPolicy.RUNTIME)
5 @Documented
6 public @interface DataSource {
7     String source();
8 }

DataPattern.java

1 import java.lang.annotation.*;
2 
3 @Target(ElementType.PARAMETER)
4 @Retention(RetentionPolicy.RUNTIME)
5 @Documented
6 public @interface DataPattern {
7     String value() default "";//you can use DataPattern("...") if you declare value() property
8 }

 InitUtil.java

 1 import java.lang.reflect.*;
 2 
 3 public class InitUtil {
 4     
 5     public static void initMtd(Object o) {
 6         Class<?> c = o.getClass();
 7         Method[] ms = c.getDeclaredMethods();
 8         for(Method m : ms) {
 9             if(m.isAnnotationPresent(DataSource.class)) {
10                 m.setAccessible(true);
11                 
12                 //the first parameter is annotated to set the pattern
13                 DataPattern p = m.getParameters()[0].getAnnotation(DataPattern.class);
14                 String dataPattern = p.value();
15                 //the method is annotated to set the data source
16                 String dataSource = m.getAnnotation(DataSource.class).source();
17                 
18                 /*do something to listen to the data source*/
19                 
20                 try {
21                     m.invoke(o, dataSource+"->"+dataPattern, 
22                             new java.util.concurrent.ConcurrentHashMap<String,String>());
23                 } catch (Exception e) {
24                     e.printStackTrace();
25                 } 
26             }
27         }
28     }
29 }

 Action.java

1 public class Action {
2     @DataSource(source = "page")
3     public String excute(@DataPattern("data") String d , java.util.Map<String,String> m) {
4         System.out.println(d);
5         m.put("data", d+" in map");
6         System.out.println(m.get("data"));
7         return "";
8     }
9 }

Test

1     public static void main(String[] args) {    
2         Action a = new Action();
3         InitUtil.initMtd(a);
4     }

 

posted @ 2016-08-15 15:57  Kharenah  阅读(451)  评论(0编辑  收藏  举报