您的位置:首页 > 编程语言 > Java开发

spring控制反转与依赖注入

2009-07-19 09:01 489 查看
所用的环境 :dom4j spring 2.5.6 ,用的有:spring.jar dom4j.jar common-logging.jar

采用Junit-4对应用进行单元测试。并且采用面向接口编程(抽象出接口层)

Spring的配置文件: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-2.5.xsd">
<!--实例化bean,实现控制反转,即由spirng容器负责创建对象-->

<bean id="personService" class="com.sgl.imp.PersonServiceBean" ></bean>

<!--通过set方法进行依赖注入-->

<bean id="daoPerson" class="com.sgl.dao.imp.PersonDaoBean"></bean>

<bean id="personService4" class="com.sgl.imp.PersonServiceBean">

<property name="personDao" ref="daoPerson"></property>

</bean>

</beans>

所用到java源文件如下 :

1、自定义应用上下文(核心)

package sgl.spring.principle;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.lang.reflect.Method;

import java.net.URL;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.logging.Level;

import java.util.logging.Logger;

import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.XPath;

import org.dom4j.io.SAXReader;

/**

*

* @author administrator

*/

public class SglClassPathXmlApplicationContext {

private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();//存放所有的bean实例

private Map<String, Object> sinletons = new HashMap<String, Object>();//存放bean与之相关联的类实例的映射

public SglClassPathXmlApplicationContext(String fileName) {

this.readXml(fileName);

this.instanceBeans();

this.injectObject();

}

/**

* 读取xml配置文件

* @param fileName 配置文件名

*/

private void readXml(String fileName) {

SAXReader saxReader = new SAXReader();

Document document = null;

URL xmlPath = this.getClass().getClassLoader().getResource(fileName);

try {

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");//获取bean 的id属性

String className = element.attributeValue("class");//获取bean的class属性

XPath propertyPath = element.createXPath("ns:property");//创建bean/property查询路径

propertyPath.setNamespaceURIs(nsMap);//设置命名空间和根元素一致

List<Element> propertys = propertyPath.selectNodes(element);//取得element(即bean)下所有property

BeanDefinition beanDefine = new BeanDefinition(id, className);//实例化一个bean

//设置property的属性,因为可能有多个property,所以用循环

for (Element property : propertys) {

String name = property.attributeValue("name");//获得property的name属性

String ref = property.attributeValue("ref");//获得property的ref属性

System.out.println("" + name + " " + ref);

PropertyDefinition propertyDefine = new PropertyDefinition(name, ref);

beanDefine.getPropertys().add(propertyDefine);

}

beanDefines.add(beanDefine);//将bean实例加入数组中

}

} catch (Exception ex) {

Logger.getLogger(SglClassPathXmlApplicationContext.class.getName()).log(Level.SEVERE, null, ex);

}

}

/**

* 完成bean实例化

*/

private void instanceBeans() {

System.out.println("实例化开始");

for (BeanDefinition beanDefine : beanDefines) {

if (beanDefine.getClassName() != null && !"".equals(beanDefine.getClassName().trim())) {

try {

//利用java反射技术来取得java类实例

System.out.println("beanID " + beanDefine.getId());

sinletons.put(beanDefine.getId(), Class.forName(beanDefine.getClassName()).newInstance());

} catch (Exception ex) {

Logger.getLogger(SglClassPathXmlApplicationContext.class.getName()).log(Level.SEVERE, null, ex);

}

}

}

System.out.println("实例化结束");

}

/**

* 获取bean实例

* @param beanName

* @return

*/

public Object getBean(String beanName) {

return this.sinletons.get(beanName);

}

private void injectObject() {

for (BeanDefinition beanDefine : beanDefines) {//遍历所有的<bean>,因为所有的<bean>右能都有property属性

Object bean = getBean(beanDefine.getId());//由bean的id,取得bean实例

if (bean != null) {

try {

//如果从<property>中取出的属性(存储在name字段中)在<bean>所对应类的属性(字段),也就是说我们一定人保证

//<property name="属性"………………>中的“属性”在<bean>所指向类中有对应的定义

//取得bean对应类的所有属性的描述(即bean类定义的所有字段)

PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();

for (PropertyDefinition property : beanDefine.getPropertys()) {//一个bean可以有多个<property>

//PropertyDescriptor中有很多字段,找出与<property name="属性">所对应的字段

for (PropertyDescriptor propertyDes : ps) {//propertyDes是<bean>所指向类的定义字段的描述

System.out.println("ps "+propertyDes.getName());

//如果property的name字段在<bean>有对应字段的定义,就进行注入

if (property.getName().equals(propertyDes.getName())) {

//根据propety中的ref属性进行依赖

//取得当前bean类的property属性的name属性对应值的属性(在此指personDao)setter方法

Method setter = propertyDes.getWriteMethod();

//取得ref对应类实例

if (setter != null) {

Object value = sinletons.get(property.getRef());

setter.setAccessible(true);//让私有方法变得透明

setter.invoke(bean, value);

}

break;//找到对应属性,其它的属性不用比较

}

}

}

} catch (Exception ex) {

Logger.getLogger(SglClassPathXmlApplicationContext.class.getName()).log(Level.SEVERE, null, ex);

}

}

}

}

}

2、PersonDao.java(接口程序)

package com.sgl.dao;

public interface PersonDao {

void add();

}

3、PersonDaoBean.java(接口层实现程序)

package com.sgl.dao.imp;

import com.sgl.dao.PersonDao;

public class PersonDaoBean implements PersonDao {

public void add(){

System.out.println("执行PersonDaoBean中add()方法");

}

}

4、 PersonService.java(业务层接口)

package com.sgl;

public interface PersonService {

void save();

void save2();

}

5、PersonServiceBean.java(业务层实现程序)

package com.sgl.imp;

import com.sgl.PersonService;

import com.sgl.dao.PersonDao;

public class PersonServiceBean implements PersonService {

private PersonDao personDao;

public void save(){

System.out.println("我是PersonServiceBean中的save()方法");

personDao.add();

}

public void save2(){

System.out.println("这是PersonServiceBean中的Save2方法");

}

public void setPersonDao(PersonDao personDao) {

this.personDao = personDao;

}

}

6配置文件中,对应属性的类封装( id、class、property)

1)、BeanDefinition.java

package sgl.spring.principle;

import java.util.ArrayList;

import java.util.List;

public class BeanDefinition {

private String id;

private String className;

private List<PropertyDefinition> propertys=new ArrayList<PropertyDefinition>();

public BeanDefinition() {

}

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;

}

public List<PropertyDefinition> getPropertys() {

return propertys;

}

public void setPropertys(List<PropertyDefinition> propertys) {

this.propertys = propertys;

}

}

2)、PropertyDefinition.java(<property>的定义)

package sgl.spring.principle;

public class PropertyDefinition {

private String name;

private String ref;

public PropertyDefinition(String name, String ref) {

this.name = name;

this.ref = ref;

}

public PropertyDefinition() {

}

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;

}

}

7、单元测试类文件 SglSpringTest.java,是junit-4.x

package junit.test;

import com.sgl.PersonService;

import org.junit.After;

import org.junit.AfterClass;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

import sgl.spring.principle.SglClassPathXmlApplicationContext;

public class SglSpringTest {

public SglSpringTest() {

}

@BeforeClass

public static void setUpClass() throws Exception {

}

@AfterClass

public static void tearDownClass() throws Exception {

}

@Before

public void setUp() {

}

@After

public void tearDown() {

}

@Test

public void instanceBeans() {

SglClassPathXmlApplicationContext ctx=new SglClassPathXmlApplicationContext("beans.xml");

//测试控制反转,即由容器创建对象

PersonService personService=(PersonService)ctx.getBean("personService");

personService.save2();

//测试控制反转和依赖注入

PersonService personService4=(PersonService)ctx.getBean("personService4");

personService4.save();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: