spring框架IOC原理分析代码
模拟ClasspathXmlApplication:
package junit.test; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.File; import java.lang.reflect.Field; 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.io.SAXReader; public class ItcastClassPathXmlApplicationContext { private ArrayList<BeanDefinition> beanDefinitions=new ArrayList<BeanDefinition>(); private Map<String,Object> sigletons=new HashMap<String,Object>(); public ItcastClassPathXmlApplicationContext(String filename){ this.readXml(filename); this.instanceBeans(); this.annotationInject(); this.injectObject(); } /** * 注解方式装载对象 */ private void annotationInject() { for(String beanName :sigletons.keySet()){ Object bean=sigletons.get(beanName); if(bean!=null){ try{ /* * 查找方法上的注解 */ PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDescriptor properdesc:ps){ Method setter=properdesc.getWriteMethod(); if(setter!=null && setter.isAnnotationPresent(ItcastResource.class)){ ItcastResource itcastResource=setter.getAnnotation(ItcastResource.class); Object value=null; if(itcastResource.name()!=null && !"".equals(itcastResource.name())){ value=sigletons.get(itcastResource.name()); }else{ value=sigletons.get(properdesc.getName()); if(value==null){ for(String key:sigletons.keySet()){ if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){ value=sigletons.get(key); break; } } } } setter.setAccessible(true); setter.invoke(bean, value); } } /** * 查找字段上的注解 */ Field[] fields=bean.getClass().getDeclaredFields(); for(Field field:fields){ if(field.isAnnotationPresent(ItcastResource.class)){ ItcastResource resource=field.getAnnotation(ItcastResource.class); Object value=null; if(resource.name()!=null && !"".equals(resource.name())){ value=sigletons.get(resource.name()); }else{ value=sigletons.get(field.getName()); if(value==null){ for(String key:sigletons.keySet()){ if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){ value=sigletons.get(key); break; } } } } String methodName="set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1); Method setter=bean.getClass().getMethod(methodName, field.getType()); setter.setAccessible(true); setter.invoke(bean, value); } } }catch(Exception e){ e.printStackTrace(); } } } } /** * 为bean对象的属性注入值 */ private void injectObject() { for(BeanDefinition beanDefinition: beanDefinitions){ Object bean=sigletons.get(beanDefinition.getId()); if(bean!=null){ try { PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition propertyDefinition:beanDefinition.getPropertys()){ for(PropertyDescriptor properdesc:ps){ if(propertyDefinition.getName().equals(properdesc.getName())){ Method setter=properdesc.getWriteMethod();//获取属性的setter方法 if(setter!=null){ Object value=null; if(propertyDefinition.getRef()!=null &&!"".equals(propertyDefinition.getRef())){ value=sigletons.get(propertyDefinition.getRef()); }else{ value=ConvertUtils.convert(propertyDefinition.getValue(), properdesc.getPropertyType()); } setter.setAccessible(true); setter.invoke(bean, value); } break; } } } } catch (Exception e) { e.printStackTrace(); } } } } /** * 完成bean的实例化 */ private void instanceBeans(){ for(BeanDefinition bd:beanDefinitions){ try { if(bd.getClassName()!=null && !"".equals(bd.getClassName().trim())) sigletons.put(bd.getId(), Class.forName(bd.getClassName()).newInstance()); } catch (Exception e) { e.printStackTrace(); } } } /** * 解析xml文件 * @param fileName */ private void readXml(String fileName) { File inputXml=new File(fileName); URL url=this.getClass().getClassLoader().getResource(fileName); SAXReader saxReader=new SAXReader(); try { Document document=saxReader.read(url); Element root=document.getRootElement(); @SuppressWarnings("unchecked") List<Element> beans=root.elements("bean"); for(Element bean:beans){ String id= bean.attributeValue("id"); String className=bean.attributeValue("class"); BeanDefinition bd=new BeanDefinition(id,className); @SuppressWarnings("unchecked") List<Element> propertys=bean.elements("property"); for(Element property:propertys){ String propertyName = property.attributeValue("name"); String propertyRef = property.attributeValue("ref"); String propertyValue=property.attributeValue("value"); PropertyDefinition pd=new PropertyDefinition(propertyName, propertyRef,propertyValue); bd.getPropertys().add(pd); } beanDefinitions.add(bd); } } catch (DocumentException e) { e.printStackTrace(); } } public Object getBean(String beanName){ return this.sigletons.get(beanName); } }
存放bean信息的类:
package junit.test; import java.util.ArrayList; import java.util.List; /** * 存放读取到的bean的信息 * @author Administrator * */ public class BeanDefinition { private String id; private String className; private List<PropertyDefinition> propertys=new ArrayList<PropertyDefinition>(); public BeanDefinition() { super(); } public BeanDefinition(String id, String className) { super(); this.id = id; this.className = className; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public void setPropertys(List<PropertyDefinition> propertys) { this.propertys = propertys; } public List<PropertyDefinition> getPropertys() { return propertys; } }
存放bean中属性信息的类:
package junit.test; /** * 属性的定义类 * @author Administrator * */ public class PropertyDefinition { private String name; private String ref; private String value; public String getName() { return name; } public void setName(String name) { this.name = name; } public PropertyDefinition(String name, String ref,String value) { super(); this.name = name; this.ref = ref; this.value=value; } public PropertyDefinition() { super(); } public String getRef() { return ref; } public void setRef(String ref) { this.ref = ref; } public void setValue(String value) { this.value = value; } public String getValue() { return value; } }
对应Resource注解:
package junit.test; 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 ItcastResource { public String name() default ""; }