引言:容器是什么?什么是容器?Spring容器又是啥东西?我给Spring容器一个对象名字,为啥能给我创建一个对象呢?
一、容器是装东西的,就像你家的水缸,你吃饭的碗等等。
java中能作为容器的有很多,例如Map,List,数组.....还有好多
二、Spring 容器的核心就是一个Map集合(可能不是很准确,见谅!)
Map<String, Object> 这个容器里根据key-value存放了好多键值对。假如你给一个String的key,就能获得相应的Object的对象,各位大佬,对Spring容器是不是有拨开云雾见太阳的感觉了?[/斜眼笑]
Spring工厂的作用:帮助我们创建管理对象。
<一>BeanFactory
1、定义Map容器,key-类名、value-对象
2、解析bean.xml文件
3、根据name返回对象
1 package com.demo.ioc.theory.factory; 2 3 import java.util.Map; 4 5 import com.demo.ioc.theory.util.ParseHelper; 6 7 public class BeanFactory { 8 //定义的Map<类名,对象>的容器 9 private Map<String, Object> map; 10 //无参构造器传的是bean.xml文件的路径 11 public BeanFactory() { 12 this("src/bean.xml"); 13 } 14 //这个构造器调用方法解析xml文件,返回值就是 类名-对象 的关系 15 public BeanFactory(String path) { 16 try { 17 map = ParseHelper.parseXml(path); 18 } catch (Exception e) { 19 e.printStackTrace(); 20 } 21 } 22 //根据类名获取对象的方法 23 public Object getBean(String beanName) { 24 return map.get(beanName); 25 } 26 }
<二>解析bean.xml文件(dom4j解析)
需要导入dom4j的相关jar包,下载地址 http://central.maven.org/maven2/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar
这个解析简单,直接上代码:
package com.demo.ioc.theory.util;import java.io.File; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map;import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader;@SuppressWarnings("unchecked") public class ParseHelper {public static Map<String, Object> parseXml(String path) throws Exception {Map<String, Object> map = new HashMap<>();// 创建saxReader对象 SAXReader saxReader = new SAXReader();//通过read方法读取一个文件 转换成Document对象 Document document = saxReader.read(new File(path));//获取根节点元素对象Element rootElement = document.getRootElement();List<Element> elements = rootElement.elements();for(Element e:elements){String beanName = e.attributeValue("name");String className = e.attributeValue("class");Object o = Class.forName(className).newInstance();map.put(beanName,o);List<Element> elements2 = e.elements();for(Element e2:elements2){//<property name="student" ref="stu"></property>String propertyName = e2.attributeValue("name"); String refName = e2.attributeValue("ref");//调用当前类中的一个私有方法 通过参数student获得其对应的set方法名:setStudentString methodName = getMethodName(propertyName);//通过对象名字stu从map中获得其对应的对象Object obj = map.get(refName);//获得setStudent方法镜像Method method = o.getClass().getMethod(methodName, new Class[]{obj.getClass()});//反射调用该方法 相当于 t.setStudent(stu); method.invoke(o, obj);}}return map;}//可以把字符串参数xxx转变为setXxxprivate static String getMethodName(String s) {s = s.substring(0,1).toUpperCase() + s.substring(1,s.length());return "set"+s;} }
<三>配置文件bean.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans><bean name="student" class="com.demo.ioc.theory.bean.Student"></bean> </beans>
<四>实体类,Student.java
package com.demo.ioc.theory.bean;public class Student {private String name;private String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}
}
<五>测试自己做的IOC容器
package com.demo.ioc.theory;import com.demo.ioc.theory.bean.Student; import com.demo.ioc.theory.factory.BeanFactory;public class IocTest {public static void main(String[] args) {//创建工厂对象BeanFactory beanFactory = new BeanFactory();//通过工厂直接拿到Student对象,不用去 new Student();Student bean = (Student) beanFactory.getBean("student");//测试bean.setAge("20");System.out.println(bean.getAge());} }
到此,一个简单的Spring Ioc容器就实现了,这个容器可以根据配置文件配置的信息获取到对应的对象。不需要再去new对象了。当然,这只是最简单的,你也可以再去深入....
下面是我的demo的项目结构,瞧一瞧哦