IOC遵循是Spirng中对依赖倒转原则的原则,依赖倒转原则告诉我们:
- 上层模块不应该依赖底层模块,他们都应该依赖于抽象
- 抽象不应该依赖于细节,细节应该依赖于抽象
先读取bean的XML配置文件,然后使用beanId查找bean配置,并获取配置文件中class地址,得到地址后使用Java反射技术实例化对象,最后获取属性配置,使用反射技术进行赋值。
详细步骤:
利用传入的参数获取xml文件的流,并且利用dom4j解析成Document对象
对于Document对象获取根元素对象后对下面的标签进行遍历,判断是否有符合的id.
如果找到对应的id,相当于找到了一个Element元素,开始创建对象,先获取class属性,根据属性值利用反射建立对象.
遍历标签下的property标签,并对属性赋值.注意,需要单独处理int,float类型的属性.因为在xml配置中这些属性都是以字符串的形式来配置的,因此需要额外处理.
如果属性property标签有ref属性,说明某个属性的值是一个对象,那么根据id(ref属性的值)去获取ref对应的对象,再给属性赋值.
返回建立的对象,如果没有对应的id,或者下没有子标签都会返回null
applicationContext.xml的文件定义:
1 2 3 4 5 6 7 8 9 10 11 12
| <beans> <bean id="user1" class = "com.wzl.ioc.User"> <property name ="userId" value = "0001"></property> <property name = "userName" value="无知狼"></property> </bean>
<bean id="user2" class = "com.wzl.ioc.User"> <property name ="userId" value = "0002"></property> <property name = "userName" value="无知猫"></property> </bean> </beans>
|
代码的实现逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| package com.wzl.ioc;
import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.springframework.util.StringUtils;
import java.lang.reflect.Field; import java.util.List;
public class ClassPathXmlApplicationContext {
private String pathXml = null;
public ClassPathXmlApplicationContext(String pathXml) { this.pathXml = pathXml; }
public Object getBean(String beanId) throws Exception { if (StringUtils.isEmpty(beanId)) { throw new Exception("beanId is null"); } SAXReader saxReader = new SAXReader(); Document read = saxReader.read(this.getClass().getClassLoader().getResource(pathXml));
Element rootElemement = read.getRootElement(); List<Element> elements = rootElemement.elements(); for (Element element : elements) { String id = element.attributeValue("id"); if (StringUtils.isEmpty(id)) { continue; } if (!id.equals(beanId)) { continue; }
String beanClass = element.attributeValue("class"); Class<?> forName = Class.forName(beanClass); Object newInstance = forName.newInstance(); List<Element> propertyElementList = element.elements(); for (Element el : propertyElementList) { String name = el.attributeValue("name"); String value = el.attributeValue("value"); Field declaredField = forName.getDeclaredField(name); declaredField.setAccessible(true); declaredField.set(newInstance, value); } return newInstance; } return null; }
public static void main(String[] args) { ClassPathXmlApplicationContext classPath = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = null; try { user = (User) classPath.getBean("user2"); } catch (Exception e) { e.printStackTrace(); } System.out.println(user.getUserId() + user.getUserName());
}
}
|