目录
开发工具:
ideal maven java
ioc介绍:
IOC(Inverse of Controll)控制反转是一种程序设计思想。
控制是什么?
JavaBean(Java对象)的创建和管理
反转是什么?
一般情况下对象的创建和管理由开发者控制,反转是把对象的创建和管理交给容器完成,然后再交给开发者。
本篇博客将教会大家通过xml实现控制反转,彻底弄懂究竟是如何实现控制反转的。
entity类:
Computer类:
package com.dmdd.ioc;
public class Computer {
private String brand;
private Cpu cpu;
private Memory memory;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Cpu getCpu() {
return cpu;
}
public void setCpu(Cpu cpu) {
this.cpu = cpu;
}
public Memory getMemory() {
return memory;
}
public void setMemory(Memory memory) {
this.memory = memory;
}
public void start (){
System.out.println(brand+"品牌的电脑启动了");
cpu.run();
memory.read();
memory.write();
}
}
computer引用了两个类一个是 cpu 一个是 memory。
Memory类:
package com.dmdd.ioc;
public class KingstonMemory implements Memory{
@Override
public void read() {
System.out.println("金士顿内存读取数据");
}
@Override
public void write() {
System.out.println("金士顿内存写数据");
}
}
package com.dmdd.ioc;
public class SumsungMemory implements Memory{
@Override
public void read() {
System.out.println("三星内存条读取。。。。");
}
@Override
public void write() {
System.out.println("三星内存条写入。。。");
}
}
CPU类:
package com.dmdd.ioc;
public class AMDCpu implements Cpu{
@Override
public void run() {
}
}
package com.dmdd.ioc;
public class IntelCpu implements Cpu{
@Override
public void run() {
}
}
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
<!--cpu对象-->
<bean id="cpu" class="com.dmdd.ioc.IntelCpu"></bean>
<!-- memory对象-->
<bean id="memory" class="com.dmdd.ioc.KingstonMemory"></bean>
<!-- computer对象-->
<bean id="computer" class="com.dmdd.ioc.Computer">
<!-- 注入值类型的属性 name属性名 value注入值类型 ref注入引用类型-->
<property name="brand" value="联想"></property>
<property name="cpu" ref="cpu"></property>
<property name="memory" ref="memory"></property>
</bean>
</beans>
1.每一个bean代表一个对象 class属性代表的是哪个类。
2.property是bean对象里面的属性 name表示属性名
3.value代表属性的值
4.ref代表引用的类型
XMLBeanFactory:
package com.dmdd.ioc.demo6;
import com.sun.xml.internal.fastinfoset.tools.StAX2SAXReader;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MyXMLBeanFactory {
//配置文件名称
private String fileName;
//保存javabean的集合
private Map<String, Object> beanMap = new HashMap<>();
public MyXMLBeanFactory(String fileName) {
this.fileName = fileName;
parseXML();
}
/***
* 解析XML
*/
public void parseXML() {
SAXReader reader = new SAXReader();
//读取xml文件,获得文档对象
try {
Document doc = reader.read(MyXMLBeanFactory.class.getClassLoader().getResourceAsStream(fileName));
//通过文档对象获得根节点
Element root = doc.getRootElement();
//通过根节点,查找所有的bean节点
List<Element> beans = root.elements("beans");
//这次循环将对象实例化添加到Map中去
for (Element bean : beans) {
//通过class属性,获得类型信息,实例化对象
String aClass = bean.attribute("class").getValue();
Class<?> aClass1 = Class.forName(aClass);
Object beanObj = aClass1.newInstance();
String id = bean.attribute("id").getValue();
beanMap.put(id, beanObj);
}
//这次循环是将bean中的属性初始化
for (Element bean : beans) {
{
//读取bean节点中的property节点
List<Element> properties = bean.elements("property");
for (Element property : properties) {
Attribute value = property.attribute("value");
if (value != null) {
//如果是value就直接赋值
String name = property.attribute("name").getValue();
//通过id在map中获取bean对象
Object beanObj = beanMap.get(bean.attribute("id").getValue());
//通过名字找到属性,通过反射赋值
Field field = beanObj.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(beanObj, value.getValue());
}
//如果是ref,从Map中查找对象进行赋值
Attribute ref = property.attribute("ref");
if (ref!=null){
//通过ref找到需要注入到属性的对象
Object refObj = beanMap.get(ref.getValue());
//如果是value,直接赋值
String name = property.attribute("name").getValue();
//通过id在map中获得当前bean对象
Object beanObj = beanMap.get(bean.attribute("id").getValue());
//通过名字找到属性,通过反射赋值,将对象注入到属性中
Field field = beanObj.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(beanObj,refObj);
}
}
}
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
/**
* 获得JavaBean
* @param beanName
* @return
*/
public Object getBean(String beanName){
return beanMap.get(beanName);
}
}
重要代码介绍:
//保存javabean的集合 private Map<String, Object> beanMap = new HashMap<>();//定义hashmap,键存id value存对象。//通过类名.class创建反射对象,通过反射对象读取XML文件 Document doc = reader.read(MyXMLBeanFactory.class.getClassLoader().getResourceAsStream(fileName));//通过class属性,获得类型信息 String aClass = bean.attribute("class").getValue();Class<?> aClass1 = Class.forName(aClass);//Class.forName(类型信息)创建反射对象Object beanObj = aClass1.newInstance();//创建类的对象//读取bean节点中的property节点 List<Element> properties = bean.elements("property");for (Element property : properties) //通过迭代器遍历循环//通过id在map中获取bean对象 Object beanObj = beanMap.get(bean.attribute("id").getValue());//通过对象.getclass创建反射对象,通过名字找到属性,通过反射赋值 Field field = beanObj.getClass().getDeclaredField(name);//如果是ref,从Map中查找对象进行赋值 Attribute ref = property.attribute("ref");//通过ref找到需要注入到属性的对象,在XML中ref的值为类对象id的值 Object refObj = beanMap.get(ref.getValue());