【Spring】使用dom4j与反射实现Spring IOC

来源:互联网 发布:linux vsftpd 安装 编辑:程序博客网 时间:2024/06/08 00:42

使用dom4j解析xml文件,使用反射创建bean对象,再通过解析的属性name找到set方法,把value传进bean对象是Spring IOC的实现原理。

这里就用相同的方式手写代码实现Spring IOC。

配置文件

config.xml

<?xml version="1.0" encoding="UTF-8"?><beans><bean id="user1" class="com.duxd.user.User"><property name="ID" value="0001"/><property name="name" value="duxd1"/></bean><bean id="user2" class="com.duxd.user.User"><property name="ID" value="0002" /><property name="name" value="duxd2" /></bean></beans>

User.java

public class User {private String ID;private String name;public String getID() {return ID;}public void setID(String iD) {ID = iD;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void introduce() {System.out.println("ID:" + getID() + "---name:" + getName());}}

最后实现

ClassPathXmlApplicationContext.java

public class ClassPathXmlApplicationContext {private String xmlPath;public ClassPathXmlApplicationContext(String xmlPath) {// 传入配置文件名this.xmlPath = xmlPath;}public static void main(String[] args) {// 模仿Spring IOC写法ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");// obj强转成User对象User user = (User) context.getBean("user1");user.introduce();}public Object getBean(String beanID) {// 将要返回的Object对象Object obj = null;// dom4j解析器SAXReader saxReader = new SAXReader();Document read = null;try {// 读取根路径下的配置文件read = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));} catch (DocumentException e) {System.out.println("未找到路径下的配置文件");}if (read == null) {return null;}// 得到config.xml的根节点Element root = read.getRootElement();// 得到根节点的子节点List<Element> elements = root.elements();// 如果没有子节点,结束方法if (elements.size() <= 0) {System.out.println("没有子节点");return null;}// 找到指定id属性的bean节点Element element = null;// 循环遍历子节点for (int i = 0; i < elements.size(); i++) {element = elements.get(i);// 如果子节点中没有bean节点,结束方法if (!element.getName().equals("bean")) {System.out.println("未找到bean节点");return null;}// 得到bean节点的id的valueString id = element.attributeValue("id");// 如果有和传入的请求一样的id属性的bean,跳出循环if (!id.equals(beanID)) {if (i < elements.size() - 1) {continue;} else {System.out.println("未找到对应id属性的bean节点");return null;}}break;}// 得到对应id属性的bean节点中的class属性String beanClass = element.attributeValue("class");Class<?> forName = null;try {// 通过反射得到并创建指定class的对象forName = Class.forName(beanClass);obj = forName.newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {// 如果指定class文件没有System.out.println("未找到指定class");return null;}// 得到指定的bean节点的属性List<Element> elements2 = element.elements();// 如果没有子节点,结束方法if (elements2.size() <= 0) {return null;}// 遍历bean节点属性for (Element element2 : elements2) {String name = element2.attributeValue("name");String value = element2.attributeValue("value");Field declaredField;try {// 通过属性name和反射得到User的set方法declaredField = forName.getDeclaredField(name);// 配置反射得到操作private变量的权限declaredField.setAccessible(true);// 将value值set到obj中declaredField.set(obj, value);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}// 返回objreturn obj;}}

结果

ID:0001---name:duxd1


原创粉丝点击