编码剖析Spring管理Bean的原理

在Spring的第一个案例中,我们已经知道了怎么将bean交给Spring容器进行管理,并且明白了怎么从Spring容器中获取bean。那我们就有一个疑问了:Spring是如何创建并管理bean的呢?现在我们就来编码剖析Spring管理Bean的原理。

本文是在Spring的第一个案例的基础上展开的。

我们要使用dom4j读取Sping的配置文件——beans.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.xsd">

    <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>

</beans>

那么就需要将dom4j所需的jar包导入该项目中。dom4j所需的jar包为:

  • dom4j-1.6.1.jar
  • jaxen-1.1-beta-6.jar

dom4j读取到诸如

<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>

这样的内容时,务必需要将读取到的bean的信息存到一个JavaBean对象中。于是我们可在junit.test包下创建这样一个JavaBean——BeanDefinition.java,其代码为:

/**
 * 将读取到的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;
    }
}

接下来我们就创建一个传智播客版的Spring容器来模拟Spring容器。在junit.test下新建一个类——ItcastClassPathXMLApplicationContext.java,其代码如下:

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

    public ItcastClassPathXMLApplicationContext(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) {
                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);
    }
}

这样,传智播客版的Spring容器就创建出来了。接下来我们就要测试传智播客版的Spring容器是否能够取得bean实例,只须修改SpringTest类的代码为:

public class SpringTest {

    @Test
    public void test() {
        // ApplicationContext是接口
        // ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); // 实例化Spring容器
        // PersonService personService = (PersonService) ctx.getBean("personService"); // 从Spring容器取得bean
        // personService.save();

        ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml"); // 实例化Spring容器
        PersonService personService = (PersonService) ctx.getBean("personService"); // 从Spring容器取得bean
        personService.save();
    }

}

测试test()方法,Eclipse控制台打印如下:

通过编写代码剖析Spring管理Bean的原理,我们就能深刻理解Spring内部到底是如何创建并管理bean实例的.

原文地址:https://www.cnblogs.com/zbdouble/p/9142151.html

时间: 2024-10-07 03:04:15

编码剖析Spring管理Bean的原理的相关文章

深入探索spring技术内幕(二): 剖析spring管理Bean的原理与配置

求二叉树的宽度和深度 给定一个二叉树,获取该二叉树的宽度和深度. 例如输入 a / \ b c / \ / \ d e f g 返回3. 详细描述: 接口说明 原型: int GetBiNodeInfo(BiNode &head, unsigned int *pulWidth, unsigned int *pulHeight) 输入参数: head 需要获取深度的二叉树头结点 输出参数(指针指向的内存区域保证有效): pulWidth 宽度 pulHeight 高度 返回值: 0 成功 1 失败

编码剖析Spring依赖注入的原理

Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中. Spring的依赖注入有两种方式: 通过构造器参数,让容器把创建好的依赖对象注入. 使用setter方法进行注入. 现在我们使用第二种方式进行依赖注入.以Spring管理的Bean的生命周期的案例为基础展开本文的说明. 首先在src目录下新建一个cn.itcast.dao包,并在该包下新建一个接口——PersonDao.java,其代码为: public interface Pers

编码剖析Spring装配基本属性的原理

上回我们已经讲到了Spring依赖注入的第一种方式,现在我们来详解第二种方式,须知这一切都是以编码剖析Spring依赖注入的原理案例为基础的. 我们将Spring的配置文件——beans.xml的内容改为: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=&quo

采用Spring管理Bean和依赖注入

1.实例化spring容器 和 从容器获取Bean目标 实例化Spring容器常用的两种办法: 办法一: 在类途径下寻觅配置文件来实例化容器 [引荐运用] ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"}); 办法二: 在文件体系途径下寻觅配置文件来实例化容器 [这种办法能够在开发期间运用] ApplicationContext ctx = new FileSyst

反射-Spring管理Bean,注入Bean属性的反射机制。

#反射 1.是JAVA API,是Java提供的现成的类!! --接受API提供的功能! 2. 是Java提供的动态执行机制,动态加载类,动态创建对象,动态访问属性,动态调用方法. ##反射用途 1. eclipse 中解析类的结构使用了反射 2.JUnit识别被测试方法使用了反射 -- JUnit3 利用了反射查找test开头的方法 -- JUnit4 利用了反射解析@Test查找测试方法 3.Spring 管理Bean对象,注入Bean属性使用了反射 --利用反射创建Bean对象实例 --利

【Sping管理bean的原理】

spring容器默认情况下,当服务启动时,解析配置文件,实例化文件中的所有类. 我们直接使用spring时,获取spring注入的bean是这样的, ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); MyService myService1 = (MyService) ctx.getBean("myService"); 那下面我们模拟spring管理bean这个的过程

Spring学习笔记——Sprin管理Bean的原理

当我们使用Spring时候在Xml文件中通过 <bean id="service" class="com.finance.service.AmountServiceImpl" /> 配置就可以操作该Bean的属性和方法,那么Spring到底是如何实现的呢?下面让我们自己实现这个过程. 首先我模拟Spring的命名方式创建一个Bean管理类MyClassPathXMLApplicationContext.java,代码如下: // 自定义容器 public

Spring(八)编码剖析@Resource注解的实现原理

beans2.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" xmlns:context="http://www.springframew

Spring2.5学习2.2_编码剖析Spring依赖注入原理

为了便于理解Spring属性注入,这里来模拟Spring容器是如何实现将PersonDaoBean注入到PersonServiceBean的. 所需jar包:下载地址http://download.csdn.net/detail/jeofey/8747927 PersonDaoBean.java [java] view plaincopy package xjj.dao.impl; import xjj.dao.PersonDao; public class PersonDaoBean impl