Spring的DI(Ioc) - 注入bean 和 基本数据类型

注入bean有两种方式:

注入其他bean:
方式一
<bean id="orderDao" class="cn.itcast.service.OrderDaoBean"/>
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
	<property name="orderDao" ref="orderDao"/>
</bean>
方式二(使用内部bean,但该bean不能被其他bean使用)
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
	<property name="orderDao">
		<bean class="cn.itcast.service.OrderDaoBean"/>
	</property>
</bean>

  

一般我们的工程在service层依赖dao层的实现来实现业务逻辑。

service层:

public class PersonServiceImpl implements PersonService {
	
	private PersonDao personDao;
	
	@Override
	public void save() {
		personDao.save();
		System.out.println("service :  " + " save 方法");
	}
	public PersonDao getPersonDao() {
		return personDao;
	}
	public void setPersonDao(PersonDao personDao) {
		this.personDao = personDao;
	}
}

  

dao层:

public class PersonDaoImpl implements PersonDao {
	@Override
	public void save() {
		System.out.println("dao层的save方法");
	}
}

  

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 id="personDaoImpl" class="cn.gbx.dao.PersonDaoImpl"></bean>
 	<bean id="personServiceImpl" class="cn.gbx.serviceimpl.PersonServiceImpl" >
 		<property name="personDao" ref="personDaoImpl"></property>
 	</bean>
</beans>

  

测试方法:

public class SpringTest {
	@Test
	public void spring1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		PersonService ps = (PersonService)ctx.getBean("personServiceImpl");
		ps.save();
	}
}

  

然后我们就实现了Spring对bean对象的依赖注入。 service层所依赖的dao层的PersonDao对象不是由service本身去创建管理,而是交给了第三方容器Spring去管理。

那么Spring是如何管理的呢?

我们可想而知

1: 首先必须解析XML 将 <bean>标签和 <property>标签都解析出来

2: 利用反射实例话对象

3: 利用内省将实例化完成的对象注入到有依赖的对象里面

 

我们可以自己模拟实现:

package cn.gbx.myExample;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
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.apache.commons.beanutils.ConvertUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

public class MyClassPathXmlApplicationContext {

	private List<DefBean> defBeans = new ArrayList<DefBean>();  //存储<bean>标签的信息
	private Map<String, Object> singltons = new HashMap<String, Object>(); //存储读出来的对象
	
	
	public MyClassPathXmlApplicationContext() {
		super();
	}

	public MyClassPathXmlApplicationContext(String filename) {
		this.readXML(filename);
		this.instanceBean();
		this.injectProperty();
	}
	//利用内省将属性注入
	private void injectProperty() {
		for (DefBean defBean : defBeans) {
			Object bean = singltons.get(defBean.getId());
			if (bean != null) {
				//要想将依赖的对象注入,我们就要通过内省来操作对象的属性
				try {
					BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
					PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();
				
					for (DefProperty p : defBean.getDefPropertys()) {
						for (PropertyDescriptor propertyDes : ps) {
							if (propertyDes.getName().equals(p.getName())) {
								Method setter = propertyDes.getWriteMethod();
								if (setter != null) {
									Object value = null;
									if (p.getRef() != null && !"".equals(p.getRef())) {
										value = singltons.get(p.getRef());
									} else { //基本数据类型利用beanUtils实现转化
										value = ConvertUtils.convert(p.getValue(),propertyDes.getPropertyType());
									}
									setter.setAccessible(true); //这样即使set方法是私有的都可以访问
									setter.invoke(bean, value); //把引用对象注入到bean属性里面
								}
								break;
							}
						}
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
    //利用反射实例化对象
	private void instanceBean() {
		for (DefBean bean : defBeans) {
			//输出测试读取的xml
			/*System.out.println(bean.getId() + "  : " + bean.getClassName());
			System.out.println("------------------------");
			for (DefProperty p : bean.getDefPropertys()) {
				System.out.println("Property : name = " + p.getName() + "  :  ref = " + p.getRef());
			}
			*/
			
			if (bean.getClassName() != null && !"".equals(bean.getClassName())) {
				try {
					singltons.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void readXML(String filename) {
		SAXReader reader = new SAXReader();
		Document document = null;
		URL xmlPath = this.getClass().getClassLoader().getResource(filename);
		try {
			document = reader.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");
			xsub.setNamespaceURIs(nsMap); // 设置命名空间
			
			List<Element> elements = xsub.selectNodes(document);
			
			DefBean defBean = null;
			for (Element e : elements) {
				String id = e.attributeValue("id");
				String className = e.attributeValue("class");
				defBean = new DefBean(id, className);
				
				//为<bean>节点设置查询路径
				XPath xPropertySub = e.createXPath("ns:property");
				xPropertySub.setNamespaceURIs(nsMap);
				List<Element> propertys =  xPropertySub.selectNodes(e);
				
				DefProperty defProperty = null;
				for (Element e2 : propertys) {
					String name = e2.attributeValue("name");
					String ref = e2.attributeValue("ref");
					String value = e2.attributeValue("value");
					defProperty = new DefProperty(name, ref, value);
					defBean.getDefPropertys().add(defProperty);
				}
				
				defBeans.add(defBean);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	public Object getBean(String key) {
		return singltons.get(key);
	}
	
	
}

  

<?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 id="personDaoImpl" class="cn.gbx.dao.PersonDaoImpl"></bean>
 	<bean id="personServiceImpl" class="cn.gbx.serviceimpl.PersonServiceImpl" >
 		<property name="personDao" ref="personDaoImpl"></property>
 		<property name="name" value="ok-gbx"></property>
 		<property name="id" value="22"></property>
 	</bean>
</beans>

  

 

posted @ 2014-02-20 20:37  E_star  阅读(1267)  评论(0编辑  收藏  举报