模拟Spring IOC的简易实现
IOC是Inversion of Control的缩写,即控制反转,是一个种面向对象的编程和设计思想。主要目的:解耦
即对象不是自己new出来的,而是由框架来生成的(工厂)。
下面来简单模拟一下Spring获得bean的过程
首先需要一个外部配置的xml以及bean所对应的具体类。
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="items" class="com.easzz.ioc.Items"/>
<bean id="users" class="com.easzz.ioc.Users">
<property name="userName" value="mike"/>
</bean>
</beans>
public interface UniversalApp {
void add();
}
/**
* Created by easzz on 2017/8/30 9:46
*/
public class Users implements UniversalApp {
private String userName;
@Override
public void add() {
System.out.println("userName is "+userName);
}
}
/**
* Created by easzz on 2017/8/30 9:29
*/
public class Items implements UniversalApp{
@Override
public void add() {
System.out.println("item add...");
}
}
下面定义一个接口BeanFactory,用于获得bean。
public interface BeanFactory {
Object getBean(String id);
}
Ioc容器,context,用于存储bean,通过解析xml,使用反射获取其对象,将bean对象和它的id放入一个map中。需要使用的时候get即可。
/**
* Created by easzz on 2017/8/30 9:30
*/
public class XmlContext implements BeanFactory {
//bean context
private Map<String, Object> context = new HashMap<>();
public XmlContext(String xmlName) {
SAXReader saxReader = new SAXReader();
try {
Document read = saxReader.read(this.getClass()
.getClassLoader().getResourceAsStream(xmlName));
Element rootElement = read.getRootElement();
Iterator iterator = rootElement.elementIterator();
while (iterator.hasNext()){
Element next = (Element)iterator.next();
Object o=null;
if ("bean".equals(next.getName())){
String id = next.attributeValue("id");
String className = next.attributeValue("class");
Class<?> aClass = Class.forName(className);
Iterator iterator1 = next.elementIterator();
while (iterator1.hasNext()){
Element next1 = (Element) iterator1.next();
if ("property".equals(next1.getName())){
//设置属性值
String name = next1.attributeValue("name");
String value = next1.attributeValue("value");
o = aClass.newInstance();
Field declaredField = aClass.getDeclaredField(name);
//允许访问私有属性
declaredField.setAccessible(true);
declaredField.set(o,value);
declaredField.setAccessible(false);
}
}
context.put(id, o);
}
}
} catch (IllegalAccessException | InstantiationException | ClassNotFoundException | DocumentException | NoSuchFieldException e) {
e.printStackTrace();
}
}
@Override
public Object getBean(String id) {
return context.get(id);
}
}
编写测试类
public class Test {
public static void main(String[] args){
BeanFactory beanFactory=new XmlContext("beans.xml");
//由Ioc容器帮我们创建对象,注入依赖。
Users users = (Users) beanFactory.getBean("users");
users.add();
}
}
输出
userName is mike
正确的获取到了xml里面所定义的bean以及依赖(userName)…