Spring_IOC底层实现模拟

在学习spring一开始,书上就会提及spring中ioc(控制反转)和aop(面向切面)是两个重点内容。

那么究竟什么是ioc呢,下面就简单总结一下ioc:(ps:关于spring的aop及其他知识将下后续文章总结)

IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。IOC的理解

那么接下来就开始我们的模拟:

User.java:

package h.l.ioc;

public class User {// 用户类

	private String username;// 账号
	private String password;// 密码
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public User(String username, String password) {
		super();
		this.username = username;
		this.password = password;
	}
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "User [username=" + username + ", password=" + password + "]";
	}

}

IOC.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean id="user2" class="club.j208.demo.User2"></bean>
	<bean id="user" class="h.l.ioc.User"></bean>
</beans>

IOCByself.java:

/**   
* @Title: IOCByself.java 
* @Package h.l.ioc 
* @Description: 模拟spring中IOC底层实现
* @author HL
* @version V1.0   
*/
package h.l.ioc;

import java.io.File;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/************************************************************************
 * 1、使用dom4j解析xml配置文件 2、获取配置文件中指定bean的class属性 3、得到属性值使用反射创建对象 *
 ***********************************************************************/
public class IOCByself {

	// 解析XML文件
	public Document parseXML(File file) {
		SAXReader saxReader = new SAXReader();
		Document document = null;
		try {
			document = saxReader.read(file);
		} catch (DocumentException e) {
			System.out.println(e.getMessage());
		}
		return document;
	}

	/**
	 * bean的格式<bean id="" class=""/>
	 * 
	 * @param beanId传入bean的id
	 * @return 创建bean的id对应的类的对象
	 */
	public Object getService(String beanId) {
		Document document = parseXML(new File("src/h/l/ioc/IOC.xml"));
		Element root = document.getRootElement();
		String className="";
		for (Iterator<Element> it = root.elementIterator(); it.hasNext();) {
			Element element = it.next();
			if(element.valueOf("@id").equals(beanId)) {
				className=element.valueOf("@class");
			}
		}
		Object object=null;
		try {
			Class<?> clazz=Class.forName(className);
			object=clazz.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return object;
	}
}

 IOCByselfTest.java:

/**   
* @Title: IOCByselfTest.java 
* @Package h.l.ioc 
* @Description: 测试
* @author HL
* @version V1.0   
*/
package h.l.ioc;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class IOCByselfTest {

	IOCByself iocByself = null;
	@BeforeEach
	void setUp() throws Exception {
		iocByself = new IOCByself();
	}

	@Test
	void test() {
		User user = (User) iocByself.getService("user");
		user.setUsername("Is-Me-HL");
		user.setPassword("root");
		System.out.println(user);
	}

}

OK,Just do it!


注:以上文章仅是个人学习过程总结,若有不当之处,望不吝赐教。

猜你喜欢

转载自blog.csdn.net/m0_37265215/article/details/84433865