一、概念
IOC
百度百科解释:
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
我的解释:
IOC:控制反转,可以将IOC看成一个很大的容器,容器中存放的全部是我们的对象
控制:是指创建对象的过程
反转:之前创建对象的时候,都是手动去new一个对象出来,现在所有的对象都由IOC容器去创建,而现在我们获取对象的
时候直接从容器中获取即可。
DI
DI:依赖注入,一个对象里面可能会有会有很多其他的对象,将其他对象设置进入的过程统称为依赖注入。
(简单点理解,就是给我们创建出来的对象赋值的过程称为DI)
二、代码展示
xml文件
applicationTeacher.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- id唯一 class要求必须是类的全限定名 -->
<!-- 要求最少有5个bean标签 -->
<!-- 1: 创建一个类解析这个xml,然后将id变成key,value是 全新定名对应的类型对象 然后类中提供一个方法,名字叫getBean(String
key),方法的返回值是 Object参数是字符串 如果参数值与key的值相等,则返回对应的value -->
<!-- 2: 要求bean如以下格式 ,在解析完xml创建对象的时候,将下面的 帝王蕉,18 这些值 存到对象的 name,age属性之中。 -->
<beans>
<bean id="person" class="com.zhiyou.work3.Person">
<property name="name">张三</property>
<property name="age">18</property>
<property name="sex">男</property>
<property name="type">黄种人</property>
</bean>
<bean id="anaimal" class="com.zhiyou.work3.Anaimal">
<property name="name">狮子</property>
<property name="age">7</property>
<property name="sex">公</property>
</bean>
<bean id="apple" class="com.zhiyou.work3.Apple">
<property name="name">红富士</property>
<property name="age">1</property>
</bean>
<bean id="fruits" class="com.zhiyou.work3.Fruits">
<property name="name">水果</property>
<property name="age">2</property>
<property name="apple" ref="apple"/>
</bean>
<bean id="tree" class="com.zhiyou.work3.Tree">
<property name="name">杨树</property>
<property name="age">14</property>
<property name="type">好树</property>
</bean>
</beans>
model类
Anaimal类:
package com.zhiyou.work3;
import lombok.Data;
@Data
public class Anaimal {
private String name;
private Integer age;
private String sex;
}
Apple类:
package com.zhiyou.work3;
import lombok.Data;
@Data
public class Apple {
private String name;
private Integer age;
}
Fruits类:
package com.zhiyou.work3;
import lombok.Data;
@Data
public class Fruits {
private String name;
private Integer age;
private Apple apple;
}
Person类:
package com.zhiyou.work3;
import lombok.Data;
@Data
public class Person {
private String name;
private Integer age;
private String sex;
private String type;
}
Tree
package com.zhiyou.work3;
import lombok.Data;
@Data
public class Tree {
private String name;
private Integer age;
private String type;
}
解析并创建对象
AnalysisTeacher类:
package com.zhiyou.work2;
import java.awt.Window.Type;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import lombok.Data;
import lombok.val;
public class AnalysisTeacher {
// 使用map来充当IOC容器,用来存储名字和对象
private static Map<String, Object> map = new HashMap<String, Object>();
//用来创建对象(IOC)
private static void method(Document document) throws Exception{
//通过document对象,可以获取到xml中最外围的标签 beans
Element rootElement = document.getRootElement();
//获得bean标签的迭代器,来迭代里面的bean标签
Iterator iterator = rootElement.elementIterator();
while(iterator.hasNext()){ //进行循环,说明还有bean标签
//循环获得bean标签
Element bean = (Element) iterator.next();
//通过class属性的value来创建反射对象
Class class1 = Class.forName(bean.attributeValue("class"));
//先把对象注入到map中
map.put(bean.attributeValue("id"), class1.newInstance());
}
}
//用来注入属性(DI依赖注入,IOC的一部分)
public static void method2(Document document) throws NoSuchFieldException, SecurityException, NumberFormatException, IllegalArgumentException, IllegalAccessException {
//通过document对象,可以获取到xml中最外围的标签 beans
Element rootElement = document.getRootElement();
//获得bean标签的迭代器,来迭代里面的bean标签
Iterator iterator = rootElement.elementIterator();
while(iterator.hasNext()){ //进行循环,说明还有bean标签
//循环获得bean标签
Element bean = (Element) iterator.next();
//通过xml中的bean标签的id属性的value 从容器中获取到对象
Object object = map.get(bean.attributeValue("id"));
//获得反射对象
Class class1 = object.getClass();
//遍历bean里面的标签property
Iterator iterator2 = bean.elementIterator();
while(iterator2.hasNext()){
//获取property标签
Element property = (Element) iterator2.next();
//通过属性名称来获得一个属性对象
Field field = class1.getDeclaredField(property.attributeValue("name"));
//破坏访问修饰符
field.setAccessible(true);
//
if(field.getType().getName().equals("java.lang.Integer")){
field.set(object, Integer.valueOf(property.getStringValue()));
}else if(field.getType().getName().equals("java.lang.String")){
field.set(object,property.getStringValue());
}else{
field.set(object, map.get(property.attributeValue("name")));
}
}
}
}
//通过静态块
static{
//获得一个读取xml文件的对象
SAXReader saxReader = new SAXReader();
try {
//通过read获得xml中所有元素
Document document = saxReader.read("E:/java/MyJava/Month3/XMLReflect/src/com/zhiyou/work2/applicationTeacher.xml");
method(document);
//进行属性的注入
method2(document);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Object getBean(String name) {
return map.get(name);
}
public static <T>T getBean(Class<T> c) {
//获取容器中的所有对象集合
Collection<Object> collection = map.values();
//获得一个集合的迭代器对象
Iterator<Object> iterator = collection.iterator();
//遍历这个集合
while(iterator.hasNext()){
//一次取出集合中的对象
Object next = iterator.next();
//判断当前对象的类名是否和传入的一致
if (next.getClass().getName().equals(c.getName())) {
return (T)next;
}
}
return null;
}
public static Object typeCast(String type, String data) {
switch (type) {
case "Integer":
return Integer.valueOf(data);
case "Float":
return Float.valueOf(data);
case "Double":
return Double.valueOf(data);
case "Long":
return Long.valueOf(data);
case "Short":
return Short.valueOf(data);
case "Timestamp":
return Timestamp.valueOf(data);
case "String":
return data;
default: //
return data;
}
}
}
测试函数:
public static void main(String[] args) {
System.out.println(AnalysisTeacher.getBean(Fruits.class));
}
测试结果: