在spring2.5中,Spring给我们供给生成IOC容器的体式格式有很多种。 1.硬编码 2.采取资料文件设备 3. XML情势设备 4. 注解,在spring3.0中还供给了一种javaconfig体式格式。这里先经由过程硬编码体式格式发挥解析IOC容器是如何产生的,然后再给出XML的体式格式是如何获得BeanFactory和ApplicationContext的办法
起首给大师看看我的Demo目次和目次中响应文件中的代码:
那些测验测验去做某事却失败的人,比那些什么也不测验测验做却成功的人不知要好上几许。
此中我的UserServiceImpl是如下实现的,很简单:
?
public class UserServiceImpl implements UserService {
private Map<String, String> map;
public UserServiceImpl () {
System.out.println("UserServiceImpl");
}
public void printInfo() {
System.out.println("hello word." + map);
}
public void setMap(Map<String, String> map) {
this.map = map;
}
}
?
我的XML设备,后面将解析的spring.xml设备
<bean id="userService" class="com.zhuxy.app.biz.impl.UserServiceImpl"> <property name="map"> <map> <entry key="hello" value="world"></entry> <entry key="love" value="you"></entry> </map> </property> </bean>?
在AppRun 中我添加了如下的代码,欲望运行后,能顺利的履行 printInfo()办法
public static void main(String[] args) {
UserService userService = (UserService) codeMethod().getBean("userService");
userService.printInfo();
}
?
?硬编码体式格式
/**
* 经由过程硬编码体式格式
*/
private static BeanFactory codeMethod() {
DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory();
AbstractBeanDefinition definition = new RootBeanDefinition(UserServiceImpl.class);
definition.setScope(ConfigurableBeanFactory.SCOPE_SINGLETON); // 包管单利
// 将Bean定义注册到容器中
beanRegistry.registerBeanDefinition("userService", definition);
Map<String, String> map = new HashMap<String, String>();
map.put("hello", "world");
map.put("love", "you");
// 同过set办法注入
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("map", map);
definition.setPropertyValues(propertyValues);
return beanRegistry;
}
?
写这段代码之前,我还有些困惑。收拾完下面的图,我逐渐的熟悉打听了:
这张图很清楚的描画了BeanFactory ,DefaultListableBeanFactory ,BeanDefinitionRegistry,以及 XmlBeanFactory之间的关系。
BeanFactory是对生成的Bean进行经管的接口
BeanDefinitionRegistry定义了Bean注册的逻辑
DefaultListableBeanFactory 同时实现了 BeanFactory 和 BeanDefinitionRegistry 2个接口, 从而实现了Bean的注册和经管。
每一个受管的对象在容器中都邑有一个BeanDefinition与之对应,负责保存对象所有的须要信息,此中包含对象的类型,是否是抽象类,机关办法参数,以及其它属性。 当客户端向BeanFactory恳求一个对象的时辰,BeanFactory会经由过程这些信息为客户端返回一个完全可用的对象实例。
对于设备文件的解析,spring供给了XmlBeanDefinitionReader,PropertiesBeanDefinitionReader 2种喜闻乐见的体式格式,也可以本身定义一种体式格式来实现,比如喜好json风格的伴侣,可以本身编写一套json的解析体式格式。
XML 解析体式格式
如下就是经由过程XmlBeanDefinitionReader来解析的做法
/**
* Spring 为 XML 格局的设备文件供给了BeanDefinitionReader实现即:XmlBeanDefinitionReader。
* 它负责读取Spring指定格局的XML文件并解析,之后将解析的文件内容映射到BeanDefinition,
* 并加载到响应 的BeanDefinitionRegistry中,这时就可以给用户应用了
*/
private static BeanFactory xmlMethod1() {
DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanRegistry);
reader.loadBeanDefinitions("classpath:spring.xml");
return (BeanFactory) beanRegistry;
}
?
简化版:
/**
* 简化第一钟 XML 体式格式:
* Spring 还在DefaultListableBeanFactory的根蒂根基上构建了简化XML格局设备加载的XmlBeanFactory实现
*/
private static BeanFactory xmlMethod2() {
return new XmlBeanFactory(new ClassPathResource("spring.xml"));
}
?
别的这里还供给了2种体式格式,创建ApplicationContext高低文,同样可以当做Spring 的 IOC Service Provider.
/**
* 经由过程FileSystemXmlApplicationContext形成ApplicationContext
*/
private static ApplicationContext applicationMethod1() {
ApplicationContext context = new FileSystemXmlApplicationContext("src/spring.xml");
return context;
}
?
?
?
/**
* 经由过程ClassPathXmlApplicationContext形成Application
*/
private static ApplicationContext applicationMethod2() {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
return context;
}
?
这里为了申明BeanFactory和ApplicationContext 的差别,收拾了下图。
?
从这张图中可以看出
1. ApplicationContext 间接持续于 BeanFactory 。 所以用BeanFactory 能操纵的东东,ApplicationContext 也可以。
2. ApplicationContext 所实现的功能远比BeanFactory的功能多。比如国际化,事务公布等
ps:
在实际应用中,大师可以调查到应用ApplicationContext来加载资料文件,速度比拟BeanFactory会慢很多,占用的体系资料也相对较多。这里主如果因为
采取ApplicationContext默认一开端就初始化所有的对象,而BeanFactory是在初次接见时才初始化这些对象