手写Spring的ioc容器

 #使用jdk提供的包完成的一个简易版本的Spring容器

 beanFactory的实现类:

public class applicationContext {
     //用来扫描的启动类(扫描出启动类的信息)
    Class aClass;
    //单例池(单例的对象需要存放的地方)
    ConcurrentHashMap<String,Object> singleton = new ConcurrentHashMap<>();
    //存放扫描进来的类的BeanDefiniton信息
    ConcurrentHashMap<String,BeanDefinition> beanDefinitionConcurrentHashMap = new ConcurrentHashMap<>();

    //构造方法
    //扫描启动类
    //把扫描到的类存放到ioc容器中
    //把单例的Bean存放到单例池中
    //原型的Bean保存它的BeanDefiniton信息
    public applicationContext(Class aClass) {
        //扫描完成,并且设置了BeanDefinition的值
        Scan(aClass);
        //把单例的bean放入单例池中
        //把遍历扫描的类那些事单例的
        Iterator<Map.Entry<String, BeanDefinition>> iterator = beanDefinitionConcurrentHashMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, BeanDefinition> next = iterator.next();
            if(next.getValue().getScope()=="singleton"){
                //创建对象放入
                Object singletonBean = creatBean(next.getValue());
                singleton.put(next.getKey(),singletonBean);
            }else {
                //如果不是单例的bean创建好就可以了
                Object o = creatBean(next.getValue());
            }
        }

    }

    //创建Bean对象
    public Object creatBean( String beanName){
        BeanDefinition beanDefinition = beanDefinitionConcurrentHashMap.get(beanName);
        try {
            Object bean = beanDefinition.getaClass().newInstance();
            return bean;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return null;
    }
    //重载creatBean()
    public Object creatBean(BeanDefinition beanDefinition)  {
        //根据BeanDefinition进行创建对象
        Class aClass = beanDefinition.getaClass();
        Object object =null;
        try {
             object = aClass.newInstance();
            System.out.println("===========object"+object);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        //@Autowired自动注入的实现
        //获取属性上的注解
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field: declaredFields)
            if (field.isAnnotationPresent(Autowired.class)) {
                //获取对象
                Object bean = getBean(field.getName());
                System.out.println("======bean========" + bean);
                //set给那个对象赋值
                try {
                    field.setAccessible(true);
                    System.out.println("=========");
                    System.out.println(field+"11111111111");
                    field.set(object, bean);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        return object;
    }


        private void Scan(Class aClass) {
        this.aClass = aClass;
        //解析配置类来创建Bean对象
        ComponentScan ComponentScan = (annotation.ComponentScan) aClass.getDeclaredAnnotation(ComponentScan.class);
        //读取注解中的信息
        String path = ComponentScan.value();//path  service
        //类加载器
        ClassLoader classLoader = ComponentScan.getClass().getClassLoader();
        String resource = classLoader.getResource(path).getPath();  //resource    /D:/IdeaVincent/untitled4/out/production/Spring/service
        File file = new File(resource);
        if(file.isDirectory()){
            File[] files = file.listFiles();
            for (File f :files) {
                String name = f.getName();
                String relPath = path+"."+name.substring(0, name.indexOf(".class"));

                try {
                    Class<?> aClass1 = classLoader.loadClass(relPath);
                    //通过类的信息来获取注解信息
                    Component annotation = aClass1.getAnnotation(Component.class);
                    String beanName = annotation.value();
                    //把注解的信息存放在BeanDefinition中
                    BeanDefinition beanDefinition = new BeanDefinition();
                    beanDefinition.setaClass(aClass1);
                    //如果有注解
                    if(aClass1.isAnnotationPresent(Scope.class)){
                        //获取Scope的值
                        String value = aClass1.getAnnotation(Scope.class).value();
                        beanDefinition.setScope(value);

                    }else {
                        //如果没有值的话设置成为单例模式
                        beanDefinition.setScope("singleton");
                    }
                    beanDefinitionConcurrentHashMap.put(beanName,beanDefinition);
                    //存放到BeanDefinitionMap中

                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public Object getBean(String beanName){
        //根据BeanDefinition来创建对象
        BeanDefinition beanDefinition = beanDefinitionConcurrentHashMap.get(beanName);
        //是原型则创建新的对象返回
        if("prototype".equals(beanDefinition.getScope())){
            Object prototypeBean = creatBean(beanName);
            return prototypeBean;
        }else if("singleton".equals(beanDefinition.getScope())){
            //单例则返回单例bean
            Object  singletonBean= singleton.get(beanName);
            return singletonBean;
        }else {

            throw new RuntimeException();


        }

    }
}

BeanDefiniton:

public class BeanDefinition {
    //存放扫描到类的class对象
    Class aClass;
    //存放bean的作用域
    String scope;

    public Class getaClass() {
        return aClass;
    }

    public void setaClass(Class aClass) {
        this.aClass = aClass;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }
}

@ComponScan注解:

//注解存活时间
@Retention(RetentionPolicy.RUNTIME)
//注解可以使用的位置
@Target(ElementType.TYPE)
public @interface ComponentScan {
     //需要扫描的路径
    String value();
}

@Component注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
    //注入的注解的名字
    String value();
}

@Autowired:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.FIELD})
public @interface Autowired {
}

@Scope:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
    //默认是单例的,如果有值的话是原型
    String value()default "";
}

启动的测试类:

@ComponentScan("service")
public class Text {
    public static void main(String[] args) {
        //完全利用jdk创建spring容器
        //
        applicationContext applicationContext = new applicationContext(Text.class);
        User user = (User)applicationContext.getBean("user");
        Object user1 = applicationContext.getBean("user");
        Object user2 = applicationContext.getBean("user");
        order order1 = (order)applicationContext.getBean("order");
        Object order2 = applicationContext.getBean("order");
        Object order3 = applicationContext.getBean("order");
       /* System.out.println(user);
        System.out.println(user1);
        System.out.println(user2);
        System.out.println(order1);
        System.out.println(order2);
        System.out.println(order3);*/
       //user.text();
        order1.text();
       // applicationContext.getBean("01");
    }
}

文字描述:

1.在配置类中添加@ComponentScan注解

2.使用ApplicationContext解析配置类

3.得到@ComponentScan注解下的路径

4.使用类加载器得到path路径

5.把path路径封装成File对象

6.使用File对象得到类的信息

7.使用类加载器加载类的信息

8.解析类的信息

9.判断是否有@Component注解,和是否有@Scope注解

10.把类的信息解析成BeanDefinition对象

11.通过BeanDefinition创建对象

12.把单例bean存放进单例池中

13.判断@Autowired注解,进行依赖注入

14.原型bean在getbean的时候再通过BeanDefinition创建

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值