容器是什么?spring中是如何体现的?一直有疑惑,这两天看了一下Spring管理bean的Demo,对于Spring中的容器有了简单的认识。

我们知道,容器是一个空间的概念,一般理解为可盛放物体的地方。在Spring容器通常理解为BeanFactory或者ApplicationContext。我们知道spring的IOC容器能够帮我们创建对象,对象交给spring管理之后我们就不用手动去new对象。

其中有BeanFactory与ApplicationContext两种方式可以创建对象。

那么BeanFactory与ApplicationContext的区别是什么?

BeanFactory采用了工厂设计模式,负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。而ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:国际化支持、aop、事务等。同时BeanFactory在解析配置文件时并不会初始化对象,只有在使用对象getBean()才会对该对象进行初始化,而ApplicationContext在解析配置文件时对配置文件中的所有对象都初始化了,getBean()方法只是获取对象的过程。

所以ApplicationContext的应用场景更广泛。

ApplicationContext是如何管理Bean呢?下面这个Demo简单模仿了这个原理:

1.建立一个类PersonServiceBean,并在xml文件中进行配置。

public class PersonServiceBean implements PersonService   {
public void save(){
System.out.println("我是save()的方法");
}
}
<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>  

2.建立类BeanDefinition,提供一个构造函数,将其作为每个bean的公共转型类。

public class BeanDefinition {  

    private String id;
private String className; public BeanDefinition(String id, String className) {
this.id = id;
this.className = className;
}
//get set方法
}

3.建立容器类tgbApplicationContext。

 /**
* 测试spring容器
* @author hegang
*
*/
public class tgbClassPathXMLApplicationContext { private List<BeanDefinition> beanDefines =new ArrayList<BeanDefinition>();
private Map<String,Object> sigletons =new HashMap<String,Object>(); public tgbClassPathXMLApplicationContext(String filename){
this.readXML(filename);
this.instanceBeans();
} /**
* 完成bean的实例化
*/
private void instanceBeans() {
for(BeanDefinition beanDefinition : beanDefines){
try {
if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())){
sigletons.put(beanDefinition.getId(),Class.forName(beanDefinition.getClassName()).newInstance());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } } /**
* 读取xml配置文件
* @param filename
*/
private void readXML(String filename) {
SAXReader saxReader = new SAXReader(); //创建读取器
Document document =null;
try{
URL xmlpath = this.getClass().getClassLoader().getResource(filename);
document =saxReader.read(xmlpath);
Map<String,String> nsMap =new HashMap<String,String>();
nsMap.put("ns","http://www.springframework.org/schema/beans"); //加入命名空间
XPath xsub = document.createXPath("//ns:beans/ns:bean"); //创建beans/bean查询路径
xsub.setNamespaceURIs(nsMap); // 设置命名空间
List<Element> beans = xsub.selectNodes(document); // 获取文档下所有的bean节点
for(Element element:beans){
String id =element.attributeValue("id"); // 获取id属性值
String clazz =element.attributeValue("class"); // 获取class属性值
BeanDefinition beanDefine =new BeanDefinition(id,clazz);
beanDefines.add(beanDefine);
} } catch(Exception e){
e.printStackTrace();
} } /**
* 获取bean实例
* @param beanName
* @return
*/
public Object getBean(String beanName){
return this.sigletons.get(beanName);
}
}

该类中拥有一个List<BeanDefinition>泛型集合类以及一个Map<String,Object>集合。通过查看代码我们知道这个容器类所做的事情如下:

a.读取配置文件bean.xml,并根据文件中bean的id,class属性实例化一个BeanDefinition,装入泛型集合中。

b.通过循环+反射,将List<BeanDefinition>中的bean加入到Map<String,Object>中,这里用反射将bean中的className属性转换为一个实例化的bean对象加入到了Map中。

c.提供一个对外的接口,通过传入参数获取该bean。

4.下面就是通过容器类获取具体bean的代码了。

 public class SpringTest {
@Test
public void instanceSpring(){
tgbClassPathXMLApplicationContext ctx =new tgbClassPathXMLApplicationContext("beans.xml");
PersonService personService =(PersonService) ctx.getBean("personService");
personService.save();
}
}

通过这样的Demo,可以清楚看到Spring容器做的事情。它在初始化的时候将配置文件中bean以及相对应关系的配置都加入到ApplicationContext,通过一系列的转换将这些bean实例化,bean被它进行了管理,所以ApplicationContext就扮演了一个容器的角色。

最新文章

  1. SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)
  2. UNIX系统基本结构
  3. c++错误——intermediate.manifest : general error c1010070很傻的错
  4. iso 培训笔记
  5. linux中nc详解
  6. scala中的抽象类
  7. 封装WCF客户端调用
  8. Gradle tip #2: understanding syntax
  9. oracle冷备份后恢复
  10. linux tar 打包 压缩 解压
  11. 方便mac os 10.9系统中phpstorm配置php运行环境
  12. windows10 subsystem(bash) 如何使用jupter notebook
  13. RHEL7对比RHEL6的主要变化
  14. Spring以及tomcat中的Listener
  15. wcf在post请求时,关于string类型参数传入中文的处理
  16. jqgrid 获取选中行主键集合
  17. jdk1.8源码Thread与Runnable区别
  18. oozie无法识别hadoopHA中的ns1
  19. CCF CSP 201312-4 有趣的数
  20. HDU - 1051 Wooden Sticks 贪心 动态规划

热门文章

  1. oracle截取字符串,定索引
  2. Linux学习grep,sed,awk工具的使用
  3. js 中callback函数的定义和使用
  4. shell中获取本机ip地址
  5. Java基础06-条件选择语句
  6. 性能测试工具LoadRunner10-LR之Virtual User Generator 错误处理函数
  7. 性能测试工具Jmeter06-Jmeter元件作用域和执行顺序
  8. Spring Boot实战(3) Spring高级话题
  9. ES增删改查入门1
  10. 利用DOS命令做伪装成图片的压缩包,看上去是图片其实是个压缩包用2条命令即搞定