\(^)/ 模拟Spring的IoC
\(^_^)/ 模拟Spring的IoC
参考:http://blog.****.net/lyq8479/article/category/1366622
参考:http://neversky.iteye.com/blog/1956018
参考:http://www.cnblogs.com/txw1958/
参考:http://justsee.iteye.com/blog/1298861
参考:http://xiaoye4188.iteye.com/blog/846822
参考:http://josephmok.iteye.com/blog/763653
参考:http://lgd-java2eye.iteye.com/blog/756599
参考:http://byd1200479.iteye.com/blog/1599365
参考:http://jim8757.iteye.com/blog/2059999
参考:http://chenzehe.iteye.com/blog/1488781
参考:http://dyygusi.iteye.com/blog/1997231
参考:http://lgd-java2eye.iteye.com/blog/759878
参考:http://ewf-momo.iteye.com/blog/1693723
Bean元素封装
package spring.mock; import java.util.ArrayList; import java.util.List; /** * Xml文件中<bean/>元素的对象 */ public class BeanDefinition { private String id; private String clazz; private List<PropertyDefinition> propertyDefinition = new ArrayList<PropertyDefinition>(); public BeanDefinition(String id, String clazz) { super(); this.id = id; this.clazz = clazz; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getClazz() { return clazz; } public void setClazz(String clazz) { this.clazz = clazz; } public List<PropertyDefinition> getPropertyDefinition() { return propertyDefinition; } public void setPropertyDefinition(List<PropertyDefinition> propertyDefinition) { this.propertyDefinition = propertyDefinition; } }
Bean中的Property元素封装
package spring.mock; /** * Xml元素中<bean>元素中的property元素 */ public class PropertyDefinition { private String name; private String ref; private String value; public PropertyDefinition(String name, String ref, String value) { super(); this.name = name; this.ref = ref; this.value = value; } 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; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
ApplicationContext模拟
package spring.mock; 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.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 MockSpringXmlApplicationContext { private List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>(); private Map<String, Object> singletons = new HashMap<String, Object>(); public MockSpringXmlApplicationContext(String fileName){ try{ this.readXML(fileName); this.instanceBean(); this.injectObject(); }catch(Exception e){ e.printStackTrace(); } } private void readXML(String fileName) throws DocumentException { SAXReader saxReader = new SAXReader(); Document document = null; URL xmlPath = this.getClass().getClassLoader().getResource(fileName); document = saxReader.read(xmlPath); XPath beanPath = document.createXPath("//ns:beans/ns:bean"); Map<String, String> nsMap = new HashMap<String, String>(); nsMap.put("ns", "http://www.springframework.org/schema/beans"); beanPath.setNamespaceURIs(nsMap); List<Element> beans = beanPath.selectNodes(document); for (Element element : beans) { String id = element.attributeValue("id"); String clazz = element.attributeValue("class"); BeanDefinition beanDefinition = new BeanDefinition(id, clazz); XPath propertyPath = element.createXPath("ns:property"); propertyPath.setNamespaceURIs(nsMap); List<Element> properties = propertyPath.selectNodes(element); for (Element propElement : properties) { String name = propElement.attributeValue("name"); String ref = propElement.attributeValue("ref"); String value = propElement.attributeValue("value"); PropertyDefinition propertyDefinition = new PropertyDefinition(name, ref, value); beanDefinition.getPropertyDefinition().add(propertyDefinition); } beanDefinitions.add(beanDefinition); } } private void instanceBean() throws InstantiationException, IllegalAccessException, ClassNotFoundException { for (BeanDefinition beanDefinition : beanDefinitions) { if (beanDefinition.getClass() != null && !"".equals(beanDefinition.getClass())) { singletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClazz()).newInstance()); } } } private void injectObject() throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { for (BeanDefinition beanDefinition : beanDefinitions) { Object bean = singletons.get(beanDefinition.getId()); if (bean != null) { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for (PropertyDefinition propertyDefinition : beanDefinition.getPropertyDefinition()) { for(PropertyDescriptor propertyDescriptor:ps){ if(propertyDefinition.getName().equals(propertyDescriptor.getName())){ Method setterMethod = propertyDescriptor.getWriteMethod(); if(setterMethod!=null){ Object temp = null; if(propertyDefinition.getRef()!=null&&!"".equals(propertyDefinition.getRef().trim())){ temp = singletons.get(propertyDefinition.getRef()); }else if(propertyDefinition.getValue()!=null&&!"".equals(propertyDefinition.getValue().trim())){ temp = ConvertUtils.convert(propertyDefinition.getValue(), propertyDescriptor.getPropertyType()); } setterMethod.setAccessible(true); setterMethod.invoke(bean, temp); } break; } } } } } } public Object getBean(String beanName){ return this.singletons.get(beanName); } }
测试DAO
package spring.mock; public class UserDAO { private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } @Override public String toString() { return "UserDAO [id=" + id + "]"; } }
测试Service
package spring.mock; public class UserService { private String id; private String name; private int age; private UserDAO userDAO; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public UserDAO getUserDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } @Override public String toString() { return "UserService [id=" + id + ", name=" + name + ", age=" + age + ", userDAO=" + userDAO + "]"; } }
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="userDAO" class="spring.mock.UserDAO"> <property name="id" value="userDAO_id_001" /> </bean> <bean id="userService" class="spring.mock.UserService"> <property name="id" value="userService_id_001" /> <property name="name" value="userName_test" /> <property name="age" value="23" /> <property name="userDAO" ref="userDAO" /> </bean> </beans>
测试类
package spring.mock; public class Test { public static void main(String[] args) { MockSpringXmlApplicationContext context = new MockSpringXmlApplicationContext("beans.xml"); UserService userService = (UserService)context.getBean("userService"); System.out.println(userService.toString()); } }