使用反射机制简单模拟IOC效果

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();
}

猜你喜欢

转载自www.cnblogs.com/czgxxwz/p/11601014.html