使用DOM和java反射实现简单的SpringIOC

在网上看了很多大神写的关于springIOC的博客,有很多都写的十分的深入,而且将IOC和DI讲的也很透彻,但是对于我们这些理论知识不是太好的小白来说,还是有些复杂了。所以今天我使用java的反射写一个简单版的springIOC的实现原理,很简单的删节版本哦。

首先我们谈谈什么是IOC,什么又是DI。(摘抄的网上解释)ioc(inverse of control )控制反转:所谓控制反转就是把对象(bean)对象和维护对象(bean)之间的关系的权利转移到Sqring容器中去了(ApplicationContext.xml)而程序本身不在维护了。di(dependency injection)依赖注入:实际上DI和IOC是同一个概念,因为在ApplicationContext.xml配置文件中bean和bean之间通过ref来维护的时候是相互依赖的,所以又叫做依赖注入。也就是控制反转。

直接上代码:

public class User {

	private String userId;
	
	private String userName;

	public User(){
		
	}
	
	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
	
}
<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean id="user1" class="com.lzf.test.User">
		<property name="userId" value="0001"></property>
		<property name="userName" value="小明"></property>
	</bean>
	<bean id="user2" class="com.lzf.test.User">
		<property name="userId" value="0002"></property>
		<property name="userName" value="张三"></property>
	</bean>
</beans>

上面是事先准备好的一个bean和xml。

public class ClassPathXmlApplicationContext {
	private String xmlPath;
	
	public ClassPathXmlApplicationContext(String xmlPath){
		this.xmlPath = xmlPath;
	}
	
	public Object getBean(String beanId) throws DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException{
		
		//1.解析xml
		SAXReader saxReader = new SAXReader();
		Document read = saxReader.read(this.getClass().getClassLoader().getResource(xmlPath));
		//如果read为null则返回
		if(read==null){
			return null;
		}
		//2.获取里面Dom
		//获取根节点的dom
		Element rootElement = read.getRootElement();
		//获取其节点下的集合
		List<Element> elements = rootElement.elements();
		if(elements.size()<=0){
			return null;
		}
		Object obj = null;
		for (Element element : elements) {
			String id = element.attributeValue("id");
			//如果id为空
			if(StringUtils.isEmpty(id)){
				return null;
			}
			//如何id不为beanId
			if(!id.equals(beanId)){
				continue;
			}
			//获取bean的class
			String Beanclass = element.attributeValue("class");
			//反射获取Class
			Class<?> forName = Class.forName(Beanclass);
			//实例化类
			obj = forName.newInstance();
			//获取子节点的集合
			List<Element> elements2 = element.elements();
			for (Element element2 : elements2) {
				//获取xmlbean里的name和value
				String name = element2.attributeValue("name");
				String value = element2.attributeValue("value");
				//为User类注入xml里的值
				Field nameUser = forName.getDeclaredField(name);
				//设置为可写
				nameUser.setAccessible(true);
				nameUser.set(obj, value);
			}
		}
		return obj;
	}
	
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, DocumentException {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("user.xml");
		User user = (User)applicationContext.getBean("user1");
		System.out.println("userName:"+user.getUserName()+"----"+"userId:"+user.getUserId());
	}
}

实际上springIOC最浅的实现原理就是解析xml然后使用java的反射机制将读取到的数据返回给bean。当然实际上的spring写的要复杂的多。我也只是为了更好的理解它,才做了简化。使用getBean我们就能拿到自己想要的实体类了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值