1. 原理
-
IOC从理论上来说,是一种代码维护优化方案。其实我们不用它也可以做软件,但是做出的软件维护代价太大,不利于二次开发,修改代码等。其实基本上所有的框架,设计模式,技术,都是为了让代码的结构更加清晰,更加易理解,更加易维护而出现的。
-
学过java的人都知道,对象与对象之间的关系是通过Object ob = new Object()这样的方式去产生关联关系,也许还有很多类似观察者模式这样的代码中存在一对多的关系。当我们代码量达到一定的程度后,对象与对象之间的代码耦合度越来越高,对维护产生了困难,甚至代码出现bug,你都无法在复杂的耦合中找到突破口。
-
所以出现了IOC,它统一的管理所有的对象,对象的创建过程,对象的生命周期等等,与使用它的对象脱离,使用者只需要告诉IOC,我需要什么样对象就好,其他的事不用管。这就是IOC的控制反转。类似相亲机构这样一个中间者的功能。
2. 代码分析
-
首先是流程,程序员通过注解,或者xml的方式告诉IOC,我需要什么样的对象,然后在代码中使用一个对象句柄进行接收即可。使用过Spring的人都是了解这个过程的不再赘述。
-
那么问题来了:
1.IOC是怎么创建对象的?
IOC是通过设计模式中工厂模式进行对所有对象的管理的,我在xml中配置的内容会被spring解析使用java的反射进行创建bean的过程。
<bean id="test" class="Test">
<property name="testMap">
<map>
<entry key="a">
<value>1</value>
</entry>
<entry key="b">
<value>2</value>
</entry>
</map>
</property>
</bean>
比如我们需要注入这样一个类那么spring是类似于这样去做的。
if (beanProperty.element("map") != null) {
Map<String, Object> propertiesMap = new HashMap<String, Object>();
Element propertiesListMap = (Element) beanProperty
.elements().get(0);
Iterator<?> propertiesIterator = propertiesListMap
.elements().iterator();
while (propertiesIterator.hasNext()) {
Element vet = (Element) propertiesIterator.next();
if (vet.getName().equals("entry")) {
String key = vet.attributeValue("key");
Iterator<?> valuesIterator = vet.elements()
.iterator();
while (valuesIterator.hasNext()) {
Element value = (Element) valuesIterator.next();
if (value.getName().equals("value")) {
propertiesMap.put(key, value.getText());
}
if (value.getName().equals("ref")) {
propertiesMap.put(key, new String[] { value
.attributeValue("bean") });
}
}
}
}
bean.getProperties().put(name, propertiesMap);
}
这里就是使用了Dom4j的技术解析xml文件进行对map的注入。然后就是使用反射创建类,我们配置的class属性就是反射需要的参数。
if (value instanceof Map) {
Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet()
.iterator();
Map<String, Object> map = new HashMap<String, Object>();
while (entryIterator.hasNext()) {
Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next();
if (entryMap.getValue() instanceof String[]) {
map.put((String) entryMap.getKey(),
getBean(((String[]) entryMap.getValue())[0]));
}
}
BeanProcesser.setProperty(obj, property, map);
}
- spring中的IOC的结构图:
我们开发中使用到的主要是ClasspathXmlApplictionContext这个类,我们一般都是把配置文件放在resource目录下的。
网友评论