剖析@Resource註解的實現原理
阿新 • • 發佈:2019-02-10
1:遍歷所有的bean物件 得到一個bean物件
2:獲取物件的屬性描述
3:得到屬性的setter方法 並判斷setter方法上面是否有註解
4:取得註解 判斷註解是否有name
5:如果有name的話 就直接把引用物件注入到屬性
import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; public class ClassPathXMLApplicationContext { //用來存放bean的資訊 private List<BeanDefinition> BeanDefines = new ArrayList<BeanDefinition>(); //儲存bean private Map<String ,Object > sigletons =new HashMap<String, Object>(); public ClassPathXMLApplicationContext(String fileName){ this.readXML(fileName);//讀XML檔案 this.instanceBeans();//例項化bean物件 this.annotationInject();//處理註解的方法 this.injectObject();//為bean物件的屬性注入值 } //處理註解的方法 private void annotationInject() { // 遍歷所有的bean物件 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(AllenResource.class)){ AllenResource resource = setter.getAnnotation(AllenResource.class); Object value = null; if(resource.name()!=null && !"".equals(resource.name())){ value = sigletons.get(resource.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(AllenResource.class)){ AllenResource resource = field.getAnnotation(AllenResource.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; } } } } field.setAccessible(true); field.set(bean, value); } } } catch (Exception e) { e.printStackTrace(); } } } } //為bean物件的屬性注入值 private void injectObject() { for (BeanDefinition beanDefinition :BeanDefines) { //例項化過後的bean Object bean = sigletons.get(beanDefinition.getId()); if(bean!=null){ try { PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition propertyDefinition:beanDefinition.getProperties()){ 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()); System.out.println(value); }else { System.out.println(properdesc.getPropertyType()); value =propertyDefinition.getValue(); } setter.setAccessible(true);//允許呼叫private的方法 setter.invoke(bean, value);//把應用物件注入到屬性 } } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //完成bean的例項化 private void instanceBeans() { for(BeanDefinition beanDefinition:BeanDefines){ try { if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())) sigletons.put(beanDefinition.getId(),Class.forName(beanDefinition.getClassName()).newInstance()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //讀取app*.xml裡面的內容 private void readXML(String fileName) { SAXReader saxReader = new SAXReader(); Document document =null; try{ URL xmlPath=this.getClass().getClassLoader().getResource(fileName); //System.out.println(xmlPath);file:/G:/workspaces1/spring/bin/beans.xml document =saxReader.read(xmlPath); Map<String,String> nsMap=new HashMap<String, String>(); //加入名稱空間 nsMap.put("ns","http://www.springframework.org/schema/beans"); //建立beans/bean的查詢路徑 XPath xsub = document.createXPath("//ns:beans/ns:bean"); //System.out.println(xsub);[XPath: /descendant-or-self::node()/child::ns:beans/child::ns:bean] //設定名稱空間 xsub.setNamespaceURIs(nsMap); //獲取文件下的所有的bean節點 List<Element> beans = xsub.selectNodes(document); for (Element element : beans) { String id =element.attributeValue("id");//獲取id屬性值 String clazz = element.attributeValue("class");//獲取class屬性值 BeanDefinition beanDefine =new BeanDefinition(id, clazz); //得到bean下面的所有property節點 XPath propertyPath = document.createXPath("ns:property"); propertyPath.setNamespaceURIs(nsMap); List<Element> properties =propertyPath.selectNodes(element); for(Element property:properties){ String propertyName = property.attributeValue("name"); String propertyRef = property.attributeValue("ref"); String propertyValue = property.attributeValue("value"); //System.out.println(propertyName+"="+propertyRef+propertyValue); PropertyDefinition propertyDefinition =new PropertyDefinition(propertyName, propertyRef,propertyValue); beanDefine.getProperties().add(propertyDefinition); } BeanDefines.add(beanDefine); } }catch(Exception e){ e.printStackTrace(); } } //獲取bean例項 public Object getBean(String beanName){ return this.sigletons.get(beanName); } }
//如有錯誤 請馬上指出來 望你我共享