理解Spring的Bean工厂
一提到工厂,我们先来回顾前面学习过的工厂方法和抽象工厂模式:
工厂方法:针对产品维度,能够产生新的产品,也能够产生新的产品工厂,既能够扩展产品维度。可是假设我们想在普通工厂上生产产品系列,就会特别麻烦假设产生Apple你就得产生AppleFactory,假设产生Mushroom,就得产生MushroomFactory.这样就会照成工厂泛滥。
抽象工厂:针对产品系列,能够在谋一系列的产品上进行扩展。缺点是假设产生产品新种,修改就会非常多。
Spring工厂:能够在产品系列方面既能扩展,又能确定产品品种。以下是Spring的实例:
1.首先定义一个接口两个类:
public class Car implements Moveable {
public void run(){
System.out.println("O(∩_∩)O哈哈~,开着敞篷车回家咯~~~~~");
}
}
public class Train implements Moveable {
@Override
public void run() {
System.out.println("呜呜呜~~,仅仅能挤火车 ~~~");
}
}
public interface Moveable {
void run();
}
2.加入引用Spring的Jar包 ,加入XML文件:applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="v" class="com.tgbstd.spring.factory.Car"></bean>
</beans>
3.測试类:
public static void main(String[] args) throws Exception {
BeanFactory f = new ClassPathXmlApplicationContext("applicationContext.xml");
Object o =f.getBean("v"); //传入id
Moveable m =(Moveable)o;
m.run();
}
}
Spring利用本身读取XML配置文件,而且实现了BeanFactory接口。我们仅仅须要在client传入配置文件名称,传入配置文件的ID,就能依据Id找到对应的class产生的对象,并将对象作为一个bean反馈回来。
上面是封装好的一个Spring,那么我们怎样来模拟Spring的原理呢?
Spring模拟:定义一个BeanFactory,在这个里面有自己的实现,最常见的实现ClassPathXML ,从这里面读XML,把读到的信息都装在一个MAP里面,当你要的时候再拿出来。
A.定义BeanFactory接口和getBean方法
public interface BeanFactory {
Object getBean(String id);
}
public class ClassPathXmlApplicationContext implements BeanFactory {
//把全部配置文件中的东西读出来保存在map里面
private Map<String,Object> container = new HashMap<String,Object>();
//定义构造函数
public ClassPathXmlApplicationContext(String fileName) throws Exception {
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build(this.getClass().getClassLoader()
.getResourceAsStream(fileName)); //拿到配置文件
Element root = doc.getRootElement();
List list = XPath.selectNodes(root, "/beans/bean");
// 循环遍历节点
for (int i = 0; i < list.size(); i++) {
Element bean = (Element) list.get(i);
String id = bean.getAttributeValue("id");
String clazz = bean.getAttributeValue("class");
Object o =Class.forName(clazz).newInstance();
container.put(id, o); //存放对象
//相关过程输出
System.out.println("id=" + id);
System.out.println("通过id拿到详细的class信息:" +"class");
}
}
@Override
//调用getBean将拿到的信息返回给客户
public Object getBean(String id) {
return container.get(id);
}
}
在ClassPathXmlApplicationContext类的构造方法中,有一个文件名称,通过fileName指向配置文件,就能从配置文件读取信息了。而且把全部从配置文件读出来的信息,存储在map容器里。
C.測试类
public class Test {
public static void main(String[] args) throws Exception {
//父类引用指向子类对象,找到配置文件
BeanFactory f = new ClassPathXmlApplicationContext("com/tgbstd/spring/factory/applicationContext.xml");
//传入id
Object o = f.getBean("v");
Moveable m =(Moveable)o;
m.run();
}
}
D.结果:
上面简单的介绍了Spring创建Bean工厂的原理。事实上Bean主要是通过自定义一个BeanFactory工厂的实现,通过构造函数传入初始值,读取XML配置文件信息。而且将读取到的id作为key值,读取到的对象作为Value值,存入到Map容器中。当client须要获取时,仅仅要传入id,就能从容器中读取出来。
百度百科定义:Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架。而Bean工厂的概念是Spring作为IOC(面向接口或面向抽象类编程,将详细的东西写在配置文件中。当我们需求改变时,仅仅须要去改动配置文件,比如,将Car改动为Train。我们得到的结果就是做火车回家的方式。)容器的基础。可想而知,理解Bean工厂的原理是很有必要的。
理解Spring的Bean工厂的更多相关文章
- 从基础知识到重写Spring的Bean工厂中学习java的工厂模式
1.静态工厂模式其他对象不能直接通过new得到某个类,而是通过调用getInstance()方法得到该类的对象这样,就可以控制类的产生过程.顺带提一下单例模式和多例模式: 单例模式是指控制其他对象获 ...
- 通过BeanPostProcessor理解Spring中Bean的生命周期
通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理 Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProces ...
- 品Spring:bean工厂后处理器的调用规则
上一篇文章介绍了对@Configuration类的处理逻辑,这些逻辑都写在ConfigurationClassPostProcessor类中. 这个类不仅是一个“bean工厂后处理器”,还是一个“be ...
- 深入理解Spring中bean的生命周期
[Spring中bean的生命周期] bean的生命周期 1.以ApplocationContext上下文单例模式装配bean为例,深入探讨bean的生命周期: (1).生命周期图: (2).具体事例 ...
- spring自定义bean工厂模式解耦
在resources下创建bean.properties accountService=cn.flypig666.service.impl.AccountServiceImpl accountDao= ...
- 一篇教你看懂spring bean工厂和aop
这篇文章为spring回顾总结的第二篇,本篇主要分为两个部分,分别是spring的bean工厂的实现.spring的aop实现原理,这两部分也是面试当中问的比较多的. spring的bean工厂的实现 ...
- 深入理解spring中的各种注解
Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...
- 深入理解spring中的各种注解(转)
Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...
- 指定spring中bean启动的顺序
参考链接: https://www.jb51.net/article/125846.htm 使用DependsOn Spring 中的 DependsOn 注解可以保证被依赖的bean先于当前bean ...
随机推荐
- Collections.sort方法对list排序的两种方式
Collections.sort( )分为两部分,一部分为排序规则,一部分为排序算法 . 规则用来判断对象,算法则考虑如何进行排序 对于自定义对象,sort()不知道规则,所以无法比较,这种情况下一定 ...
- Ubuntu 安装启动Tomcat
首先下载ubuntu 的tar包 官网: http://tomcat.apache.org/download-80.cgi 安装启动 1 .下载对应的tar 2 .解压任意文件夹下,更改名字tomca ...
- lsh341999的资源
懒得下载了,仔细研究: http://download.csdn.net/user/lsh341999/uploads/2
- FMXUI - UI.Dialog 示例
在 FMXUI 开源库,增加了 UI.Dialog 单元.此单元实现了跨平台的基础对话框组件.使用时引用 UI.Dialog 即可.如果需要自定义对话框的样式, 可以添加一个 TDialogStyle ...
- 『WPF』DataGrid的使用
原文 『WPF』DataGrid的使用 几点说明 这里主要是参考了MSDN中关于DataGrid的说明 这里只会简单说明在WPF中,DataGird最简单的使用方法 对于MSDN中的翻译不会很详细,也 ...
- [置顶] Objective-C ,ios,iphone开发基础:UIAlertView使用详解
UIAlertView使用详解 Ios中为我们提供了一个用来弹出提示框的类 UIAlertView,他类似于javascript中的alert 和c#中的MessageBox(); UIAlertVi ...
- hdu4431 Mahjong
Mahjong Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 学习算法-基数排序(radix sort)卡片分类(card sort) C++数组实现
基数排序称为卡片分类,这是一个比较早的时间越多,排名方法. 现代计算机出现之前,它已被用于排序老式打孔卡. 说下基数排序的思想.前面我有写一个桶式排序,基数排序的思想是桶式排序的推广. 桶式排序:ht ...
- 华为手机logcat不出日志解决方案
解决方法:在拨打电话界面,录入*#*#2846579#*#* 自动进入开发界面菜单,进入第一个,选择开启logcat.
- VS2010+QT4.8.5 +FastReport教程
如需转载请标明出处:http://blog.csdn.net/itas109 採用QT 的QAxObject方式执行FastReport特别麻烦,并且无法在编译的时候知道代码是否正确,并且大部分的函数 ...