初见Spring
程序员文章站
2024-01-05 15:38:40
Spring是众多开源 Java 项目中的一员,基于分层的 JavaEE 应用一站式轻量级开源框架,主要核心是IOC控制反转(Inversion of Control, IoC)和依赖注入(Dependency Injection, DI)这两大技术。 下面是一个非常原始,简易的BeanFactor ......
spring是众多开源 java 项目中的一员,基于分层的 javaee 应用一站式轻量级开源框架,主要核心是ioc控制反转(inversion of control, ioc)和依赖注入(dependency injection, di)这两大技术。
下面是一个非常原始,简易的beanfactory。
通过创建factory对象调用到构造器,构造器再调用方法,实现自动解析xml配置文件,实例化对象,并完成依赖注入。
1 /** 2 * ioc工厂接口的实现类 3 * 1.在创建实现类对象时解析xml文件 4 * 2.分析解析后的内容,通过反射创建对象,装入hashmap中 5 * 3.根据传入的classname返回指定对象 6 * 4.依赖注入,给属性赋值(对象) 7 */ 8 public class factory02 implements factory { 9 //用于存放解析xml后得到的bean对象 10 private list<factorybeans> beans = new arraylist<>(); 11 //用于存放完成实例化后的对象 12 private map<string,object> map = new hashmap<>(); 13 14 public factory02(string filename){ 15 this.parsexml(filename); 16 this.instancebean(); 17 this.setbeanproperty(); 18 } 19 20 /** 21 * 为实例化的对象赋值 22 */ 23 private void setbeanproperty() { 24 if(beans.size()>0){ 25 for(factorybeans factorybeans : beans){ 26 //获取当前bean对象中的property对象集合 27 list<propertybean> subelementlist = factorybeans.getpropertybeanlist(); 28 if(subelementlist!=null && subelementlist.size()>0){ 29 for(propertybean propertybean : subelementlist){ 30 //获取当前property对象中的id 31 string id = propertybean.getid(); 32 //首字母大写 用于拼接set方法 33 id = id.touppercase().charat(0)+id.substring(1); 34 //获取当前property对象中的ref 35 string ref = propertybean.getref(); 36 //获取当前bean对象的类对象 37 class clazz = map.get(factorybeans.getid()).getclass(); 38 try { 39 //1.拼接set方法 2.传入set方法所需要的形参(通过property对象中的ref引用 查找到map中已经生成的对象 40 // 获取它的class类对象) 41 method method = clazz.getdeclaredmethod("set"+id,map.get(ref).getclass()); 42 //执行该set方法 1.指定调用该set方法的类 2.赋的值 即map中已经创建出的指定对象 43 method.invoke(map.get(factorybeans.getid()),map.get(ref)); 44 } catch (exception e) { 45 e.printstacktrace(); 46 } 47 } 48 } 49 } 50 } 51 } 52 53 /** 54 * 实例化解析的得到的数据 55 */ 56 private void instancebean(){ 57 if(beans.size()>0){ 58 try { 59 for(factorybeans factorybeans : beans){ 60 //key为id,value为通过全限定名class实例化得到的对象 61 map.put(factorybeans.getid(),class.forname(factorybeans.getclazz()).newinstance()); 62 } 63 } catch (instantiationexception e) { 64 e.printstacktrace(); 65 } catch (illegalaccessexception e) { 66 e.printstacktrace(); 67 } catch (classnotfoundexception e) { 68 e.printstacktrace(); 69 } 70 } 71 } 72 73 /** 74 * 解析xml 75 * @param filename xml文件名 76 */ 77 private void parsexml(string filename){ 78 //获取xml的唯一指定资源标识符 79 url url = this.getclass().getclassloader().getresource(filename); 80 if(url!=null){ 81 //创建sax解析对象 82 saxreader saxreader = new saxreader(); 83 try { 84 //解析该url指向的文件 85 document document = saxreader.read(url); 86 //配置xpath需要解析的内容 即所有beans标签后的bean标签中的内容 87 xpath xpath = document.createxpath("beans/bean"); 88 //指定解析标签的范围为当前整个xml文件(document) 89 list<element> elementlist = xpath.selectnodes(document); 90 if(elementlist!=null || elementlist.size()>0){ 91 for(element element : elementlist){ 92 //解析property标签中的内容 93 xpath = document.createxpath("property"); 94 //指定范围为当前元素下(element) 95 list<element> subelementlist = xpath.selectnodes(element); 96 //创建属性类对象的集合备用 97 list<propertybean> propertybeanlist = null; 98 //通过解析bean标签得到的id和全限定名 创建factorybeans对象 99 factorybeans factorybeans = new factorybeans(element.attributevalue("id"),element.attributevalue("class")); 100 //判断当前元素中是否包含属性property标签 101 if(subelementlist!=null && subelementlist.size()>0){ 102 propertybeanlist = new arraylist<>(); 103 //遍历该bean标签中所有的property标签 创建相对应的property对象 104 for(element subelement : subelementlist){ 105 //装入集合中 106 //propertybean对象中有两个元素 107 //id:用于创建用来赋值的set方法 除了首字母 其它字符须和被赋值的属性保持一致 108 //ref:用于引用其它bean标签 ref必须和被引用的bean标签id保持一致 109 propertybeanlist.add(new propertybean(subelement.attributevalue("id"),subelement 110 .attributevalue("ref"))); 111 } 112 //将property标签创建的对象装入factorybeans的集合属性中 113 //每个factorybeans都带有一个集合属性 专门用于存放property对象 114 //如果xml中该bean标签下没有property标签 则不会有任何集合产生 115 //反之有多少个property标签 就会有多少个property对象生成并装入该集合中 116 factorybeans.setpropertybeanlist(propertybeanlist); 117 } 118 //将factorybeans对象装入集合中 119 beans.add(factorybeans); 120 } 121 }else{ 122 system.out.println("未解析元素"); 123 } 124 } catch (exception e) { 125 e.printstacktrace(); 126 } 127 128 }else{ 129 system.out.println("未找到文件"); 130 } 131 } 132 133 /** 134 * ioc工厂接口的实现类方法 135 * @param classname 类名 136 * @return 指定类的对象 137 */ 138 @override 139 public object getobject(string classname) { 140 return map.get(classname); 141 } 142 }
初见spring,如有错误的地方,希望对这方面有研究的朋友指出,谢谢!