zoukankan      html  css  js  c++  java
  • 【Sping管理bean的原理】

    spring容器默认情况下,当服务启动时,解析配置文件,实例化文件中的所有类。

    我们直接使用spring时,获取spring注入的bean是这样的,        

    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");

                  MyService myService1 = (MyService) ctx.getBean("myService");

    那下面我们模拟spring管理bean这个的过程,代码如下

    1.         第一步,创建Java project,引入spring.jar

    2.         创建spring.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">

     

    </beans>

    3.         创建接口MyService,只需要一个测试方法save

    4.         创建实现类MyServiceImpl,控制台输出一句话

    5.         创建一个自己的解析类MyClassPathXmlApplicationContext

    主要是构造方法中的两步

      1     // 装载实例化bean
      2 
      3        private Map<String, Object> beanMap = new HashMap<String, Object>();
      4 
      5        // 装载配置文件的属性和值
      6 
      7        private List<MyBeans> beanlist = new ArrayList<MyBeans>();
      8 
      9       
     10 
     11        public MyClassPathXmlApplicationContext(String filename) {
     12 
     13               //第一步,解析spring配置文件
     14 
     15               readXml(filename);
     16 
     17               //第二步,通过反射,实例化所有注入bean
     18 
     19               initBeans();
     20 
     21        }
     22 
     23  
     24 
     25        /**
     26 
     27         * 通过反射机制,初始化配置文件中的bean
     28 
     29         */
     30 
     31        private void initBeans() {
     32 
     33               for (MyBeans bean : beanlist) {
     34 
     35                      try {
     36 
     37                             if (bean.getClassName() != null && !"".equals(bean.getClassName())) {
     38 
     39                                    beanMap.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
     40 
     41                             }
     42 
     43                      } catch (Exception e) {
     44 
     45                             e.printStackTrace();
     46 
     47                      }
     48 
     49               }
     50 
     51        }
     52 
     53  
     54 
     55        /**
     56 
     57         * 解析配置文件,把解析后的bean设置到实体中,并保持到list
     58 
     59         *
     60 
     61         * @param filename
     62 
     63         */
     64 
     65        private void readXml(String filename) {
     66 
     67               SAXReader reader = new SAXReader();
     68 
     69  
     70 
     71               Document doc = null;
     72 
     73               URL xmlpath = this.getClass().getClassLoader().getResource(filename);
     74 
     75               try {
     76 
     77                      Map<String, String> nsMap = new HashMap<String, String>();
     78 
     79                      nsMap.put("ns", "http://www.springframework.org/schema/beans");
     80 
     81                      doc = reader.read(xmlpath);
     82 
     83                      XPath xpath = doc.createXPath("//ns:beans//ns:bean");// 创建//ns:beans//ns:bean查询路径
     84 
     85                      xpath.setNamespaceURIs(nsMap);// 设置命名空间
     86 
     87                      List<Element> eles = xpath.selectNodes(doc);// 取得文档下所有节点
     88 
     89                      for (Element element : eles) {
     90 
     91                             String id = element.attributeValue("id");
     92 
     93                             String cn = element.attributeValue("class");
     94 
     95                             //自定义实体bean,保存配置文件中id和class
     96 
     97                             MyBeans beans = new MyBeans(id, cn);
     98 
     99                             beanlist.add(beans);
    100 
    101                      }
    102 
    103               } catch (Exception e) {
    104 
    105                      e.printStackTrace();
    106 
    107               }
    108 
    109  
    110 
    111        }
    112 
    113  
    114 
    115        public Object getBean(String beanId) {
    116 
    117               return beanMap.get(beanId);
    118 
    119        }
    120 
    121  
    122 
    123 6.         实体类
    124 
    125  
    126 
    127 package com.mooing.service;
    128 
    129  
    130 
    131 public class MyBeans {
    132 
    133        private String id;
    134 
    135        private String className;
    136 
    137  
    138 
    139        public MyBeans(String id, String className) {
    140 
    141               this.id = id;
    142 
    143               this.className = className;
    144 
    145        }
    146 
    147  
    148 
    149        public String getId() {
    150 
    151               return id;
    152 
    153        }
    154 
    155  
    156 
    157        public void setId(String id) {
    158 
    159               this.id = id;
    160 
    161        }
    162 
    163  
    164 
    165        public String getClassName() {
    166 
    167               return className;
    168 
    169        }
    170 
    171  
    172 
    173        public void setClassName(String className) {
    174 
    175               this.className = className;
    176 
    177        }
    178 
    179 }

    7.         测试

    1       MyClassPathXmlApplicationContext ctx = new MyClassPathXmlApplicationContext("spring.xml");
    2 
    3               MyService myService = (MyService) ctx.getBean("myService");
    4 
    5                myService.save();
    6 
    7  

    总结:

    自定义代码同样可以得到使用spring容器实例化的效果,也就是说,实际spring实例化管理bean时,也是经过两大步:第一,服务启动解析配置文件,并保存配置文件中的元素;第二,实例化所有元素,并提供获取实例方法。

  • 相关阅读:
    Ajax组件(wagang版)
    动画组件(wagang版)之基础篇:跳帧与延时
    Ajax组件(wagang版)之无依赖化
    ✍23 postgresql批量删除表
    ✍20 samba共享服务
    ✍16 asyncio异步IO
    ✍19 Tensonfow(GPU)使用
    ✍25 mysqlclient 安装(linux,mac)
    ✍17 aiohttp模块的使用
    ✍18 Linnux上安装node.js
  • 原文地址:https://www.cnblogs.com/yangjian-java/p/6933647.html
Copyright © 2011-2022 走看看