用java的spring实现一个简单的IOC容器示例代码
发布时间 - 2026-01-10 23:27:46 点击率:次要想深入的理解IOC的技术原理,没有什么能比的上我们自己实现它。这次我们一起实现一个简单IOC容器。让大家更容易理解Spring IOC的基本原理。

这里会涉及到一些java反射的知识,如果有不了解的,可以自己去找些资料看看。
注意
在上一篇文章,我说,启动IOC容器时,Spring会将xml文件里面配置的bean扫描并实例化,其实这种说法不太准确,所以我在这里更正一下,xml文件里面配置的非单利模式的bean,会在第一次调用的时候被初始化,而不是启动容器的时候初始化。但是我们这次要做的例子是容器启动的时候就将bean初始化。特此说明一下,害怕误导初学者。
现在我们开始做一个简单的IOC容器
思路:
1,启动容器时,加载xml文件。
2,读取xml文件内的bean信息,并使用反射技术将bean实例化,并装入容器。
3,确认bean之间的以来关系,进行注入。
下面直接上代码,先看配置文件,与上一篇文章中使用的例子是一样的,我们这次继续使用上一篇文章的吃苹果和吃橘子的例子,只不过这次我们用我们自己写的IOC容器,所以,我只粘贴了关键代码。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--这是吃橘子的Bean -->
<bean id="eatOrange" class="it.spring.liao.com.EatOrange"></bean>
<!--这是吃苹果的Bean -->
<bean id="eatApple" class="it.spring.liao.com.EatApple"></bean>
<bean id="person" class="it.spring.liao.com.Person">
<!-- 这里我们注入的是吃橘子的bean-->
<property name="eat" ref="eatOrange"/>
</bean>
</beans>
此处为关键代码
package it.spring.liao.com;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class BeanFactory {
// 用于存放bean实例的集合
private Map<String, Object> beanMap = new HashMap<String, Object>();
/**
* bean工厂的初始化. <br>
*
* @param xml
* 配置文件路径
*/
public void init(String xml) {
try {
// 1.创建读取配置文件的reader对象
SAXReader reader = new SAXReader();
// 2.获取当前线程中的类装载器对象
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// 3.从class目录下获取指定的xml文件
InputStream ins = classLoader.getResourceAsStream(xml);
// 4.使用dom4j 解析xml文件
Document doc = reader.read(ins);
Element root = doc.getRootElement();
// 5.初始化bean
setBean(root);
// 6.注入bean的依赖关系
setPv(root);
} catch (Exception e) {
System.out.println(e.toString());
}
}
/**
* 初始化bean
*
* @param root
* xml文件
* @throws Exception
*/
public void setBean(Element root) throws Exception {
// 1.遍历xml文件当中的Bean实例
for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
Element foo = (Element) i.next();
// 2.针对每个Bean实例,获取bean的属性id和class
String id = foo.attribute("id").getText();
String cls = foo.attribute("class").getText();
// 3.利用Java反射机制,通过class的名称获取Class对象
Class bean = Class.forName(cls);
// 4.创建对象
Object obj = bean.newInstance();
// 5.将对象放入beanMap中,其中key为bean的id值,value为bean的实例
beanMap.put(id, obj);
}
}
/**
* 注入bean的依赖关系
*
* @param root
* xml文件
* @throws Exception
*/
public void setPv(Element root) throws Exception {
for (Iterator it = root.elementIterator("bean"); it.hasNext();) {
Element foo = (Element) it.next();
// 1.针对每个Bean实例,获取bean的属性id和class
String cls = foo.attribute("class").getText();
String id = foo.attribute("id").getText();
// 2.利用Java反射机制,通过class的名称获取Class对象
Class bean1 = Class.forName(cls);
// 3.获取对应class的信息
java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean1);
// 4.获取其属性描述
java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
// 5遍历该bean的property属性
for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
Element foo2 = (Element) ite.next();
// 6.获取该property的name属性
String name = foo2.attribute("name").getText();
String ref = foo2.attribute("ref").getText();
// 7.在类中寻找与xml配置文件中该bean的property属性名相同的属性
for (int k = 0; k < pd.length; k++) {
// 8.如果相等,证明已经找到对应得属性
if (pd[k].getName().equalsIgnoreCase(name)) {
Method mSet = null;
// 9.利用反射,获取该属性的set方法
mSet = pd[k].getWriteMethod();
// 10.用原beanMap中该bean的实例,执行该属性的set方法,并从原beanMap中获取该属性的依赖值
mSet.invoke(beanMap.get(id), beanMap.get(ref));
}
}
break;
}
}
}
/**
* 通过bean的id获取bean的实例
*
* @param beanName
* bean的id
* @return 返回对应对象
*/
public Object getBean(String beanName) {
Object obj = beanMap.get(beanName);
return obj;
}
}
/**
* 测试方法.
*
* @param args
*/
public static void main(String[] args) {
//使用我们自己写的 BeanFactory
BeanFactory factory = new BeanFactory();
factory.init("eat.xml");
Person javaBean = (Person) factory.getBean("person");
System.out.println(javaBean.eat());
}
详细的解释都在代码的注释中,这个例子可以帮助你更深刻的理解spring的基本技术原理。但Spring的复杂程度远远高于这个例子,再说一次,spring IOC中使用懒加载机制,在启动spring IOC时,只会实例化单例模式的bean,不会实例化普通的bean,关于单例模式还是其他模式,是可以自己配置的,我们会在后面的文章中讲解,非单例模式bean的实例化,发生在第一次调用的时候,与我们这个例子不太一样。这个例子只供了解Spring IOC的基本原理,真实情况要复杂的多,需要我们一点点的去学习,不积跬步无以至千里。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# spring
# ioc容器
# ioc
# 简单实现
# spring的ioc容器
# 使用Java反射模拟实现Spring的IoC容器的操作
# Java基础之Spring5的核心之一IOC容器
# 使用Java注解模拟spring ioc容器过程解析
# 深入理解java的spring-ioc的使用
# Spring学习笔记1之IOC详解尽量使用注解以及java代码
# 深入理解Java的Spring框架中的IOC容器
# 浅析Java的Spring框架中IOC容器容器的应用
# 一篇文章带你了解Java Spring基础与IOC
# 配置文件
# 这是
# 不太
# 遍历
# 会在
# 上一
# 基本原理
# 的是
# 加载
# 我说
# 都在
# 我只
# 没有什么
# 去找
# 只会
# 要想
# 要做
# 做一个
# 千里
# 不了解
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Python函数文档自动校验_规范解析【教程】
js代码实现下拉菜单【推荐】
如何快速查询网站的真实建站时间?
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网
智能起名网站制作软件有哪些,制作logo的软件?
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权
Laravel如何发送系统通知?(Notification渠道示例)
使用C语言编写圣诞表白程序
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
高端网站建设与定制开发一站式解决方案 中企动力
原生JS实现图片轮播切换效果
java中使用zxing批量生成二维码立牌
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
Linux安全能力提升路径_长期防护思维说明【指导】
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
如何在云主机上快速搭建多站点网站?
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
非常酷的网站设计制作软件,酷培ai教育官方网站?
如何用y主机助手快速搭建网站?
长沙企业网站制作哪家好,长沙水业集团官方网站?
Laravel如何使用查询构建器?(Query Builder高级用法)
如何在七牛云存储上搭建网站并设置自定义域名?
Laravel如何实现一对一模型关联?(Eloquent示例)
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
怎样使用JSON进行数据交换_它有什么限制
免费视频制作网站,更新又快又好的免费电影网站?
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
潮流网站制作头像软件下载,适合母子的网名有哪些?
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化
Laravel如何处理文件下载请求?(Response示例)
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
如何为不同团队 ID 动态生成多个独立按钮
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
实例解析Array和String方法
android nfc常用标签读取总结
Laravel如何使用Eloquent进行子查询
装修招标网站设计制作流程,装修招标流程?
如何快速上传建站程序避免常见错误?
专业商城网站制作公司有哪些,pi商城官网是哪个?
如何在景安服务器上快速搭建个人网站?
香港服务器网站推广:SEO优化与外贸独立站搭建策略
在线制作视频的网站有哪些,电脑如何制作视频短片?
如何获取上海专业网站定制建站电话?
Laravel Session怎么存储_Laravel Session驱动配置详解
如何基于PHP生成高效IDC网络公司建站源码?
上一篇:NAT原理与配置详解
上一篇:NAT原理与配置详解

