1,依赖注入的实现代码
package junit.test;
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 joeho.vo.BeanDefinition;
import joeho.vo.PropertyDefinition;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
public class JoehoaClassPathXMLApplicationContext {
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
private Map<String,Object> singeton = new HashMap<String,Object>();
public JoehoaClassPathXMLApplicationContext(String xmlName) {
this.readXml(xmlName);
this.instanceBeans();
this.injectObject();
}
/**
* 读XML文件
* @param xmlName
*/
private void readXml(String xmlName) {
SAXReader saxReader = new SAXReader();
Document document = null;
try {
URL xmlPath = this.getClass().getClassLoader().getResource(xmlName);
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> list = xsub.selectNodes(document);//获取文档下的所有BEAN节点
for(Element element:list){
String id = element.attributeValue("id");//获取ID属性值
String classzz = element.attributeValue("class");//获取class属性值
BeanDefinition beanDefin = new BeanDefinition(id,classzz);
XPath xsubproperty = element.createXPath("ns:property");//创建bean/property的查询路径
xsubproperty.setNamespaceURIs(nsMap);//设置命名空间
List<Element> propertys = xsubproperty.selectNodes(element);//获取文档下的所有property节点
for(Element property:propertys){
String propertyname = property.attributeValue("name");
String propertyref = property.attributeValue("ref");
PropertyDefinition propertyBean = new PropertyDefinition(propertyname,propertyref);
beanDefin.getPropertys().add(propertyBean);
}
beanDefines.add(beanDefin);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 完成bean的实例化
*/
private void instanceBeans() {
for(BeanDefinition beans:beanDefines){
try {
if(beans.getClasszz()!=null&&!"".equals(beans.getClasszz().trim())){
singeton.put(beans.getId(), Class.forName(beans.getClasszz()).newInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 为bean的属性注入值
* 注入的原理
*/
private void injectObject() {
for(BeanDefinition beanDefine:beanDefines ){
Object bean = singeton.get(beanDefine.getId());//获取实例对象
if(bean!=null){
try {
PropertyDescriptor[] beanProperty = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDefinition propertyDefini:beanDefine.getPropertys()){
//获取property的所有属性,并和beanProperty中的属性进行比较
for(PropertyDescriptor propertyDes:beanProperty){
if(propertyDefini.getName().equals(propertyDes.getName())){
Method setter =propertyDes.getWriteMethod();//获取属性的setter方法
if(setter!=null){
Object value = singeton.get(propertyDefini.getRef());//从容器中取得XML中的ref对象
setter.setAccessible(true);//可能为私有的则不能访问,为了能访问设置为TRUE
setter.invoke(bean, value);//把引用对象注入到属性
}
break;
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 获取Bean实例
* @param beanName
* @return
*/
public Object getBean(String beanName){
return singeton.get(beanName);
}
}
2,引用的BEAN对象
package joeho.vo;
import java.util.ArrayList;
import java.util.List;
public class BeanDefinition {
private String id;
private String classzz;
private List<PropertyDefinition> propertys = new ArrayList<PropertyDefinition>();
public BeanDefinition(String id, String classzz) {
this.id = id;
this.classzz = classzz;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClasszz() {
return classzz;
}
public List<PropertyDefinition> getPropertys() {
return propertys;
}
public void setPropertys(List<PropertyDefinition> propertys) {
this.propertys = propertys;
}
public void setClasszz(String classzz) {
this.classzz = classzz;
}
}
package joeho.vo;
public class PropertyDefinition {
private String name;
private String ref;
public PropertyDefinition(String name, String ref) {
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;
}
}
3,解析的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 service -->
<bean id="personservice" class="joeho.blog.service.impl.PersonServiceBean" destroy-method="delete" >
<!-- 此处的name属性填的是service类中setter的属性值,ref引用的是bean dao中的对象,此处将ref中的对象注入到属性中来 -->
<property name="personDao" ref="personDao"></property>
</bean>
<bean id="personservice1" class="joeho.blog.service.impl.PersonServiceBeanFactory" factory-method="createPersonServiceBean1"/>
<bean id="PersonServiceBeanFactory" class="joeho.blog.service.impl.PersonServiceBeanFactory" />
<bean id="personservice2" factory-bean="PersonServiceBeanFactory" factory-method="createPersonServiceBean2"></bean>
<!-- bean dao -->
<bean id="personDao" class="joeho.blog.dao.impl.PersonDaoBean"></bean>
</beans>
4,JUNIT测试代码
package junit.test;
import joeho.blog.service.PersonService;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void instanceSpring(){
/* AbstractApplicationContext act = new ClassPathXmlApplicationContext("Beans.xml");
PersonService ps=(PersonService)act.getBean("personservice");
PersonService ps1=(PersonService)act.getBean("personservice1");
System.out.println(ps==ps1);
ps.save();
act.close();*/
JoehoaClassPathXMLApplicationContext act = new JoehoaClassPathXMLApplicationContext("Beans.xml");
PersonService ps=(PersonService)act.getBean("personservice");
ps.save();
}
}