spring 简单模拟 ioc

来源:互联网 发布:淘宝sony嘉诚 编辑:程序博客网 时间:2024/05/17 23:53

身为java程序员,spring 或多或少的接触,但是我们经常从spring这个大容器里获取的bean到底是怎么获取的呢?小编给你分析一波

首先定义一个BeanFactory,模拟spring的工厂

package com.dingjianlei.spring.ioc;public interface BeanFactory {public Object getBean(String id);}


这是声明了一个BeanFactory,模拟一下spring的bean工厂(ps:当然spring那庞大的spi需要读者自己理清。。。)

定义 ClassPathApplicationContext 模拟spring的 ClassPathXmlApplicationContext 继承BeanFactory, ClassPathApplicationContext 这个类里面自定义读取xml配置文件的代码

package com.dingjianlei.spring.ioc;import java.io.File;import java.io.InputStream;import java.net.URL;import java.util.concurrent.ConcurrentHashMap;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;/*** 自定义beanFactory 获取自定义xml bean 放入ConcurrentHashMap,防止多线程进行读取** @author 丁建磊**/public class ClassPathApplicationContext implements BeanFactory {private ConcurrentHashMap<String, Object> beans = new ConcurrentHashMap<String, Object>();private final String rootElementName = "bean";// 根节点private Logger logger = LoggerFactory.getLogger(ClassPathApplicationContext.class);public ClassPathApplicationContext() {try {// 1.创建解析工厂:DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 2.指定DocumentBuilderDocumentBuilder db = factory.newDocumentBuilder();// 3.从文件构造一个Document,因为XML文件中已经指定了编码,所以这里不必了ClassLoader classLoader = ClassPathApplicationContext.class.getClassLoader();InputStream resourceAsStream = classLoader.getResourceAsStream("beans.xml");Document doc = db.parse(resourceAsStream);// 获取根节点Element root = doc.getDocumentElement();NodeList nodeList = root.getElementsByTagName(rootElementName);if (nodeList != null) {for (int i = 0; i < nodeList.getLength(); i++) {if (nodeList.item(i).getNodeType() == Element.ELEMENT_NODE) {Element item = (Element) nodeList.item(i);String attribute = item.getAttribute("id");String clazz = item.getAttribute("class");Object o = Class.forName(clazz).newInstance();beans.put(attribute, o);}}}} catch (Exception e) {// TODO: handle exceptionlogger.info("解析配置文件错误");}}public Object getBean(String id) {// TODO Auto-generated method stubreturn beans.get(id);}}


模拟读取spring的applicationContext.xml文件,里面需要的技术dom解析xml。

最后,定义一个测试类,运行一下我们的程序

package com.dingjianlei.spring.ioc;import com.dingjianlei.service.DaoService;public class IOC {public static void main(String[] args) {ClassPathApplicationContext context =new ClassPathApplicationContext();DaoService daoService=(DaoService) context.getBean("stuDao");daoService.getDao();}}


以上就是我们自定义模拟spring的ioc简单版实现,对于我们理解spring的依赖注入很有帮助,搞明白的小伙伴们自己试试吧。最后喜欢的小伙伴来波关注,我会定期分享javaweb的前沿技术,各种开源框架的解析陆续推出,谢谢大家了,