框架最底层其实就是通过反射实现的,就像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的信息