反射结合xml简单的模拟spring创建bean
Posted bluedarkni
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射结合xml简单的模拟spring创建bean相关的知识,希望对你有一定的参考价值。
框架最底层其实就是通过反射实现的,就像spring,当你配置各种各样的bean时都是以配置文件的形式配置的,你需要用到哪些bean就配哪些,spring容器就会根据你的需求去动态加载,这儿写一个简单的例子模拟一下:
1.加深对反射的理解,
2.了解一下框架的实现的原理
3.通过dom4j对xml的解析
两个简单的类:
User:
public class User { private String userName; private String userPwd; private String userAge; public String getUserAge() { return userAge; } public void setUserAge(String userAge) { this.userAge = userAge; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } }
Student类:
public class Student { private String stuName; private String stuNo; public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public String getStuNo() { return stuNo; } public void setStuNo(String stuNo) { this.stuNo = stuNo; } }
配置xml文件:<bean-class>里面是类的包名+类名
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean> <bean-name>user</bean-name> <bean-class>com.bwf.test.User</bean-class> <init> <property name="userName">zhangsan</property> <property name="userAge">18</property> <property name="userPwd">123456</property> </init> </bean> <bean> <bean-name>user1</bean-name> <bean-class>com.bwf.test.User</bean-class> <init> <property name="userName">lisi</property> <property name="userPwd">654321</property> <property name="userAge">24</property> </init> </bean> <bean> <bean-name>student</bean-name> <bean-class>com.bwf.test.Student</bean-class> <init> <property name="stuName">wangwu</property> <property name="stuNo">1</property> </init> </bean> </beans>
解析xml为对象赋值及测试:
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.bwf.test.Student; import com.bwf.test.User; public class XMLRefelct { public static void main(String[] args) { try { readXML(); } catch (Exception e) { e.printStackTrace(); } } /** * 读xml 文件 * @throws Exception */ public static void readXML() throws Exception{ InputStream in = null; try { in = new FileInputStream(new File("src/spring.xml")); } catch (FileNotFoundException e) { e.printStackTrace(); } SAXReader reader = new SAXReader(); try { Document document = reader.read(in); //读xml Element root = document.getRootElement(); List<Element> beans = root.elements(); //获取xml中的所有<bean> for(Element bean : beans){ bean.element("bean-class").getStringValue(); //获取配置的类的全路径名 // <bean-class>com.bwf.test.User</bean-class> //System.out.println(bean.element("bean-class").getStringValue()); //通过全路径名 反射得到Class 对象 Class<?> c = Class.forName(bean.element("bean-class").getStringValue()); List<Element> properties = bean.element("init").elements("property");//获取配置里面的所有属性 Object o = c.newInstance(); //反射创建对象 for(Element property : properties){ //判断属性是否在类的属性中存在 并为对象初始化配置的值 o = checkPropertyEsxit(property.attribute("name").getStringValue(),o,c,property.getStringValue()); } test(o); //调用测试方法 } } catch (DocumentException e) { e.printStackTrace(); } } /** * 判断属性是否在类的属性中存在 并为对象初始化配置的值 * @param propertyName * @param o * @param c * @param propertyValue * @return */ public static Object checkPropertyEsxit(String propertyName,Object o ,Class<?> c,String propertyValue ){ Field[] fields = c.getDeclaredFields(); boolean isExsit = false;//初始化为不存在 for(Field field:fields){ if(field.getName().equals(propertyName)){ //说明属性存在 isExsit = true; //拼接set方法的规范名字 String setMethod = "set"+String.valueOf(field.getName().charAt(0)).toUpperCase()+ field.getName().substring(1); try { //获取set方法 Method m = c.getDeclaredMethod(setMethod, field.getType()); try { //调用set方法初始化属性的值 m.invoke(o, new Object[]{propertyValue}); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } } if(isExsit){ // System.out.println(propertyName+"存在"); }else{ // System.out.println(propertyName+"不存在"); try { throw new NoSuchFieldException(propertyName + "属性不存在" ); } catch (NoSuchFieldException e) { e.printStackTrace(); } } return o; } /** * 测试对象是否已经初始化 * @param o */ public static void test(Object o ){ if(o instanceof User){ User user = (User)o; System.out.println(user.getUserName()); System.out.println(user.getUserPwd()); System.out.println(user.getUserAge()); System.out.println("----------------"); }else if(o instanceof Student){ Student s = (Student)o; System.out.println(s.getStuNo()); } } }
结果:配置了两个user 一个 Student 输出了两个user的信息和student的信息
以上是关于反射结合xml简单的模拟spring创建bean的主要内容,如果未能解决你的问题,请参考以下文章