0、目标
xml配置类的id和class
自己写一个ClassPathXmlApplicationContext 类,作为容器,能够读取、解析、创建、获取对象。
1、核心原理
ClassPathXmlApplicationContext 是主要实现类,它持有 类的定义登记册、以及 类初始化后对象的Map。
private List<BeanDefinition> beanDefinitions = new ArrayList<>();
private Map<String,Object> singletons = new HashMap<>();
当需要获取对象时,从Map中获取即可
public Object getBean(String beanName){
return singletons.get(beanName);
}
其中,BeanDefiniton是类的配置,核心为id和className。实际上就是对xml配置文件的封装。
public class BeanDefinition {
private String id,className;
public BeanDefinition(String id, String className) {
this.id = id;
this.className = 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;
}
}
2、实现步骤
创建xml文件,描述类名和路径
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id = "superman" class = "com.geek.minis.ioc01.Geek"></bean>
</beans>
解析xml
public void readXml(String fileName){
SAXReader saxReader = new SAXReader();
URL resource = this.getClass().getClassLoader().getResource(fileName);
Document document = null;
try {
document = saxReader.read(resource);
Element rootElement = document.getRootElement();
List<Element> elements = rootElement.elements();
for (Element element:elements){
String id = element.attributeValue("id");
String aClass = element.attributeValue("class");
BeanDefinition definition = new BeanDefinition(id,aClass);
beanDefinitions.add(definition);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
根据解析去创建对象
private void initBeans(){
for(BeanDefinition beanDefinition: beanDefinitions){
try{
singletons.put(beanDefinition.getId(),Class.forName(beanDefinition.getClassName()).newInstance());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
组装!初始化时就干完所有的事。
public ClassPathXmlApplicationContext(String xmlFileName) {
this.readXml(xmlFileName);
this.initBeans();
}
3、测试代码
public class Main {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");
SuperMan man = (SuperMan) classPathXmlApplicationContext.getBean("superman");
man.bang();
}
}
测试结果
结语
本专栏做一个简版的spring ,通过动手实践进一步理解ioc、aop、mvc、jdbcTemplate登。
项目代码分享在 https://github.com/forestnlp/minispring