- IOC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。
2.对象多了之后,对象之间的关系依赖度非常高,维护起来成本高,迁一发动全身
3.IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”。 1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了IOC 这个概念。对于面向对象设计及编程的基本思想,前面我们已经讲了很多了,不再赘述,简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦,如下图:
大家看到了吧,由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。
4.IOC的好处是解耦 IOC原理:把创建、销毁、维护对象依赖关系,由原来服务调用方反转到第三方,如Spring IOC容器 IOC容器在启动时主要利用反射将所有被管理的对象纳入管理,并利用DI将被依赖的对象注入
5.IOC与DI区别:IOC是理论基础,DI是实现
6.用代码模拟IOC的原理
public interface UserDao {
void save();
}
public class UserDaoImpl implements UserDao{
public void save() {
System.out.println("save user ...");
}
}
public interface UserService {
void save();
}
public class UserServiceImpl implements UserService{
private UserDao userDao;
//通过set方法注入依赖属性
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void save(){
System.out.println("call userDao.save...");
userDao.save();
}
}
创建bean.xml
<beans>
<bean id="userDao" class="cn.bintools.service.UserDaoImpl"></bean>
<bean id="userService" class="cn.bintools.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
创建BeanFactory
public class BeanFactory {
private Map<String, Object> singleObjects = new ConcurrentHashMap<>();
public void start(String xml) throws DocumentException, ClassNotFoundException, IllegalAccessException, InstantiationException {
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xml);
SAXReader reader = new SAXReader();
Document read = reader.read(inputStream);
Element rootElement = read.getRootElement();
List elements = rootElement.elements();
Iterator iterator = elements.iterator();
while (iterator.hasNext()) {
DefaultElement defaultElement = (DefaultElement) iterator.next();
Attribute aClass = defaultElement.attribute("class");
Attribute idAttr = defaultElement.attribute("id");
String className = aClass.getValue();
Object bean = null;
try {
bean = Class.forName(className).newInstance();
singleObjects.put(idAttr.getValue(), bean);
} catch (Exception ex) {
ex.printStackTrace();
}
List properties = defaultElement.elements();
if (properties != null && properties.size() > 0) {
Iterator innerIterator = properties.iterator();
while (innerIterator.hasNext()) {
DefaultElement property = (DefaultElement) innerIterator.next();
Attribute nameAttr = property.attribute("name");
Attribute refAttr = property.attribute("ref");
if (nameAttr == null || refAttr == null) {
continue;
}
String refName = refAttr.getValue();
String value = nameAttr.getValue();
//拼接属性对应的set方法
String setMethod = "set" + value.substring(0, 1).toUpperCase() + value.substring(1);
try {
//获取相应属性对应字段的类型
Class<?> fieldType = Class.forName(className).getDeclaredField(value).getType();
//反映调用set方法填入引用的属性
Class.forName(className).getMethod(setMethod,fieldType).invoke(bean, singleObjects.get(refName));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public Object getBean(String className) {
return singleObjects.get(className);
}
}
开始测试
public class Client {
public static void main(String[] args) throws Exception{
BeanFactory factory = new BeanFactory();
factory.start("bean.xml");
UserService userService = (UserService) factory.getBean("userService");
userService.save();
}
}
结果:
call userDao.save...
save user ...