spring 简单模拟 ioc

身为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.指定DocumentBuilder

DocumentBuilder 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 exception

logger.info("解析配置文件错误");

}

}

public Object getBean(String id) {

// TODO Auto-generated method stub

return 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的前沿技术,各种开源框架的解析陆续推出,谢谢大家了,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值