package anno; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; /** * @program: tx_annotation_demo * @description: 使用反射机制模拟实现IOC(控制反转) * @author: czg * @create: 2019-09-27 22:41 */ public class MySpring { public static void main(String[] args) { //题目:入参:一个包名.类名字符串 出参:一个对应的对象 对象中已存在数据(数据存在无参构造方法的注解中) Person p=(Person)Ioc("anno.Person"); System.out.println(p.toString()); } public static Object Ioc(String ClassName){ Object o =null; try { Class clazz=Class.forName(ClassName); //获得对象 o = clazz.newInstance(); //获得无参构造方法 Constructor constructor = clazz.getConstructor(); System.out.println("--------------开始获得注解中的数据---------------"); //获得无参构造方法上面的自定义注解 Annotation annotation = constructor.getAnnotation(MyAnnotaion.class); //获得注解类的Class Class aClass = annotation.getClass(); //获得注解类的方法 Method test = aClass.getMethod("test"); //获得其里面的数据 String[] data =(String[]) test.invoke(annotation); System.out.println("注解中的数据:"+Arrays.toString(data)); System.out.println("--------------构建组合对象set方法:set+大写首字母的对象属性名---------------"); //构建组合Object所代表对象中的setXxxx方法 //获得私有的属性 Field[] fields = clazz.getDeclaredFields(); //循环遍历属性名 for (int i=0;i<fields.length;i++){ Field field=fields[i]; String name = field.getName(); //组合属性对应的set方法 StringBuilder setMethod=new StringBuilder("set").append(name.substring(0,1).toUpperCase()) .append(name.substring(1)); //获得属性的类型 Class filedType=field.getType(); //获得并运行set方法 Method method = clazz.getMethod(setMethod.toString(),filedType); //需要将注解读取到的String字符串转出其他对应的类型 //Integer i=new Integer(""); //找到属性类型对应待String类型的构造函数 构造出新的对象 method.invoke(o,filedType.getConstructor(String.class).newInstance(data[i])); } } catch (Exception e) { e.printStackTrace(); } return o; } }
package anno; /** * @program: tx_annotation_demo * @description: 自定义注解测试使用 * @author: czg * @create: 2019-09-27 21:54 */ public class Person { //@MyAnnotaion(test = {"czg","18","男"}) private String name; private Integer age; private String sex; @MyAnnotaion(test = {"czg","18","男"}) public Person() { } public Person(String name, Integer age, String sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Person{" + "name=‘" + name + ‘\‘‘ + ", age=" + age + ", sex=‘" + sex + ‘\‘‘ + ‘}‘; } }
package anno; import java.lang.annotation.*; /** * @program: tx_annotation_demo * @description: * * 自定义注解(与接口用法有点类似) * 特点:注解中的方法必须有返回值,返回值必须是以下五种 * 基本数据类型 String类型 枚举类型enum 注解类型@ 数组类型(数组内部必须是前面四种) * * 注解要使用还必须使用Java提供好的元注解(元注解:元注解不是拿来使用的,是用来辅助说明自定义注解的) * * 常见元注解有:@Target 说明声明的注解是放在哪里使用的(注解一般放在 类的上面,属性上面,方法的上面,构造方法的上面,参数前面) * ElementType.FIELD(属性上面),ElementType.METHOD(方法上面),ElementType.CONSTRUCTOR(构造方法上面) 注解可以在 * @Retention 描述当前的这个注解存在什么作用域中 SOURCE:源码文件 CLASS:字节码文件 RUNTIME:内存运行 * @Inherited 描述当前这个注解是否会被子类对象继承 * @Documented 描述当前这个注解是否能生成文档 * @author: czg * @create: 2019-09-27 20:50 */ @Target({ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotaion { public static final String NAME_TEST="XXXX";//一般注解里面比较少用这种 //public abstract 一般是默认的 public abstract String[] test(); }
原文地址:https://www.cnblogs.com/czgxxwz/p/11601014.html
时间: 2024-10-29 18:51:33