• 编码剖析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实例的.

  • 相关阅读:
    JS判断浏览器类型及版本
    php函数ob_start()、ob_end_clean()、ob_get_contents()
    HTML-embed标签详解
    QQ一键登录功能的实现过程
    windows 7系统搭建本地SVN服务器的过程
    php 环境工具官网地址
    yii2 auth access-token
    使用Yii2时遇到的实际问题
    PHPExcel正确读取excel表格时间单元格(转载)
    持续集成 Jenkins
  • 原文地址:https://www.cnblogs.com/zbdouble/p/9142151.html
Copyright © 2020-2023  润新知