模拟Spring中的依赖注入原理

模拟Spring中的依赖注入原理代码:(通过反射及内省机制将实体类对象成员上的注解中的信息注入该实体类的对象中) 注意条件是自定义注解中的属性名与实体类中的属性名相同

需求1:假设实体类CarManager中show方法的参数的类型(即实体类的类型)知道,也知道CarManager类中有一个名为show的方法;自定义注解的类型知道,但不知道自定义注解中的属性名以及给这些属性赋的值,只知道自定义注解中的属性名与实体类中的属性名一致
代码:

/*
 * lenovo 2019/8/16 14:59
 * 佛祖保佑,永无BUG!
 * 属性根据类中方法定义:getXxx (带返回值)、setXxx(有参数)、isXxx(返回类型是boolean类型)
 */
public class Car {
    private String brand;
    private String color;
    private double price;

    public Car(String brand, String color, double price) {
        this.brand = brand;
        this.color = color;
        this.price = price;
    }
    public Car() {

    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }

    public void run(){
        System.out.println(brand+color+"价格"+price+"的汽车在奔跑");
    }
}
/*
 * lenovo 2019/8/16 15:02
 * 佛祖保佑,永无BUG!
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface CarAnnotation {
    //假设注解中属性名与Car实体类中属性名相同
    String[] brand()default "";
    String color();
    double[] price();
}
/*
 * lenovo 2019/8/16 15:02
 * 佛祖保佑,永无BUG!
 */
public class CarManager {
    @CarAnnotation(brand = "法拉利",color = "绿色",price = 1000000)
    public void show(Car car){
        System.out.println("展示汽车");
        car.run();
    }
}
/*
 * lenovo 2019/8/16 15:04
 * 佛祖保佑,永无BUG!
 */
public class Demo {
    public static void main(String[] args) throws Exception{
        CarManager carManager=new CarManager();
        Class<?> clazz=CarManager.class;
        Method show = clazz.getMethod("show",Car.class);
        Class<?> clazz2=Car.class;

        //Java ,内省机制,是一种使用反射获取或设置对象属性的一种方式
        // Introspector  内省类
        // BeanInfo 类的信息类
        // PropertyDescriptor 属性描述符类

        //1使用内省类Introspector获取类信息对象
        BeanInfo beanInfo = Introspector.getBeanInfo(clazz2);
        //2调用类信息的getPropertyDescriptors()获取属性描述符
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

        //获取注解
        CarAnnotation annotation = show.getAnnotation(CarAnnotation.class);
        //获取注解的类对象
        Class<?> clazz3=CarAnnotation.class;

        //创建一个Car对象并给其属性赋值
        Object o = clazz2.newInstance();
        for (PropertyDescriptor descriptor : propertyDescriptors) {
            //System.out.println(pd.getName());
            //System.out.println(pd.getName());
            String name=descriptor.getName();//获取类中的属性名
            try {
                Method method = clazz3.getMethod(name);//获取注解中的方法(属性)
                if(method!=null){
                    Object value = method.invoke(annotation);//调用注解中的方法,返回注解中属性对应的值
                    Method writeMethod = descriptor.getWriteMethod();//获取Car类中该属性对应的set方法
                    writeMethod.invoke(o,value);//相当于调用该属性的set方法给该属性赋值value
                }
            } catch (Exception e) {
                continue;// 因为Car类继承了Object类中的getClass方法,
                         // 所以属性中会有一个名为class属性,但是
                         // 这个属性在自定义的注解中是没有的,因此会
                         // 抛异常,通过catch语句屏蔽这个异常,通过continue继续遍历
            }
        }
        System.out.println(o.toString());//自始至终并没有通过Car类中的set方法就可以给Car类中的属性赋上值
    }
}

需求2:假设实体类CarManager中的成员变量car的类型不知道,但知道有一个名为car的成员变量;自定义注解的类型知道,但不知道自定义注解中的属性名以及给这些属性赋的值,只知道自定义注解中的属性名与实体类中的属性名一致
代码:

/*
 * lenovo 2019/8/16 14:59
 * 佛祖保佑,永无BUG!
 * 属性根据类中方法定义:getXxx (带返回值)、setXxx(有参数)、isXxx(返回类型是boolean类型)
 */
public class Car{
    private String brand;
    private String color;
    private double price;

    public Car(String brand, String color, double price) {
        this.brand = brand;
        this.color = color;
        this.price = price;
    }
    public Car() {

    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }

    public void run(){
        System.out.println(brand+color+"价格"+price+"的汽车在奔跑");
    }
}
/*
 * lenovo 2019/8/16 15:02
 * 佛祖保佑,永无BUG!
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface CarAnnotation {
    //假设注解中属性名与Car实体类中属性名相同
    String brand();
    String color();
    double price();

}
/*
 * lenovo 2019/8/16 15:02
 * 佛祖保佑,永无BUG!
 */
public class CarManager {
    @CarAnnotation(brand = "法拉利",color = "绿色",price = 1000000)
    private Car car;
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
}
/*
 * lenovo 2019/8/16 15:04
 * 佛祖保佑,永无BUG!
 */
public class Demo {
    public static void main(String[] args) throws Exception{
        CarManager carManager=new CarManager();
        Field car = CarManager.class.getDeclaredField("car");
        //获取car的类型
        Class<?> carClass = car.getType();

        //Java ,内省机制,是一种使用反射获取或设置对象属性的一种方式
        // Introspector  内省类
        // BeanInfo 类的信息
        // PropertyDescriptor 属性描述符

        //1使用内省类Introspector获取类信息对象
        BeanInfo beanInfo = Introspector.getBeanInfo(carClass);
        //2调用类信息的getPropertyDescriptors()获取属性描述符
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

        //获取字段(car)上的注解
        CarAnnotation annotation = car.getAnnotation(CarAnnotation.class);
        //获取注解的类对象
        Class<?> clazz3=CarAnnotation.class;

        //创建一个Car对象并给其属性赋值
        Object o = carClass.newInstance();
        for (PropertyDescriptor descriptor : propertyDescriptors) {
            //System.out.println(pd.getName());
            //System.out.println(pd.getName());
            String name=descriptor.getName();//获取类中的属性名
            try {
                Method method = clazz3.getMethod(name);//获取注解中的方法(属性)
                if(method!=null){
                    Object value = method.invoke(annotation);//调用注解中的方法,返回注解中属性对应的值
                    Method writeMethod = descriptor.getWriteMethod();//获取Car类中该属性对应的set方法
                    writeMethod.invoke(o,value);//相当于调用该属性的set方法给该属性赋值value
                }
            } catch (Exception e) {
                continue;// 因为Car类继承了Object类中的getClass方法,
                         // 所以属性中会有一个名为class属性,但是
                         // 这个属性在自定义的注解中是没有的,因此会
                         // 抛异常,通过catch语句屏蔽这个异常,通过continue继续遍历
            }
        }
        System.out.println(o.toString());//自始至终并没有通过Car类中的set方法就可以给Car类中的属性赋上值
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值