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

spring Ioc 简单实现

2013-01-21 10:26 435 查看
地址:http://1011355643.iteye.com/blog/1772840

spring Ioc 简单实现

下面我们来实现一个最简单的Ioc,基本功能是通过SimpleClassPathXmlApplicationContext 获得 beans.xml的2个bean

shoppingDao和shoppingService ,而shoppingService中注入了shoppingDao,它调用了shoppingDao的insert()方法打印出"添加到购物车!"

以下所有代码均经过实例验证通过,复制即可,如果出现问题,100%是jar包缺失导致,请知悉

本人项目结构图



前期准备:

可以新建maven工程,pom.xml添加读取xml文件的依赖包

<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1-beta-8</version>
</dependency>


1.使用junit进行测试,输出“添加到购物车!”

public class springIocTest {

@Test
public void test() {
SimpleClassPathXmlApplicationContext sc = new SimpleClassPathXmlApplicationContext(
"beans.xml");
ShoppingService shopping = (ShoppingService) sc
.getBean("shoppingService");
shopping.addToShoppingCart();
}

}


2.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-3.0.xsd"> <bean id = "shoppingDao" class= "com.tqt.example.springIoc.ShoppingDaoImpl"></bean>
<bean id = "shoppingService" class= "com.tqt.example.springIoc.ShoppingServiceImpl">
<property name = "shoppingDao" ref = "shoppingDao"></property>
</bean>
</beans>


3.基础的ShoppingDao接口和实现方法ShoppingDaoImpl,ShoppingService和ShoppingServiceImpl

public interface ShoppingDao {
public void insert();
}

public class ShoppingDaoImpl implements ShoppingDao {

public void insert() {
//数据库操作,这里只做简单print
System.out.println("添加到购物车!");
}

}

public interface ShoppingService {
public void addToShoppingCart();
}

public class ShoppingServiceImpl implements ShoppingService{
//正常情况下使用@Autowire,现在需要get和set方法手动注入
private ShoppingDao shoppingDao;

//调用dao层方法
public void addToShoppingCart() {
getShoppingDao().insert();
}

public ShoppingDao getShoppingDao() {
return shoppingDao;
}

public void setShoppingDao(ShoppingDao shoppingDao) {
this.shoppingDao = shoppingDao;
}
}


4. pojo类PropertyRef存放bean的名字和引用。BeanDefinition存放id,完整路径的类名,属性

/**
* @author tqt
* 存放属性的对象
*/
public class PropertyRef {
private String name;
private String ref;

public PropertyRef(String name,String ref)
{
this.name = name;
this.ref = ref;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


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

/**
* @author tqt 存放xml中的bean的定义
*/
public class BeanDefinition {
private String id;
private String className;
private List<PropertyRef> propertyRef = new ArrayList<PropertyRef>();

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<PropertyRef> getPropertyRef() {
return propertyRef;
}

public void setPropertyRef(List<PropertyRef> propertyRef) {
this.propertyRef = propertyRef;
}
}


5.核心容器

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 org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

/**
* @author tqt 简易springIoc容器
*/
public class SimpleClassPathXmlApplicationContext {

// 存放bean的id、类名、属性list对象
private static List<BeanDefinition> beanDefinitionList = new ArrayList<BeanDefinition>();
// 存放id和对应的class实例
private static Map<String, Object> pojos = new HashMap<String, Object>();

/**
* @param fileName
*/
public SimpleClassPathXmlApplicationContext(String fileName) {
this.readXml(fileName);
this.instanceBeans();
this.injectObject();
}

/**
* 简单读取xml文件
* 需要dom4j,dom4j需要jaxen
* @param fileName
*/
private void readXml(String fileName) {
String id = null;
String clazz = null;
String propertyName = null;
String propertyRefNode = null;
BeanDefinition beanDefine = null;
PropertyRef propertyRef = null;

List<Element> properties = new ArrayList<Element>();

Map<String, String> nameSpaceMap = new HashMap<String, String>();
SAXReader saxReader = new SAXReader();
URL filePath = this.getClass().getClassLoader().getResource(fileName);
try {
// dom4j Document读取文档
Document doc = saxReader.read(filePath);
// 加入命名空间
nameSpaceMap.put("nameSpace", "http://www.springframework.org/schema/beans");
// dom4j xpath创建beans/bean查询路径
XPath xpath = doc.createXPath("nameSpace:beans/nameSpace:bean");
// 设置命名空间
xpath.setNamespaceURIs(nameSpaceMap);
// 获取文档下所有bean节点
List<Element> beans = xpath.selectNodes(doc);
for (Element element : beans) {
// 获取id属性值
id = element.attributeValue("id");
// 获取class属性值
clazz = element.attributeValue("class");
// 本地bean的对象
beanDefine = new BeanDefinition(id, clazz);
// 获得所有的属性
List<PropertyRef> propertyRefs = new ArrayList<PropertyRef>();
XPath propertiesX = element.createXPath("nameSpace:property");
propertiesX.setNamespaceURIs(nameSpaceMap);
properties = propertiesX.selectNodes(element);
for (Element property : properties) {
propertyName = property.attributeValue("name");
propertyRefNode = property.attributeValue("ref");
propertyRef = new PropertyRef(propertyName, propertyRefNode);
propertyRefs.add(propertyRef);
}
// 设置所有属性
beanDefine.setPropertyRef(propertyRefs);
// 添加属性到bean变量
beanDefinitionList.add(beanDefine);
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 实例化bean
*/
private void instanceBeans() {
for (BeanDefinition beanDefinition : beanDefinitionList) {
if (null != beanDefinition.getClassName()
|| "".equals(beanDefinition.getClassName().trim())) {
try {
pojos.put(beanDefinition.getId(),
Class.forName(beanDefinition.getClassName())
.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

/**
* 注入属性
*/
private void injectObject() {
for (BeanDefinition beanDefinition : beanDefinitionList) {
Object bean = pojos.get(beanDefinition.getId());
if (null != bean) {
PropertyDescriptor[] pdArray;
try {
// 使用拦截器获得指定的bean的所有属性
pdArray = Introspector.getBeanInfo(bean.getClass())
.getPropertyDescriptors();
for (PropertyRef pr : beanDefinition.getPropertyRef()) {
for (PropertyDescriptor pd : pdArray) {
// 如果找到该属性就获得setter方法并赋值
if (pr.getName().equals(pd.getName())) {
// 获取属性的setter方法
Method setter = pd.getWriteMethod();
if (null != setter) {
Object ob = pojos.get(pr.getRef());
// 访问权限设置
setter.setAccessible(true);
// 把引用对象注入到属性
setter.invoke(bean, ob);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}

}
}

}

/**
* 获得bean实例
*
* @param beanName
* @return
*/
public Object getBean(String beanName) {
return this.pojos.get(beanName);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: