一直在使用
Spring
,感慨良多,有欣赏也有不屑。如今
spring2.0
出现了,趁此机会对它进行一个深入的研究,以便印证自己的一些想法,同时也理解
Spring
的演进。
没有XmlBeanFactory(InputStream is);这样的构造子啊,不知为什么,呵呵。后来我用下面的代码来实现:
写到这里IoC容器和Bean的原理就介绍完了,下一次介绍“依赖”。使用实例工厂方法实例化:
同时
Spring IoC
的
Bean
功能也和这些信息对应。
本文将以章节的形式出现,以反映笔者的进程。
一、
IoC
1.1 容器和Bean的原理
1.1.1 容器
Spring
文档中的这张示意图很好的反映了“容器”一词在
Spring
中的含义。
首先
spring
将读取我们配置的原数据并通过他对应用中的
各个对象进行
实例化、配置和组装
org.springframework.beans.factory.BeanFactory
是
Spring IoC
容器的实际代表者,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。从本质上讲,
BeanFactory
仅仅只是一个维护
bean
定义以及相互依赖关系的高级工厂接口。
我们配置的表现形式可以是多样的。到目前版本以支持:
XML
格式、
Java
属性文件格式或使用
Spring
公共
API
编程实现。
但是
Spring
将配置元数据的读取与容器的实现封装在一个类中,总感觉是一种“耦合”,是否应该将配置元数据重新封装在另一个独立接口中呢?
到目前为止
Spring
提倡的主流的配置形式仍是
XML
配置文件,同时
Spring
对这种方式也有比较完善的
API
支持,比如多
xml
的载入就有两种不同的实现方式:
1、
将文件路径作为字符串数组传给
ApplicationContext
构造器,而
bean factory
将通过调用
bean defintion reader
从多个文件中读取
bean
定义。
2、
使用一个或多个的
<import/>
元素来从另外一个或多个文件加载
bean
定义。
1.1.2 Bean
这里说的
Bean
是指
:
通过配置由
Spring
管理的对象,
Spring
支持多种
bean
的形式。在
IoC
容器内部,这些
bean
定义由
BeanDefinition
对象来表示,该定义将包含以下信息:
Class、name、scope、constructor arguments、properties、autowiring mode、dependency checking mode、lazy-initialization mode、initialization method和destruction method
·类命名(name)
Spring
允许为Bean指定一个或者多个别名,在Bean的定义中可以同过name属性,如:<bean id="name1" name="name2,name3,name4" class="java.lang.String"/>;同时,在xml配置文件的其它部分可以通过alias标签指定已存在bean的别名,如:<alias name="componentA-dataSource" alias="componentB-dataSource"/>。
写到这里,我想到Spring中的相关实现大概如此:
这里笔者使用范型的方式将Map的结构表现出来,当然在容器中还会有Map<String,
BeanDefinition>
这样的Map,用来保存Bean名称和BeanDefinitiond的映射。
/** */
/** Map from alias to canonical bean name */
private final Map < String,String > aliasMap = new HashMap < String,String > ();
private final Map < String,String > aliasMap = new HashMap < String,String > ();
·类初始化(class)
Spring
类的初始化有三种形式:用构造器来实例化、使用静态工厂方法实例化和使用实例工厂方法实例化。XML配置分别如下:
用构造器来实例化:
使用静态工厂方法实例化:
<
bean
id
="exampleBean"
class
="examples.ExampleBean"
/>
<
bean
id
="exampleBean"
class
="examples.ExampleBean2"
factory-method
="createInstance"
/>
1.1.3 容器的使用
关于容器的使用,在Spring2.0 的官方文档上是有这样一段代码:
我不知道是文档作者的疏忽还是我的无知,不过这段代码在2.0中编译不通过,看看XmlBeanFactory的源码:
InputStream is
=
new
FileInputStream(
"
beans.xml
"
);
BeanFactory factory = new XmlBeanFactory(is);
BeanFactory factory = new XmlBeanFactory(is);
public
class
XmlBeanFactory extends DefaultListableBeanFactory
...
{
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
/**//**
* Create a new XmlBeanFactory with the given resource,
* which must be parsable using DOM.
* @param resource XML resource to load bean definitions from
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource) throws BeansException ...{
this(resource, null);
}
/**//**
* Create a new XmlBeanFactory with the given input stream,
* which must be parsable using DOM.
* @param resource XML resource to load bean definitions from
* @param parentBeanFactory parent bean factory
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException ...{
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
/**//**
* Create a new XmlBeanFactory with the given resource,
* which must be parsable using DOM.
* @param resource XML resource to load bean definitions from
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource) throws BeansException ...{
this(resource, null);
}
/**//**
* Create a new XmlBeanFactory with the given input stream,
* which must be parsable using DOM.
* @param resource XML resource to load bean definitions from
* @param parentBeanFactory parent bean factory
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException ...{
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
Resource resource
=
new
FileSystemResource(
"
applicationContext.xml
"
);
BeanFactory factory = new XmlBeanFactory(resource);
BeanFactory factory = new XmlBeanFactory(resource);
<!--
the factory bean, which contains a method called createInstance()
-->
< bean id = " myFactoryBean " class = " ... " >
...
</ bean >
<!-- the bean to be created via the factory bean -->
< bean id = " exampleBean "
factory - bean = " myFactoryBean "
factory - method = " createInstance " />
< bean id = " myFactoryBean " class = " ... " >
...
</ bean >
<!-- the bean to be created via the factory bean -->
< bean id = " exampleBean "
factory - bean = " myFactoryBean "
factory - method = " createInstance " />