在学习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!
注:以上文章仅是个人学习过程总结,若有不当之处,望不吝赐教。