因为我们一般是Web开发,所以本文的环境是web环境。有jetty有servlet(自己实现)。

我的逻辑是这样的,程序启动就去加载classpath下的某个配置文件,然后解析转换成BeanInfo对象,然后存入Map中,然后开始实例化,取出Map中的BeanInfo对象,取到属性(是类的权限定名),根据属性值用反射实例化Bean,实例化完成后根据所有Bean的set方法进行注入,把注入后的Bean对象与bean的名称映射放入map;然后就是使劲往spring上靠,这里也有一个beanFactory(IOC基础容器)维护了这两个Map,还有个ApplicationContext(Ioc上下文容器,基础Ioc包装,这里为了简单没有其他的逻辑)持有beanFactory。
下面为项目结构,下面会有详细解释

Spring 依赖注入之造轮术(下)
由于本工程是Web项目,并且要求在web容器启动就去加载xml,所以这里有个SpringListener代码如下
Spring 依赖注入之造轮术(下)
其继承了ServletContextListener,保证了在web启动的时候去执行contextInitialized方法。
getFilePath是获取在web.xml中配置的配置文件的绝对路径。代码如下:
Spring 依赖注入之造轮术(下)
这里是通过web.xml的全局初始化参数去加载名为configLocation的参数值,其值为配置的xml路径。
支持两种写法一种是classpath:+文件名 另一种是直接写文件名都是去classpath下去找。对应的web.xml配置如下:
Spring 依赖注入之造轮术(下)
另一个方法refresh是核心方法,xml的解析,初始化,实例化,依赖注入都在这个方法中执行
refresh方法代码如下:
Spring 依赖注入之造轮术(下)
在解析上面代码之前,先看下配置文件,配置的sping.xml文件内容如下
Spring 依赖注入之造轮术(下)
为了简单起见,这里只配置了两个Bean,分别只有id与class属性
UserController持有一个UserService引用,并且有个set方法(用来依赖注入),代码如下
Spring 依赖注入之造轮术(下)
UserService 代码如下
Spring 依赖注入之造轮术(下)
ok,接下来先看refresh中的resolveXml代码,代码如下
Spring 依赖注入之造轮术(下)
以下为listNode递归解析
Spring 依赖注入之造轮术(下)
Spring 依赖注入之造轮术(下)
代码解释已经在代码中标出,这里不再做描述,代码中可以看出返回值已经包括了所有在xml配置的bean。
下面代码是上面提到的一些类:
BeanHashMap类:
Spring 依赖注入之造轮术(下)
SpringBeanFactory类:
Spring 依赖注入之造轮术(下)
接下来看refresh中的instance方法,这是实例化bean与依赖注入:
InstanceBean类如下:
Spring 依赖注入之造轮术(下)
instanceBeansAndInject方法:
Spring 依赖注入之造轮术(下)
Spring 依赖注入之造轮术(下)
getBeanNameInMap方法:
Spring 依赖注入之造轮术(下)
到此为止,所有的bean已经实例化,并且都进行了依赖,都存到了SpringBeanFactory的实例化bean的Map中,以后只要
用就在SpringBeanFactory通过getBean即可。
最后还有一个类SpringApplicationContext是对SpringBeanFactory的封装,这里只是简单的持有SpringBeanFactory的引用,
spring中还做了其他扩展。
SpringApplicationContext类如下:
Spring 依赖注入之造轮术(下)
最后在refresh的initContext方法中进行两者关联:
Spring 依赖注入之造轮术(下)

至此所有的工作完成,接下来验证,写个servlet实现doget方法,在servlet中取出上下文,得到SpringApplicationContext
属性,然后调用getBean获取usercontroller这个Bean,调用say方法代码如下:
Spring 依赖注入之造轮术(下)
在web.xml配置此servlet,并设置匹配路径:
Spring 依赖注入之造轮术(下)
启动工程访问http://localhost:8080/hello
控制台打印:
Spring 依赖注入之造轮术(下)
userController与userService的say方法都执行了,说明注入成功。

相关文章:

  • 2021-09-29
  • 2021-07-18
  • 2021-08-07
  • 2021-12-03
  • 2021-10-10
猜你喜欢
  • 2022-12-23
  • 2021-11-05
  • 2021-09-02
  • 2022-12-23
  • 2022-12-23
  • 2021-06-12
相关资源
相似解决方案