用那么多年spring,一直对spring容器是如何实现的感到神秘,今天自己手撕一个spring ioc容器 感觉很简单,适合入门理解。
主要用到xml的解析 和 反射
public class BeanUtil {
private static Map<String, Object> beans = new HashMap<String, Object>();
private static void parse() {
// 获取项目根路径下的配置文件
Resource resource = new ClassPathResource("applicationContext.xml");
File file;
try {
file = resource.getFile();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(file);
NodeList employees = document.getChildNodes();
for (int i = 0; i < employees.getLength(); i++) {
Node employee = employees.item(i);
NodeList employeeInfo = employee.getChildNodes();
for (int j = 0; j < employeeInfo.getLength(); j++) {
Node node = employeeInfo.item(j);
String nodeName = node.getNodeName();
// 解析二级标签 即 beans 下的 bean
if ("bean".equals(nodeName)) {
NamedNodeMap attributes = node.getAttributes();
Node beanName = attributes.getNamedItem("id");
Node cl = attributes.getNamedItem("class");
String name = beanName.getNodeValue();
String clazzName = cl.getNodeValue();
System.out.println(name + " :: " + clazzName);
// 利用反射 获取class对象
Class<?> clazz = Class.forName(clazzName);
//获取 指定class的实例
Object instance = clazz.newInstance();
//将去放入map 相当于一级缓存 也可以放入到redis 等 缓存工具
beans.put(name, instance);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
public static Object getBean(String beanName) {
parse();
return beans.get(beanName);
}
}
这里只是简单的实现解析配置文件里的bean,对于context:componte-scan并没有实现 下期将会实现 本例有不明白的地方可以加企鹅:2624112814