前言
距离上次更新有一周了,
这几天一直在寻找一种方式将源码的概念清晰的呈现出来
最好的方式莫过于源码结合UML类图+时序图,理解起来还是会有障碍
如果有更好的表述方式,希望大家可以给我留言,并指点一二,不胜感激
这篇原定要写IOC容器接口继承体系,已经写好了几天,只是没发出来
今天觉得应该先写一个IOC容器的简单Demo,介绍一下使用
顺便也为不熟悉Spring框架的朋友们降低一下学习门槛
对于Spring框架的学习,不仅是了解框架内部实现,有助于日常开发,
更多的还是学习框架思想以及优秀代码是如何架构,分层和实现的
Spring框架中使用的设计模式堪称最佳实践,是非常有价值的
那这一篇,对于熟悉Spring框架的朋友,又几乎是一篇废话了....
IOC容器的源码环境
之前我们说了Spring框架源码环境的搭建
Spring框架提供了根据应用场景的剪裁和选择
研究IOC容器部分,我们可以只使用Spring框架的IOC容器部分.即源码中的spring-beans模块
IOC容器依赖模块:
IOC容器功能的实现主要在org.Springframework.beans.jar中,即spring-beans模块
而spring-beans依赖于spring-core模块
IOC容器部分,只需要依赖spring-beans和spring-beans即可
创建IOC容器工程:
创建java工程IocContainer,使其依赖spring-beans和spring-beans两个模块
项目结构:
项目模块依赖关系:
测试IOC容器
为了测试IOC容器,我们写一个最简单的Demo,项目结构如下:
1.Bean:MyTestBean.java
Spring的目的就是让bean能成为一个纯粹的POJO(Plain Ordinary Java Object 简单的Java对象)
package com.brave.spring.beans;
public class MyTestBean {
private String testStr = "testStr";
public String getTestStr() {
return testStr;
}
public void setTestStr(String testStr) {
this.testStr = testStr;
}
}
2.配置文件:beanFactoryTest.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(com.brave.spring.beans.MyTestBean),id属性为MyTestBean -->
<bean id="MyTestBean" class="com.brave.spring.beans.MyTestBean"/>
</beans>
以上虽然是一个最简单的bean声明方式,但能够满足大多数应用的需要
Spring配置中的bean元素还提供了N多种属性,可以适配各种应用场景,后续会逐个讲解
3.测试类:BeanFactoryTest.java
package com.brave.spring.beans;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class BeanFactoryTest {
public static void main(String[] args) {
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
MyTestBean bean = (MyTestBean)xmlBeanFactory.getBean("MyTestBean");
String testStr = bean.getTestStr();
System.out.print("testStr = " + testStr);
}
}
从命名可以看出,这是一个对bean工厂的测试,主要逻辑如下:
1,读取配置文件beanFactoryTest.xml
2,根据beanFactoryTest.xml中的配置(id)在Bean工厂中找到对应类的配置,并实例化
3,调用实例
关于Demo中xmlBeanFactory的详细实现,也是我们日后要说的重点
IOC容器的一些概念
以上我们创建了一个只拥有IOC容器功能的Spring工程
虽然我们实现了Spring-IOC容器下,通过配置文件创建和使用bean
但概念上还需要再细说一下,对于日后学习源码会有帮助
理解”容器”
说到容器,我们应该能想到水壶,水杯,水桶之类,他们是装水的容器
而IOC容器,即Bean容器(BeanFactory),就是装bean的容器
所以,我们可以将Bean容器想象成一个水桶,而其中的bean就是水桶中的水
bean容器中装载的无数Bean,就相当于水桶中的无数水滴
Spring中的容器
尽管水桶有大小和材质上的区别,但我们统称之为水桶
我们如何定义水桶? 能装水的桶叫水桶,重点在于能装水
站在面向对象的角度,"水桶"应该实现"能装水"的接口
Spring中也为我们提供了多种BeanFactory的实现,
Spring中如何定义BeanFactory?必须要实现BeanFactory接口
BeanFactory接口定义了Bean容器的基本功能
如Demo中的xmlBeanFactory,在实现了BeanFactory接口的基础上,增加了通过XML文件获取资源定位的能力
后续讲解容器接口体系时,会主要讲解两类BeanFactory
一类是基于BeanFactory实现的容器,我们将这一类容器称为"基本容器"
另一类是基于ApplicationContext实现的容器,我们将这一类容器称为"高级容器"
bean如何放入容器
Spring提供了多种定义bean的方式,如xml方式,注解方式
而对于容器(水桶)而言,不管以何种方式定义bean,最终在容器中都是以同一种对象(水)存在
Spring通过BeanDefinition,抽象了我们对Bean的定义,是容器的主要数据类型
BeanDefinition即为Bean容器中的"水"
Spring用过各种资源加载器,获取定义Bean的资源定位,转换为BeanDefinition,放入BeanFactory
结尾
这一篇暂时先写到这里,虽然没什么营养,也为日后的学习做了铺垫
这个Demo依赖了spring-bean和spring-core的源码
也是日后学习这部分源码的重要工程
关于容器理解的部分日后会继续补充的完善
维护日志:
20180318:
删除了多余的修饰词,使语义更加简洁明确