通过反射模拟ioc的bean添加和自动注入原理

通过反射模拟ioc的bean添加和自动注入原理


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/***
 *         模拟 ioc bean添加到map容器里面去
 *         同时也模拟了自动注入的
 */
public class Dom05 {
    Map<String, Object> map = new ConcurrentHashMap<>();

    @autowrite()
    private A a;


    public static void main(String[] args) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        final Dom05 dom05 = new Dom05();
        dom05.run();
        System.out.println(dom05.map);
        System.out.println(dom05.a.getName());
    }

    public void run() throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        //获取反射class
        final Class c = this.getClass();
        //获取当前calss下的全部方法
        final Method[] methods = c.getDeclaredMethods();
        //遍历方法
        for (Method method : methods) {
            //判断方法上面有ben没有
            if (method.getAnnotation(bean.class) != null) {
                final bean annotation = method.getAnnotation(bean.class);
                String name = null;
                //判断写添加bean的名称没有 如果写了就用用户的  如果没有写我们就通过反射获取 方法名添加到我们的map里面去
                if (!annotation.value().equals("")) {
                    name = annotation.value();
                } else {
                    //有的话我们把返回的对象添加到我们的map里面去
                    name = method.getName();
                }
                //把返回值添加到map里面
                map.put(name, method.invoke(c.newInstance()));
            }
        }
        //获取全部的变量
        final Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            //检查变上有不有我们的注解bean
            final autowrite annotation = field.getAnnotation(autowrite.class);
            if (annotation != null) {
                //我们先判断是否写bean的名字  如果写了我们直接去map里面去找 如果没有我就循环遍历去找
                if (!field.getAnnotation(autowrite.class).value().equals("")) {
                    field.setAccessible(true);
                    final String value = field.getAnnotation(autowrite.class).value();
                    field.set(this, map.get(value));
                    field.setAccessible(false);
                } else {
                    //有的话我们的循环检查看看有不有相应的对象类型如果有我们就赋值上去
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        //判断两个对象直接的类型是不是一致的 如果是一致那就证明是需要注入的对象
                        //System.out.println(entry.getValue().getClass().hashCode() + "        " + field.getType().hashCode());
                        if (entry.getValue().getClass().hashCode() == field.getType().hashCode()) {
                            field.set(this, entry.getValue());
                        }
                    }
                }
                field.setAccessible(false);
            }
        }
    }


    @bean
    public A a() {
        return new A("张三");
    }
}

class A {
    private String name;

    public A() {
    }

    public A(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


@Target(ElementType.METHOD)//内置注解表名用于方法上
@Retention(RetentionPolicy.RUNTIME) //表示在程序运行是也生效
@interface bean {
    String value() default ""; //default 设置默认值
}

@Target(ElementType.FIELD)//内置注解表名用于变量上
@Retention(RetentionPolicy.RUNTIME)//表示在程序运行是也生效
@interface autowrite {
    String value() default "";//default 设置默认值
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百度搜索爱敲代码的小庆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值