spring的强大之处在于它的扩展性非常的好,而spring中IOC和AOP的功能非常强大,帮我们在工作中解决了很多的麻烦,节省了很多撸代码的时间,使我们更能专注于业务代码;下面我们使用调试的方式来看看spring是如何初始化bean的。
IOC:(Inversion Of Control)控制反转,可以分为两部分来理解:
1、控制:创建对象的权利被控制了,之前创建对象都是我们在程序中new出来的,现在对象的创建交给了IOC容器,由IOC来创建并控制了对象
2、反转:IOC容器帮我们查找及注入依赖对象,之前是我们主动去获取对象的依赖,其实是依赖对象的获取被反转了
接下来我们先看IOC容器的初始化和对bean的解析。
代码片段:
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="testService" class="com.yashon.gateway.service.TestService"></bean>
</beans>
代码:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-service.xml");
TestService testService = context.getBean("testService", TestService.class);
使用debug模式进入到ClassPathXmlApplicationContext中的构造方法
其中setConfigLocations(configLocations);这个方法进入到AbstractRefreshableConfigApplicationContext
在这个方法中设置配置文件的路径;这个方法走完打出日志:
接下来会进入最重要的refresh()方法
在这篇文章中最重要的是obtainFreshBeanFactory();这个方法,spring将在这个方法中完成IOC的初始化和对bean的解析
进入到obtainFreshBeanFactory()方法中,会看到一个很简单的调用:
进入到refreshBeanFactory();中,这个方法在AbstractRefreshableApplicationContext类中,这个类继承了AbstractApplicationContext
这个方法中首先会判断是否有beanFactory,如果有则销毁bean并关掉beanFactory
接下来会创建beanFactory(创建的是DefaultListableBeanFactory对象)、设置序列化ID、自定义beanFactory、加载beanDefinitions
进入到loadBeanDefinitions()方法中(AbstractXmlApplicationContext类中):
进入到方法:loadBeanDefinitions
进入到AbstractBeanDefinitionReader类中的loadBeanDefinitions()统计加载xml的个数:
最终进入到XmlBeanDefinitionReader类中的loadBeanDefinitions()方法:
在这个方法中主要是使用流读取配置文件,接着会把相关的配置文件和流传入doLoadBeanDefinitions()方法中,在这个方法中完成spring对bean的注入
这个方法很简单:1、获取Document对象;2、注册beanDefinition;进入到registerBeanDefinitions()方法中:
在这个方法主要是返回beandefinitions的个数,其中getRegistry()就是返回beanFactory,因为beanFactory继承了BeanDefinitionRegistry
进入到DefaultBeanDefinitionDocumentReader类中的registerBeanDefinitions()方法:
再次进入doRegisterBeanDefinitions()方法:
在这个方法中完成beanDefinition的解析,最终会进入DefaultListableBeanFactory类,在这个类中使用beanDefinitionMap将beanName作为key,beanDefinition作为value存入缓存中。
接下来就是获得beanFactory,将初始化完成的beanFactory返回:
以上有不正确的地方,请指出,谢谢!
就此对IOC容器的初始化算是完成了,接下来会初始化bean