我对spring的感觉-开篇(IOC篇)

个人见解, 欢迎指正。

spring 主要看两块
1.spring的核心
2.spring的数据访问

下面我们从这两点出发,说说我对spring的感受。
1.关于spring的核心

我们知道现在spring发展的很好,社区也很好,可以说是java必备了。
spring最开始的时候,其实功能很简单,就是为了减少程序员的重复工作 ,比如依赖注入等
如果最早的时候,你有一个想法, 指定配置文件路径,启动时候解析 ,反射实例化类,保存在map容器中 , 那你发展发展有可能搞出个spring出来。

言归正传:
spring的核心,基本是spring面试必备了 , 大家应该都不陌生,就是IOC、DI、AOP、MVC这四大功能。

下面我们来说说IOC:
IOC其实就是我上面说的,用一个map存储实例对象,以后你的依赖注入等等一系列操作,都围绕这个map展开。

如果有这样一个需求,你要怎么做呢 ?
1->你需要资源文件的位置?
我们可以通过contextConfigLocation参数、annotation扫描、new Application中传递的路径来定位资源文件。文件可以存放在classpath、FileSystem、servletContext、newWork等地方。
但是问题来了 ,我们发现文件格式多种多样啊 ?有xml、yml、properties、annotation等
2-> 如何解决多种多样的配置文件?
不管有多少种配置文件和格式 ,我用不同的解析器,最终把它们都解析成统一的格式。
所以spring中,采用策略模式,对不同的文件进行解析,最终都会把对bean的描述解析成BeanDefinition

我们上面说到,ioc容器其实就是把对象存到map中,那我们只要跟一下源码,看到把bean放到map中,也就是ioc容器初始化了。
下面我们来跟踪一下源码,
3->源码跟踪
不管是ClassPathXmlApplication、FileSystemXmlApplication还是AnnotataionApplication
它们都会调用refresh方法,这个方法相当于入口 功能主要是重启、刷新、重置

我们以ClassPathXmlApplication为例。
setConfigLocations就是解析定义的资源文件路径
refresh是一个抽象类中的方法,也就是说这方法是公用的。
我们主要关注 obtainFreshBeanFactory,也就是bean资源文件的载入。
obtainFreshBeanFactory->我们看到这里定义了一个抽象方法 refreshBeanFactory,
也就是说,具体的实现交给子类完成。跟下去 。
refreshBeanFactory 我们可以看到 一些对于容器的操作了。

判断容器是否存在?如果存在就销毁容器中的bean 并关闭容器:

if (hasBeanFactory()) {
	destroyBeans();
	closeBeanFactory();
}

创建ioc容器(这时DefaultListableBeanFactory已经出来了 )

DefaultListableBeanFactory beanFactory = createBeanFactory();

我们主要看loadBeanDefinitions bean的载入过程.这块还是使用的委派模式,我们取看子类实现。
loadBeanDefinitions中 我们看到了一个 XmlBeanDefinitionReader 这是bean资源文件读取器。
我们继续看重载的loadBeanDefinitions ,在这个里面,又调用了DefinitionReader的loadBeanDefinitions;
我们继续跟踪发现还是loadBeanDefinitions(为什么套这么多 ? 这就是单一职责原则)

最终会回到XMLBeanDefinitionReader的 loadBeanDefinitions(Resource)重载的方法。
这里你会看到熟悉的代码。花里胡哨的你是终于要干活了。

InputStream inputStream = encodedResource.getResource().getInputStream();

我们接着看doLoadBeanDefinitions,也就是读取过程
这里面会将resource转换成document对象 -> 传给 registerBeanDefinitions
不看花里胡哨的我们接着 registerBeanDefinitions
这里我们看到 获取了document的根元素root ->传递给 doRegisterBeanDefinitions
这里面记住别看蒙了 跟住 BeanDefinitionParserDelegate对象 ,就能找到光明

->parseBeanDefinitions(从根元素开始解析,bean定义的document对象)
-> parseDefaultElement(使用spring的bean规则解析)
这里 你看到了熟悉的模样吧 ?
我们主要看解析元素节点"bean"->processBeanDefinition
下面这个是 ?它其实就是BeanDefinition,使用的装饰器模式,包装了一下。在这里就已经把xml的数据解析成统一格式BeanDefinition了

BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

我们看下面这个,registry是什么呢?DefaultListableBeanFactory就是它的实现。到这你想到什么了吗?
beandefinition的包装类 和DefaultListableBeanFactory的父类都传递过去了,那是不是说通过registry就可以把beandefinition 放到 DefaultListableBeanFactory的 beandefinitionMap中了 ?

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());

果然如此。。在里面就自行跟踪吧,就是放到map里。支持ioc容器初始化完成了。

registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

未完待续接着更新 spring的DI…

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值