传智播客Spring2.5视频教程_编码剖析Spring依赖注入的原理 1

成对出标色的地方  是保持一致的 

<bean id="pesonDaoId" class="six.spring.service.impl.PersonDaoBean"></bean>
    <bean id="personService"
        class="six.spring.service.impl.PersonServiceBean" lazy-init="true">
        <property name="personDaoBean" ref="pesonDaoId"></property>
    </bean>

///

package six.spring.service.impl;

import six.spring.service.PersonDao;
import six.spring.service.PersonService;

public class PersonServiceBean implements PersonService {
 private PersonDao personDaoBean;

 public void savePerson() {
  System.out.println("我是包[six.spring.service.impl]的"
    + "类[PersonService]的[savePerson]方法");
  this.personDaoBean.add();
 }

 public PersonDao getPersonDaoBean() {
  return personDaoBean;
 }

 // 通过属性注入依赖对象的时候 必须给属性设置set方法
 public void setPersonDaoBean(PersonDao personDaoBean) {
  this.personDaoBean = personDaoBean;
 }
}

///

以下传智播客Spring2.5视频教程_编码剖析Spring依赖注入的原理

 

老师只是讲了 具体实现 老师的实现  是 [万事万物皆对象]的一个小体现

 

从要解析的xml文件开始

<bean id="pesonDaoId" class="six.spring.service.impl.PersonDaoBean"></bean>
 <bean id="personService"class="six.spring.service.impl.PersonServiceBean" lazy-init="true">
        <property name="personDaoBeanAA" ref="pesonDaoId"></property>

        <property name="personDaoBeanBB" ref="pesonDaoId"></property>
 </bean>

 

看看,什么是对象? 万事万物皆对象 需求心中留

什么是需求呢? 解析xml 文件 ,得到反射的必要信息,

通过反射,实例化对象,在通过set 方法注入。

很明显了 一个元素 就是一个对象了

property对象 属性 name ref

bean 对象 属性 id class list<property>

/

package six.spring.application.beandefinition;

import java.util.ArrayList;
import java.util.List;

public class BeanDefinition {

    private String id;
    private String className;
    private List<PropertyBeanDefinition> propertys = new ArrayList<PropertyBeanDefinition>();

    // 将解析xml文件后的 结果 ,通过构造方法 实例化对象

    // 构造方法里 不需要初始化被注如的属性

   // 将List<PropertyBeanDefinition> propertys组装完毕后

   //  通过set 方法设置
    public  BeanDefinition(String id, String clazz) {
        this.id = id;
        this.className = clazz;
    }

省去set get 方法

/

ackage six.spring.application.beandefinition;

public class PropertyBeanDefinition {

    private String name;
    private String href;
    public PropertyBeanDefinition(String name,String href) {
        this.name = name;
        this.href = href;
       
    }

省去set get 方法

/

ackage six.spring.application;

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;

import six.spring.application.beandefinition.BeanDefinition;
import six.spring.application.beandefinition.PropertyBeanDefinition;

public class ClassPathXMLApplicationContext {

    private List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();
    private Map<String, Object> objsMap = new HashMap<String, Object>();

    public ClassPathXMLApplicationContext(String fileName)
            throws ClassNotFoundException {
        this.readXML(fileName);
        this.instanceBeans();
    }

  
    private void instanceBeans() {
        // 利用反射 生成对象
        for (BeanDefinition beanDefinition : beanDefinitions) {
            String className = beanDefinition.getClassName();
            if (className != null && !"".equals(className.trim())) {
                try {
                    // Class.forName(xxx.xx.xx) 返回的是一个类,
                    // newInstance() 后才创建一个对象
                    // Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类
                    // ,也就是说JVM会执行该类的静态代码段
                    Object object = Class.forName(className).newInstance();
                    objsMap.put(beanDefinition.getId(), object);
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void readXML(String fileName) {
       
        SAXReader saxReader = new SAXReader();
        Document document = null;
        try {
            System.out.println(fileName);
            URL xmlPath = this.getClass().getClassLoader().getResource(fileName);
            System.out.println(xmlPath);
            document = saxReader.read(xmlPath);
            Map<String, String> nsMap = new HashMap<String, String>();

            // 加入命名空间
            nsMap.put("ns", "http://www.springframework.org/schema/beans");

            // 创建beans/bean查询路径 注意 查询路径的写法
            XPath xPath = document.createXPath("//ns:beans/ns:bean");

            // 设置命名空间
            xPath.setNamespaceURIs(nsMap);

            //取得根元素下的所有节点
            List<Element> beans = xPath.selectNodes(document);
            for (Element element : beans) {
                String id = element.attributeValue("id");
                String clazz = element.attributeValue("class");
                BeanDefinition beanDefinition = new BeanDefinition(id, clazz);

                //  查找bean 接点的子接点property 不需要 带根路径
                XPath xPathBeanDefinition = element.createXPath("ns:property");

                // 设置命名空间
                xPathBeanDefinition.setNamespaceURIs(nsMap);

                //取得[Element]元素下的所有 节点 查找bean 接点的子接点property 
                List<Element> propertyBeans = xPathBeanDefinition.selectNodes(element);
                for (Element propertyBean : propertyBeans) {

                    String name = propertyBean.attributeValue("name");
                    String ref = propertyBean.attributeValue("ref");
                   
                    PropertyBeanDefinition propertyDefination = new PropertyBeanDefinition(name, ref);
                    beanDefinition.getPropertys().add(propertyDefination);
                }
                beanDefinitions.add(beanDefinition);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
///

ackage six.spring.junit;

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

import six.spring.application.ClassPathXMLApplicationContext;

public class SpringTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }
    @Test
    public void instanceSpring()  {
       
        try {
            ClassPathXMLApplicationContext ctx = new ClassPathXMLApplicationContext("six/spring/junit/sixbeans.xml");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
///

 

ackage six.spring.junit;

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

import six.spring.application.ClassPathXMLApplicationContext;

public class SpringTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }
    @Test
    public void instanceSpring()  {
       
        try {
            ClassPathXMLApplicationContext ctx = new ClassPathXMLApplicationContext("six/spring/junit/sixbeans.xml");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

///

调试 过程 出现了一个bug

            ClassPathXMLApplicationContext ctx = new ClassPathXMLApplicationContext("/six/spring/junit/sixbeans.xml");

异常信息

java.lang.NullPointerException
/six/spring/junit/sixbeans.xml
null
    at org.dom4j.io.SAXReader.read(SAXReader.java:284)
    at six.spring.application.ClassPathXMLApplicationContext.readXML(ClassPathXMLApplicationContext.java:55)
    at six.spring.application.ClassPathXMLApplicationContext.<init>(ClassPathXMLApplicationContext.java:24)
    at six.spring.junit.SpringTest.instanceSpring(SpringTest.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
    at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
    at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
    at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
    at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
    at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66)
    at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
    at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
    at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
    at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

/


null

发生异常的 位置

package six.spring.application;

            System.out.println(fileName);  // fileName = /six/spring/junit/sixbeans.xml 
            URL xmlPath = this.getClass().getClassLoader().getResource(fileName); //  URL = null
如果 fileName 是 six/spring/junit/sixbeans.xml  的话 就没有问题了。

因为 根目录 this.getClass().getClassLoader() 得到根目录 就是 存放class 的 bin 目录 

涉及到的知识点 我 在下一篇 《getClass().getClassLoader().getResource(path) 相关》 写一些 自己查到的

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值