手写Spring-基于xml总结

代码参考牛客网大佬,何人听我楚狂声:https://github.com/CN-GuoZiyang/My-Spring-IOC/tree/82967670e52fe66ad55a6b2a539dbb4d48b46805

代码目录分5大部分:

  • context
  • factory
  • entity
  • io
  • reader

已实现功能:基本属性注入,引用依赖注入,singleton和prototype模式注入。

第一阶段:要实现基于XML的配置文件注入,第一步想到的就是怎么把xml文件里面的内容给拿出来,这部分涉及到三个目录的内容,每个目录的功能如下。

1.entity目录

        此目录下定义了4种实体类,也就是4种数据结构,核心的数据结构是BeanDefinition实体类。

2.io目录

        此目录的功能是通过.xml文件名去获取.xml文件的绝对路径名,然后建立InputStream。

3.reader目录

        此目录功能是通过io目录建立的InputStream将xml文件的内容拿到一个Document对象里面,这里用的是jdk自带的类DocumentBuilderFactory和DocumentBuilder,拿到代表xml文件内容的Docunment对象后就对Document对象从文件根递归解析,把每个bean的定义和配置信息拿到我们定义的Definition对象里面,包括beanName,beanClassName,propertyValues,singleton。最后返回一个Map<String, BeanDefinition>,key是bean的名字,value就是bean的信息(一个Definition对象),最后关闭输入流inputStream.close()。

第二阶段:拿到我们所有的bean的信息后我们怎么生成bean对象呢?这就是第二阶段的内容,这次我们从上往下分析:我们在Spring框架中通过.xml文件去拿到Spring容器的时候,都要通过一个ClassPathXmlApplicationContext(xx.xml)的有参构造来返回一个应用上下文ApplicationContext,他是Spring的入口,然后我们通过这个应用上下去调applicationContext.getBean("beanName")就能得到我们的bean对象,所以context目录的功能就出来了:

4.context目录

        此目录定义一个ApplicationContext接口,在接口中定义getBean方法,给出了获取bean对象的方法,而getBean的方法实现,我们用ClassPathXmlApplicationContext这个类来实现,我们在这个类里面把第一阶段产生的一个Map全部转移到BeanFactory里面的Map中去,也就是把每个bean的名字和对应的Bean的信息都传给BeanFactory,然后对象怎么产生,我们定义在BeanFactory中。

        注意,在 Spring 中,ApplicationContext 实现 BeanFactory 接口的方式,是在 ApplicationContext 对象的内部,保存了一个 BeanFactory 对象的实例,实质上类似一种代理模式。所以我们通过applicationContext.getBean去获取Bean,实际上是beanFactory.getBean去获取Bean,applicationContext.getBean封装了beanFactory.getBean。

5.factory目录

        我们用ConcurrntHashMap存储关于Bean的Name和Bean的信息以保证并发安全。

我们根据Spring框架的2行常见代码来解析factory的内容:

第一行是获取Spring IOC容器,也就是建立BeanFactory工厂,本质工作就是检查BeanFactory里面存储Bean信息的Map,看哪个Bean是singleton模式,singleton模式的Bean在这个阶段就直接生成,然后存储到Map里面去,下次要用就直接返回就行了。核心代码是在ClassPathXmlApplicationContext类里面调用了prepareBeanFactory(beanFactory),这行代码的本质就是调用BeanFactory里面的doCreateBean(),循环遍历来创建singleton模式的Bean对象。

第二行代码就是从Spring IOC容器里面get Bean对象,本质也是调用BeanFactory的getBean方法,如果singleton模式就直接返回,不是就去创建。

创建Bean的本质是通过反射来创建的,对象的创建依赖:

Object bean = beanDefinition.getBeanClass().newInstance();

而对象的属性的赋值依赖:

Field field = bean.getClass().getDeclaredField(propertyValue.getName());

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值