简单IOC1
IoC容器,也就是BeanFactory,存在的意义就是将创建对象与使用对象的业务代码解耦,让业务开发人员无需关注底层对象
(Bean)的构建和声明周期的管理,专注于业务开发。
简单IoC容器非常原始和简单,一个部件来对应Bean内存的映像;一个XML Reader负责从外部XML文件中读取Bean的配置;
一个反射部件,负责加载Bean Class并且创建这个实例;创建好实例后,用一个Map来保存Bean的实例;提供一个getBean方法供外部使用。

ioc-1.png
- 构建BeanDefinition
public class BeanDefinition {
private String id;
private String className;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public BeanDefinition(String id, String className) {
this.id = id;
this.className = className;
}
}
- 定义BeanFactory
此接口拥有2个方法
1)获取一个Bean getBean()
- 注册一个BeanDefinition registerBeanDefinition
public interface BeanFactory {
Object getBean(String beanName) throws NoSuchBeanDefinitionException;
void registerBeanDefinition(BeanDefinition bd);
}
定义Resource
把外部配置信息都当成Resource(资源)来进行抽象
public interface Resource extends Iterator<Object> {
}定义ClassPathXmlResource
目前数据来源都比较单一,读取的都是XML文件配置
public class ClassPathXmlResource implements Resource {
Document document;
Element rootElement;
Iterator<Element> elementIterator;
public ClassPathXmlResource(String fileName) {
SAXReader saxReader = new SAXReader();
URL xmlPath = this.getClass().getClassLoader().getResource(fileName);
try {
this.document = saxReader.read(xmlPath);
this.rootElement = document.getRootElement();
this.elementIterator = this.rootElement.elementIterator();
} catch (DocumentException e) {
e.printStackTrace();
}
}
@Override
public boolean hasNext() {
return this.elementIterator.hasNext();
}
@Override
public Object next() {
return this.elementIterator.next();
}
}
- 定义XmlBeanDefinitionReader
如何把解析好的XML转换成BeanDefinition呢?就是通过XmlBeanDefinitionReader
public class XmlBeanDefinitionReader {
BeanFactory bf;
public XmlBeanDefinitionReader(BeanFactory bf) {
this.bf = bf;
}
public void loadBeanDefinition(Resource res) {
while (res.hasNext()) {
Element element = (Element) res.next();
String beanID = element.attributeValue("id");
String beanClassName = element.attributeValue("class");
BeanDefinition beanDefinition = new BeanDefinition(beanID, beanClassName);
this.bf.registerBeanDefinition(beanDefinition);
}
}
}
- BeanFactory的简单实现
public class SimpleBeanFactory implements BeanFactory {
private List<BeanDefinition> beanDefinitions = new ArrayList<>();
private List<String> beanNames = new ArrayList<>();
private Map<String, Object> singletons = new HashMap<>();
public SimpleBeanFactory() {}
@Override
public Object getBean(String beanName) throws NoSuchBeanDefinitionException {
Object singleton = singletons.get(beanName);
if (singleton == null) {
int i = beanNames.indexOf(beanName);
if (i == -1) {
throw new NoSuchBeanDefinitionException();
} else {
BeanDefinition bd = beanDefinitions.get(i);
try {
singleton = Class.forName(bd.getClassName()).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
singletons.put(bd.getId(), singleton);
}
}
return singleton;
}
@Override
public void registerBeanDefinition(BeanDefinition bd) {
this.beanDefinitions.add(bd);
this.beanNames.add(bd.getId());
}
}
- 定义ClassPathXmlApplicationContext
public class ClassPathXmlApplicationContext implements BeanFactory {
BeanFactory beanFactory;
public ClassPathXmlApplicationContext(String fileName) {
Resource res = new ClassPathXmlResource(fileName);
BeanFactory bf = new SimpleBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
reader.loadBeanDefinition(res);
this.beanFactory = bf;
}
@Override
public Object getBean(String beanName) throws NoSuchBeanDefinitionException {
return this.beanFactory.getBean(beanName);
}
@Override
public void registerBeanDefinition(BeanDefinition bd) {
this.beanFactory.registerBeanDefinition(bd);
}
}
测试:
1)定义XML配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="aservice" class="com.minis.test.AServiceImpl"></bean>
</beans>
- 定义接口和类
package com.minis.test;
public interface AService {
void sayHello();
}
package com.minis.test;
public class AServiceImpl implements AService {
@Override
public void sayHello() {
System.out.println("a service 1 say hello.");
}
}
测试IOC-1.PNG
参考:极客时间 手把手带你写一个MiniSpring,以上是学习过程中的记录。