java模拟spring ioc 博客分类: javaspring javaspring控制反转
程序员文章站
2024-02-07 13:28:04
...
<?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="personDao" class="junit.test12.PersonDaoBean"/> <bean id="personService" class="junit.test12.PersonServiceBean"> <property name="id" value="24"/> <property name="name" value="zyj"/> <!-- <property name="personDao" ref="personDao"/> --> </bean> </beans>
package junit.test12; import java.util.ArrayList; import java.util.List; /** * xml中的<bean/>的定义 * @author Administrator * */ public class BeanDefinition { private String id; private String clazz; private List<PropertyDefinition> propertyDefinitions=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> getPropertyDefinitions() { return propertyDefinitions; } public void setPropertyDefinitions(List<PropertyDefinition> propertyDefinitions) { this.propertyDefinitions = propertyDefinitions; } }
package junit.test12; 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; } }
package junit.test12; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD,ElementType.METHOD}) public @interface UserDefinedResource { public String name() default ""; }
//使用dom4j读取spring配置文件
package junit.test12; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; 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 junit.test12.BeanDefinition; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.Converter; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; /** * 自定义容器 * @author Administrator * */ public class UserDefinedClassPathXMLApplicationContext { private List<BeanDefinition> beanDefinitions=new ArrayList<BeanDefinition>(); private Map<String, Object> sigletons=new HashMap<String, Object>(); public UserDefinedClassPathXMLApplicationContext(String filename){ this.readXML(filename); this.instanceBeans(); this.annotationInject(); this.injectObject(); } /** * 读取xml配置文件 * @param filename */ private void readXML(String filename){ SAXReader saxReader=new SAXReader(); Document document=null; try { URL xmlPath=this.getClass().getClassLoader().getResource(filename); document=saxReader.read(xmlPath); XPath xPath=document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径。从根路径开始 Map<String, String> nsMap=new HashMap<String, String>(); nsMap.put("ns", "http://www.springframework.org/schema/beans");//加入命名空间 xPath.setNamespaceURIs(nsMap);//设置命名空间 List<Element> beans=xPath.selectNodes(document);//获取文档下所有bean节点 for (Element element : beans) { String id=element.attributeValue("id"); String clazz=element.attributeValue("class"); BeanDefinition beanDefinition=new BeanDefinition(id, clazz); XPath xPath2=element.createXPath("ns:property");//从相对路径开始 xPath2.setNamespaceURIs(nsMap); List<Element> propertys=xPath2.selectNodes(element); for (Element element2 : propertys) { String name=element2.attributeValue("name"); String ref=element2.attributeValue("ref"); String value=element2.attributeValue("value"); PropertyDefinition propertyDefinition=new PropertyDefinition(name, ref,value); beanDefinition.getPropertyDefinitions().add(propertyDefinition); } beanDefinitions.add(beanDefinition); } } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 完成bean的实例化 */ private void instanceBeans(){ try { for (BeanDefinition beanDefinition : beanDefinitions) { if (beanDefinition.getClazz()!=null&&!"".equals(beanDefinition.getClazz().trim())) { sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClazz()).newInstance()); } } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 为bean对象的属性注入值 * @throws IntrospectionException * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException */ private void injectObject() { try { for (BeanDefinition beanDefinition : beanDefinitions) { Object bean=sigletons.get(beanDefinition.getId()); if (bean!=null) { PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition propertyDefinition:beanDefinition.getPropertyDefinitions()){ for (PropertyDescriptor propertyDescriptor : ps) { if (propertyDefinition.getName().equals(propertyDescriptor.getName())) { Method setterMethod=propertyDescriptor.getWriteMethod();//获取属性的setter方法 if (setterMethod!=null) { Object temp=null; if (propertyDefinition.getRef()!=null&&!"".equals(propertyDefinition.getRef().trim())) { temp=sigletons.get(propertyDefinition.getRef()); }else if (propertyDefinition.getValue()!=null&&!"".equals(propertyDefinition.getValue().trim())) { temp=ConvertUtils.convert(propertyDefinition.getValue(), propertyDescriptor.getPropertyType()); } setterMethod.setAccessible(true);//防止setter方法为private setterMethod.invoke(bean, temp);//把引用对象注入到属性 } break; } } } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 通过注解实现注入依赖对象 * @throws IntrospectionException * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException */ private void annotationInject(){ try { for (String beanName : sigletons.keySet()) { Object bean=sigletons.get(beanName); if (bean!=null) { PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for (PropertyDescriptor propertyDescriptor : ps) { Method setterMethod=propertyDescriptor.getWriteMethod(); if (setterMethod!=null&&setterMethod.isAnnotationPresent(UserDefinedResource.class)) { UserDefinedResource userDefinedResource=setterMethod.getAnnotation(UserDefinedResource.class); Object temp = null; if(userDefinedResource.name()!=null && !"".equals(userDefinedResource.name())){ //一旦指定了name属性,就只能按名称装配了 temp = sigletons.get(userDefinedResource.name()); }else{ temp = sigletons.get(propertyDescriptor.getName()); if(temp==null){ for(String key : sigletons.keySet()){ if(propertyDescriptor.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){ temp = sigletons.get(key); break; } } } } setterMethod.setAccessible(true); setterMethod.invoke(bean, temp);//把引用对象注入到属性 } } Field[] fields = bean.getClass().getDeclaredFields(); for(Field field : fields){ if(field.isAnnotationPresent(UserDefinedResource.class)){ UserDefinedResource userDefinedResource = field.getAnnotation(UserDefinedResource.class); Object temp = null; if(userDefinedResource.name()!=null && !"".equals(userDefinedResource.name())){ temp = sigletons.get(userDefinedResource.name()); }else{ temp = sigletons.get(field.getName()); if(temp==null){ for(String key : sigletons.keySet()){ if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){ temp = sigletons.get(key); break; } } } } field.setAccessible(true);//允许访问private字段 field.set(bean, temp); } } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 获取bean实例 * @param beanName * @return */ public Object getBean(String beanName){ return this.sigletons.get(beanName); } }
package junit.test12; import static org.junit.Assert.*; import junit.test12.PersonService; import junit.test12.UserDefinedClassPathXMLApplicationContext; import org.junit.Test; public class SpringTest { @Test public void instanceSpring() { UserDefinedClassPathXMLApplicationContext applicationContext=new UserDefinedClassPathXMLApplicationContext("beans.xml"); PersonService personService=(PersonService) applicationContext.getBean("personService"); personService.save(); } }