Spring的IOC从入门到深入
1.分析下面代码开发中存在的问题:
2. 针对上述代码存在的问题,我们该解决,
解决方案是: 将测试类与接口的耦合,通过第三方容器来解决
实现步骤分为两步:
第一步: 将耦合类配置到xml文件中, 比如: beans.xml
<?xml version="1.0" encoding="utf-8" ?>
<!--上面是:文档声明是xml文档-->
<!--XML有且仅有一个根标签: objs,由于是自定义的xml,标签可以任意定义-->
<objs>
<!--子标签: obj
id: 唯一标识,一般建议使用类名,首字母小写
class:类的全路径
-->
<obj id="dog" class="com.tedu.service.impl.Dog"/>
<obj id="cat" class="com.tedu.service.impl.Cat"/>
</objs>
第二步: 创建容器对象,加载配置文件,创建对象存储到容器中
/**
* 模拟Spring核心对象:
* 1.通过解析xml文件,读取到class属性的值
* 2.利用反射Class.newInstance()创建对象
* 3.把创建的对象存到map里面(map就是spring容器)
* map容器存对象有两种方式:
* 方式一: map中的key: 类名称(首字母小写), map的value: 类对象
* 方式二: map中的key: 类的class对象, map的value: 类对象
*/
public class MyApplicationContext {
//1.引入被加载的xml文件
private String resourcesXml;
//2.创建容器对象, 就是map, 底层是线程安全的map
private static Map<Object,Object> map = new ConcurrentHashMap<Object,Object>();
//3.通过构造方法给引入的xml文件赋值
public MyApplicationContext(String xmlPath){
this.resourcesXml = xmlPath;
//解析配置文件,创建对象,存到map容器中
try{
//5.解析配置文件的代码: dom4j技术解析xml,
SAXReader saxReader = new SAXReader();//核心解析器对象
//6.类加载器获取配置文件字节输入流
InputStream in = MyApplicationContext.class.getClassLoader()。getResourceAsStream(resourcesXml);
//7.读取配置文件字节输入流,获取xml的文档对象
Document document = saxReader.read(in);
//8.根据document获取所有的obj标签对象
List<Node> list = document.selectNodes("//obj");
//9.遍历list集合,获取list集合里面的每一个obj标签
for (Node node : list) {
//10. 把node节点转换为 element标签
Element element = (Element)node;
//11. 根据element标签对象:获取id属性值,获取class属性值
String idValue = element.attributeValue("id");//比如:idValue = dog
String classPath = element.attributeValue("class");//比如:classPath = 包名。Dog
//12.利用反射创建对象
Class aClass = Class.forName(classPath);//得到类的字节码对象, 比如: Dog.class
Object obj = aClass.newInstance();//反射: 默认使用无参数的构造方法创建对象
//13.把创建好的对象存到容器中
//13.1比如: 根据 dog名称-- new Dog()对象
map.put(idValue,obj);
//13.2比如: 根据 Dog.class-- new Dog()对象
map.put(aClass,obj);
}
}catch (Exception e){
e.printStackTrace();
}
}
//4.提供一个根据名称: 也就是根据id的属性值获取 bean对象的方法
//直接从map容器中获取对象
public static Object getBean(String idValue){
return map.get(idValue);
}
//5.提供一个根据名称: 也就是根据Class字节码对象获取 bean对象的方法
//定义泛型的优点: 避免类型强转
//直接从map容器中获取对象
public static <T> T getBean(Class<T> clz){
return (T)map.get(clz);
}
}
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h65080.shtml