Spring学习笔记(6)----编码剖析Spring依赖注入..
时间:2010-06-02 来源:mcuflower
在Spring学习笔记(3)中剖析了Spring管理Bean的原理,下面解释下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"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
- <bean id="mySqlDAO" class="com.szy.spring.dao.UserDAO4MySqlImpl"/>
- <bean id="oracleDAO" class="com.szy.spring.dao.UserDAO4OracleImpl"/>
- <bean id="userService" class="com.szy.spring.service.UserServiceImpl">
- <!--构造方法注入
- <property name="userDAO" ref="mySqlDAO"></property>
- -->
- <property name="userDAO" ref="oracleDAO"></property>
- </bean>
- </beans>
根据配置文件信息,我们首先需要建立一个Bean类,用来保存bean节点的信息:
Java代码- package com.szy.spring.bean;
- import java.util.List;
- public class Bean
- {
- private String id;
- private String className;
- private List<Property> propertyList;
- public Bean(String id, String className, List<Property> propertyList)
- {
- super();
- this.id = id;
- this.className = className;
- this.propertyList = propertyList;
- }
- 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;
- }
- public List<Property> getPropertyList()
- {
- return propertyList;
- }
- public void setPropertyList(List<Property> propertyList)
- {
- this.propertyList = propertyList;
- }
- }
此外,由于bean下存在property信息,因此我们还需要建立property类
Java代码- package com.szy.spring.bean;
- public class Property
- {
- private String name;
- private String ref;
- public Property(String name, String ref)
- {
- super();
- this.name = name;
- this.ref = ref;
- }
- public String getName()
- {
- return name;
- }
- public void setName(String name)
- {
- this.name = name;
- }
- public String getRef()
- {
- return ref;
- }
- public void setRef(String ref)
- {
- this.ref = ref;
- }
- }
在Spring学习笔记(3)中,我们在读取xml文件时bean节点下面是不存在property节点的,因此在这里我们需要修改readXML()方法:
Java代码- /**
- * 读取xml配置文件
- * @param fileName 配置文件名
- */
- private void readXML(String fileName)
- {
- // 寻找配置文件
- URL xmlPath = this.getClass().getClassLoader().getResource(fileName);
- Document doc = null;
- Element root = null;
- try
- {
- SAXBuilder sb = new SAXBuilder(false);
- doc = sb.build(new FileInputStream(new File(xmlPath.toURI())));
- // 设置命名空间
- Namespace xhtml = Namespace.getNamespace("xhtml",
- "http://www.springframework.org/schema/beans");
- root = doc.getRootElement(); // 获取根元素
- List<Element> bList = root.getChildren("bean", xhtml); //获取全部bean节点
- for (Element beanElement : bList)// 遍历节点,取得每个节点的属性
- {
- String id = beanElement.getAttributeValue("id");
- String className = beanElement.getAttributeValue("class");
- //获得每个bean下面的属性
- List<Element> pList = beanElement
- .getChildren("property", xhtml);
- List<Property> propertyList = new ArrayList<Property>(); //存储属性信息
- if (pList.size() > 0) //如果存在属性
- {
- for (Element propertyElement : pList) //遍历属性节点
- {
- String name = propertyElement.getAttributeValue("name");
- String ref = propertyElement.getAttributeValue("ref");
- Property property = new Property(name, ref);
- propertyList.add(property); //保存属性节点
- }
- }
- Bean bean = new Bean(id, className, propertyList);
- beanList.add(bean);
- }
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- }
读取完配置文件后我们还是需要对bean进行实例化的,这方法和Spring学习笔记(3)中的instanceBeans()方法一样。下面就是我们需要给bean属性进行注入,实现方法如下:
Java代码- /**
- * 为bean对象的属性注入值
- */
- public void injectObject()
- {
- for (Bean bean : beanList)
- {
- Object object = beanObject.get(bean.getId()); //获取bean的实例
- if (object != null)
- {
- try
- {
- PropertyDescriptor[] ps = Introspector.getBeanInfo(
- object.getClass()).getPropertyDescriptors(); //取得bean的属性描述
- for (Property property : bean.getPropertyList()) //获取bean节点的属性
- {
- for (PropertyDescriptor properdesc : ps)
- {
- if (property.getName().equals(properdesc.getName()))
- {
- Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private
- if (setter != null)
- {
- Object value = beanObject.get(property.getRef()); //取得值
- setter.setAccessible(true); //设置为允许访问
- setter.invoke(object, value);//把引用对象注入到属性
- }
- break;
- }
- }
- }
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- }
我们进行测试:
Java代码- MyClassPathXMLApplicationContext ctx=new MyClassPathXMLApplicationContext("applicationContext.xml");
- UserService service=(UserService)ctx.getBean("userService");
- service.show();
运行输出
结果代码- OracleDAO Implement
上面仅是简单的演示了Spring依赖注入的原理,但是在实际操作中还需要考虑很对其它因素,在此就不进行讨论了。
- spring.rar (2.8 MB)
相关阅读 更多 +