spring管理bean原理

PersonService.java
Java代码
package cn.itcast.service;  
 
public interface PersonService {  
 
    public void save();  
 
}  
PersonServiceBean.java  
package cn.itcast.service.impl;  
 
import cn.itcast.service.PersonService;  
 
public class PersonServiceBean implements PersonService {  
 
    public void save(){  
        System.out.println("传智播客版容器:  我是save()方法");  
    }  

package cn.itcast.service;

public interface PersonService {

 public void save();

}
PersonServiceBean.java
package cn.itcast.service.impl;

import cn.itcast.service.PersonService;

public class PersonServiceBean implements PersonService {

 public void save(){
  System.out.println("传智播客版容器:  我是save()方法");
 }
}
BeanDefinition.java
Java代码
package junit.test;  
 
/* 
 * 在读取配置文件的时候,我们会把读取到bean的信息存放在这个javabean对象里面去 
 * */ 
public class BeanDefinition {  
    private String id;  
    private String className;  
 
    public BeanDefinition(String id, String className) {  
        this.id = id;  
        this.className = className;  
    }  
    public String getId() {  
        return id;  
    }  
    public void setId(String id) {  
        this.id = id;  
    }  
    public String getClassName() {  
        return className;  
    }  
    public void setClassName(String className) {  
        this.className = className;  
    }  
 

package junit.test;

/*
 * 在读取配置文件的时候,我们会把读取到bean的信息存放在这个javabean对象里面去
 * */
public class BeanDefinition {
 private String id;
 private String className;

 public BeanDefinition(String id, String className) {
  this.id = id;
  this.className = className;
 }
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getClassName() {
  return className;
 }
 public void setClassName(String className) {
  this.className = className;
 }

}beans.xml
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-2.5.xsd"> 
          <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean> 
</beans> 

<?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-2.5.xsd">
          <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>
</beans>
  前面我们学习了怎样把bean交给Spring容器管理,怎样从Spring容器获取bean实例,相信大家肯定会有很多疑问,其中一个疑问是:  Spring容器内部怎么帮我们创建,管理bean的?
  接下来解说一下,到底Spring容器内部是如何创建bean的。 我们模拟Spring容器,来建一个传智播客版的Spring容器
ItcastClassPathXMLApplicationContext.java
Java代码
package junit.test;  
 
import java.net.URL;  
import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  
 
import org.dom4j.Document;  
import org.dom4j.Element;  
import org.dom4j.XPath;  
import org.dom4j.io.SAXReader;  
 
/** 
 * 传智播客版的Spring容器 
 */ 
public class ItcastClassPathXMLApplicationContext {  
    private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();  
    private Map<String, Object> sigletons = new HashMap<String, Object>();  
 
    // 存放bean实例  
 
    public ItcastClassPathXMLApplicationContext(String filename) {  
        // 模拟内部的实现,首先要读取配置文件,可以用dom4j  
        this.readXML(filename);  
        // 读取完bean之后,Spring要对bean进行实例化,怎么实现实例化呢? 通过反射机制就很容易做到  
        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());  
                // 通过反射技术把bean都创建出来  
            } catch (Exception e) {  
                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", " 加入命名空间  
            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);  
    }  

package junit.test;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

/**
 * 传智播客版的Spring容器
 */
public class ItcastClassPathXMLApplicationContext {
 private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
 private Map<String, Object> sigletons = new HashMap<String, Object>();

 // 存放bean实例

 public ItcastClassPathXMLApplicationContext(String filename) {
  // 模拟内部的实现,首先要读取配置文件,可以用dom4j
  this.readXML(filename);
  // 读取完bean之后,Spring要对bean进行实例化,怎么实现实例化呢? 通过反射机制就很容易做到
  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());
    // 通过反射技术把bean都创建出来
   } catch (Exception e) {
    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", "

加入命名空间
   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);
 }
}


之后做下测试:看从传智播客版的容器里是否能够取到bean实例?
SpringTest.java
Java代码
package junit.test;  
 
 
import org.junit.BeforeClass;  
import org.junit.Test;  
 
import cn.itcast.service.PersonService;  
 
public class SpringTest {  
 
    @BeforeClass 
    public static void setUpBeforeClass() throws Exception {  
    }  
 
    @Test public void instanceSpring(){  
        ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml");  
        PersonService personService = (PersonService)ctx.getBean("personService");  
        personService.save();  
    }  

package junit.test;


import org.junit.BeforeClass;
import org.junit.Test;

import cn.itcast.service.PersonService;

public class SpringTest {

 @BeforeClass
 public static void setUpBeforeClass() throws Exception {
 }

 @Test public void instanceSpring(){
  ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml");
  PersonService personService = (PersonService)ctx.getBean("personService");
  personService.save();
 }
}
运行单元测试,打印结果是 
传智播客版容器:  我是save()方法
这句话是业务方法打印出来的。
在控制台里,我们通过传智播客版的Spring容器取到了bean实例,并且成功的调用了它的save方法。 这里大家就可以了解,到底Spring内部是如何创建和管理bean的,当然这只是个模拟的代码,实际中可能要处理的情况还是很复杂,这例子是为了便于大家理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值