首先看下Java项目结构图:
Apple.java文件内容:
package com.rain.po;
/**
* 苹果.
*/
public class Apple implements Fruit {
/**
* 水果名称.
*/
private String name;
/**
* 苹果构造器.
*/
public Apple() {
super();
this.name = "红富士";
}
/**
* 设置苹果名称.
* @param name 苹果名称.
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取苹果名称.
* @return 苹果名称.
*/
public String getName() {
return name;
}
}
Fruit.java文件内容:
package com.rain.po;
/**
* 水果接口.
*/
public interface Fruit {
/**
* 获取水果名称.
* @return 水果名称.
*/
String getName();
}
Shop.java文件内容:
package com.rain.po;
/**
* 商店.
*/
public class Shop {
/**
* 水果.
*/
private Fruit fruit;
/**
* 无参构造器.
*/
public Shop() {
super();
}
/**
* 有参构造器.
* @param fruit 水果.
*/
public Shop(Fruit fruit) {
super();
this.fruit = fruit;
}
/**
* 设置水果.
* @return 水果.
*/
public Fruit getFruit() {
return fruit;
}
/**
* 获取水果.
* @param fruit 水果.
*/
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
}
BeanDefinition.java文件内容:
package com.rain.spring.util;
import java.util.ArrayList;
import java.util.List;
/**
* Bean定义.
* 用于解析xml文件中对应的bean标签.
*/
public class BeanDefinition {
/**
* bean标签的class属性.
*/
private String className;
/**
* bean标签的id属性.
*/
private String id;
/**
* bean标签的子元素property集合.
*/
private List list = new ArrayList();
/**
* bean构造器.
* @param id bean标签的id属性.
* @param className bean标签的class属性.
*/
public BeanDefinition(String id,String className){
this.className = className;
this.id = id;
}
/**
* 获取bean标签的class属性.
* @return bean标签的class属性.
*/
public String getClassName() {
return className;
}
/**
* 设置bean标签的class属性.
* @param className bean标签的class属性.
*/
public void setClassName(String className) {
this.className = className;
}
/**
* 获取bean标签的id属性.
* @return bean标签的id属性.
*/
public String getId() {
return id;
}
/**
* 设置bean标签的id属性.
* @param id bean标签的id属性.
*/
public void setId(String id) {
this.id = id;
}
/**
* 获取bean标签的property集合.
* @return bean标签的property集合.
*/
public List getList() {
return list;
}
/**
* 设置bean标签的property集合.
* @param list bean标签的property集合.
*/
public void setList(List list) {
this.list = list;
}
}
PropertyDefinition.java文件内容:
package com.rain.spring.util;
/**
* property定义.
* 用于解析property标签.
*/
public class PropertyDefinition {
/**
* property标签的name属性.
*/
private String name;
/**
* property标签的ref属性.
*/
private String ref;
/**
* 无参构造器.
*/
public PropertyDefinition() {
super();
}
/**
* 有参构造器.
* @param name property标签的name属性.
* @param ref property标签的ref属性.
*/
public PropertyDefinition(String name, String ref) {
super();
this.name = name;
this.ref = ref;
}
/**
* 获取property标签的name属性.
* @return property标签的name属性.
*/
public String getName() {
return name;
}
/**
* 设置property标签的name属性.
* @param name property标签的name属性.
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取property标签的ref属性.
* @return property标签的ref属性.
*/
public String getRef() {
return ref;
}
/**
* 设置property标签的ref属性.
* @param ref property标签的ref属性.
*/
public void setRef(String ref) {
this.ref = ref;
}
}
MyClassPathXmlApplicationContext.java文件内容:
package com.rain.spring.util;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
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.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
/**
* bean工厂.
* 解析xml文件生成Java类.
*/
public class MyClassPathXmlApplicationContext {
/**
* bean集合.
*/
private List beanDefines = new ArrayList();
/**
* .
*/
private Map singletons = new HashMap();
/**
* 有参构造器.
* @param fileName xml文件名.
*/
public MyClassPathXmlApplicationContext(String fileName){
this.readXML(fileName);
this.instanceBeans();
try {
this.injectObject();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取bean实例.
* @param beanName bean标签的name属性.
* @return bean实例.
*/
public Object getBean(String beanName){
return singletons.get(beanName);
}
/**
* 读取xml文件.
* @param fileName xml文件名.
*/
private void readXML(String fileName){
SAXReader saxReader = new SAXReader();
Document document = null;
try {
//取得这个类的类加载器,通过类加载器取得类路径下的fileName文件
URL xmlPath = this.getClass().getClassLoader().getResource(fileName);
System.out.println(xmlPath.toString());
//读取文档的内容,得到一个document
document = saxReader.read(xmlPath);
System.out.println("document: "+document.asXML());
Map nsMap = new HashMap();
nsMap.put("ns", "http://www.springframework.org/schema/beans");
//创建beans/bean查询路径 。其中的//ns是根
XPath xsub = document.createXPath("//ns:beans/ns:bean");
System.out.println("设置命名空间前xsub: "+xsub);
//设置命名空间
xsub.setNamespaceURIs(nsMap);
System.out.println("设置命名空间后xsub: "+xsub);
//获取文档下所有bean节点
@SuppressWarnings("unchecked")
List beans = xsub.selectNodes(document);
for(Element element : beans){
//获取id属性值
String id = element.attributeValue("id");
//获取class属性值
String clazz = element.attributeValue("class");
BeanDefinition beanDefinition = new BeanDefinition(id, clazz);
System.out.println("element: "+element.asXML());
@SuppressWarnings("unchecked")
List propertys = element.elements("property");
if(propertys!=null){
List list = new ArrayList();
for(Element property : propertys){
System.out.println("property: "+property.asXML());
String name = property.attributeValue("name");
String ref = property.attributeValue("ref");
PropertyDefinition propertyDefinition = new PropertyDefinition(name,ref);
list.add(propertyDefinition);
}
beanDefinition.setList(list);
}
beanDefines.add(beanDefinition);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 初始化所有的bean,放入singletons Map中.
*/
private void instanceBeans(){
for(BeanDefinition beanDefinition : beanDefines){
try {
if(beanDefinition.getClassName()!=null && !beanDefinition.getClassName().equals("")){
singletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 向含有property子元素的bean中注入bean实例.
* @throws IntrospectionException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private void injectObject() throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
for(BeanDefinition beanDefinition : beanDefines){
Object bean = singletons.get(beanDefinition.getId());
if(bean != null){
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for (PropertyDefinition property : beanDefinition.getList()){
for(PropertyDescriptor propertyDescriptor : propertyDescriptors){
if(property.getName().equals(propertyDescriptor.getName())){
Method setter = propertyDescriptor.getWriteMethod();
if(setter != null){
setter.setAccessible(true);
Object value = singletons.get(property.getRef());
setter.invoke(bean, value);
}
}
}
}
}
}
}
}
Test.java文件内容:
package com.rain.test;
import com.rain.po.Shop;
import com.rain.spring.util.MyClassPathXmlApplicationContext;
/**
* 测试.
*/
public class Test {
public static void main(String[] args) {
//读取beans.xml文件
MyClassPathXmlApplicationContext mySpring = new MyClassPathXmlApplicationContext("beans.xml");
//获取shop实例
Shop shop = (Shop) mySpring.getBean("shop");
System.out.println(shop.getFruit().getName());
}
}
beans.xml文件内容: