本文主要的内容就是用自己的代码实现spring下面的代码功能:
1. 确定有两个类,一个是Course,一个是Student,Course由名称、学分、描述组成。Student由学号、名字、课程组成。现在要先建一个Course然后把这个类作为Student的Course属性。
Course.java
package entity; public class Course { private String name; private long credit; private String desc; public Course() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getCredit() { return credit; } public void setCredit(long credit) { this.credit = credit; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
//Student.java: package entity; public class Student { private String NO; private String name; private Course course; public String getNO() { return NO; } public void setNO(String nO) { NO = nO; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } }
2 在bean.xml中写上bean的信息,我改了一下xml的名字,现在是conf.xml,name和class都是必要的,而children节点的property就是这个bean的一些属性。property中的param指这个属性的名字,text的部分是value。
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="mathCourse" class="entity.Course"> <property param="name">math</property> <property param="credit">5</property> <property param="desc"> 数学 </property> </bean> <bean id="stud0" class="entity.Student"> <property param="NO">000</property> <property param="name">stud0</property> <property param="course" ref="mathCourse">mathCourse</property> </bean> </beans>
package entity; public class Property { private String name; private boolean ref; private String value; public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isRef() { return ref; } public void setRef(boolean ref) { this.ref = ref; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
4.通过解析这个xml获得写在里面的信息。这里使用dom4j
public static Map<String, Property> getBeanParams(Element bean) { Map<String, Property> map = new HashMap<String, Property>(); for (Iterator<Element> beanIt = bean.elementIterator(); beanIt .hasNext();) { Element property = beanIt.next(); Property p = new Property(); p.setName(property.attribute("param").getStringValue()); p.setRef(property.attribute("ref") == null ? false : true); p.setValue(property.getTextTrim()); map.put(property.attribute("param").getStringValue(), p); } return map; }
5.使用java的反射对对象的属性进行赋值。可以通过两种方法,一种是直接通过访问属性,另一种就是使用方法就是setXXX(value),当然也可以用构造函数,用起来不是一般的麻烦。
package reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; public class ClassHelper { // 通过类方法获取属性值 public static Map<String, Object> getMethods(Object obj) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { Map<String, Object> map = new HashMap<String, Object>(); Method[] method = obj.getClass().getDeclaredMethods(); for (int i = 0; i < method.length; i++) { String methodName = method[i].getName().toString(); if (methodName.startsWith("get")) { map.put(method[i].getName().toString(), method[i].invoke(obj, null)); } } return map; } // 通过类方法对属性赋值 public static String[] setMethods(Object obj, Map<String, Property> propertyMap, Map<String, Object> objMap) throws NumberFormatException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Method[] method = obj.getClass().getDeclaredMethods(); String[] methods = new String[method.length]; for (int i = 0; i < method.length; i++) { String methodName = method[i].getName().toString(); if (methodName.startsWith("set")) { for (Class<?> c : method[i].getParameterTypes()) { String paramType = c.getSimpleName().toString();// 获取方法中变量的类型 String name = method[i].getName().toString() .substring(3, methodName.length()).toLowerCase();// 记得要转换为小写,截取后得到的string开头字母是大写 // System.out.println(name); Property property = propertyMap.get(name); String val = property.getValue(); if (property.isRef()) { Object o = objMap.get(val); method[i].invoke(obj, o); } else if (paramType.toLowerCase().equals("long")) { method[i].invoke(obj, Long.parseLong(val)); } else if (paramType.toLowerCase().equals("int") || paramType.equals("Integer")) { method[i].invoke(obj, Integer.valueOf(val)); } else if (paramType.toLowerCase().equals("float")) { method[i].invoke(obj, Float.valueOf(val)); } else if (paramType.toLowerCase().equals("short")) { method[i].invoke(obj, Short.valueOf(val)); } else if (paramType.toLowerCase().equals("double")) { method[i].invoke(obj, Double.valueOf(val)); } else if (paramType.toLowerCase().equals("char")) { method[i].invoke(obj, val.charAt(0)); } else if (paramType.toLowerCase().equals("boolean")) { method[i].invoke(obj, Boolean.valueOf(val)); } else if (paramType.toLowerCase().equals("byte")) { method[i].invoke(obj, val.getBytes()[0]); } else { method[i].invoke(obj, val); } } } } return methods; } // 获取类属性的值 public static Map<String, Object> getFieldsValues(Object obj) throws IllegalArgumentException, IllegalAccessException { Field[] field = obj.getClass().getDeclaredFields(); Map<String, Object> map = new HashMap<String, Object>(); for (int i = 0; i < field.length; i++) { field[i].setAccessible(true); // 允许访问私有属性 map.put(field[i].getName(), field[i].get(obj));// 使用属性的名称作为key // ,属性的值作为value } return map; } // 通过属性直接赋值 public static String[] setFields(Object obj, Map<String, Property> propertyMap, Map<String, Object> objMap) throws NumberFormatException, IllegalArgumentException, IllegalAccessException { Field[] field = obj.getClass().getDeclaredFields(); String[] fields = new String[field.length]; for (int i = 0; i < field.length; i++) { field[i].setAccessible(true); // 允许访问私有属性 String name = field[i].getName(); fields[i] = name; String type = field[i].getType().getSimpleName(); // System.out.println("name:" + name + " type:" + type); Property property = propertyMap.get(name); String val = property.getValue(); if (property.isRef()) { Object o = objMap.get(val); field[i].set(obj, o); } else if (type.toLowerCase().equals("long")) { field[i].setLong(obj, Long.parseLong(val)); } else if (type.toLowerCase().equals("int") || type.equals("Integer")) { field[i].setInt(obj, Integer.valueOf(val)); } else if (type.toLowerCase().equals("float")) { field[i].setFloat(obj, Float.valueOf(val)); } else if (type.toLowerCase().equals("short")) { field[i].setShort(obj, Short.valueOf(val)); } else if (type.toLowerCase().equals("double")) { field[i].setDouble(obj, Double.valueOf(val)); } else if (type.toLowerCase().equals("char")) { field[i].setChar(obj, val.charAt(0)); } else if (type.toLowerCase().equals("boolean")) { field[i].setBoolean(obj, Boolean.valueOf(val)); } else if (type.toLowerCase().equals("byte")) { field[i].setByte(obj, val.getBytes()[0]); } else { // System.out.println(val); field[i].set(obj, val); } } return fields; } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub } }6.利用上面的方法构建BeanFactory;
public class BeanFactory { /** * @param args */ private String path; public static Map<String, Object> map; public BeanFactory() { this("src/bean.xml"); } public BeanFactory(String path) { super(); this.path = path; init(); } private void init() { Document doc = null; map = new HashMap<String, Object>(); SAXReader reader = new SAXReader(); try { doc = reader.read(new File(path)); Element root = doc.getRootElement(); for (Iterator<Element> beans = root.elementIterator(); beans .hasNext();) { Element bean = beans.next(); Map<String, String> beanParams = XmlHelper.getBeanParams(bean); Class cla = Class.forName(bean.attributeValue("class")); Object obj = cla.newInstance(); // set value ClassHelper.setFields(obj, beanParams, map); // ClassHelper.setMethods(obj, beanParams, map); map.put(bean.attributeValue("name"), obj); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // System.out.println(System.getProperty("user.dir")); } public static <T> T getBean(String key, Class<T> classOf) { return (T) map.get(key); } public String getPath() { return path; } public void setPath(String path) { this.path = path; } }
本次实现是通过直接访问类的属性进行赋值的。
public class Main { /** * @param args * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { // TODO Auto-generated method stub BeanFactory beanFactory = new BeanFactory("src/conf.xml"); Student stud0 = BeanFactory.getBean("stud0", Student.class); Course mathCourse = BeanFactory.getBean("mathCourse", Course.class); System.out.println("stud name:" + stud0.getName()); System.out.println("stud NO.:" + stud0.getNO()); Course testMathCourse = stud0.getCourse(); System.out.println("the same ?:" + (mathCourse == testMathCourse ? true : false)); System.out.println("math name:" + mathCourse.getName()); System.out.println("math credit:" + mathCourse.getCredit()); System.out.println("math desc:" + mathCourse.getDesc()); Map<String, Object> vals = ClassHelper.getMethods(stud0); for (Iterator<String> it = vals.keySet().iterator(); it.hasNext();) { String key=it.next(); System.out.println(key+":"+vals.get(key)); } } }
8.运行结果;
source code url:
https://github.com/scalaview/reflection