首页 > 代码库 > 利用反射模拟一个spring的内部工作原理

利用反射模拟一个spring的内部工作原理

  • 这个简单的案例是实行了登录和注册的功能,没有链接数据库。
  •  在bean中id 是唯一的,id和name的区别在于id不能用特殊字符而name可以用特殊字符,比如:/-\....
 1 package com.obtk.reflect;
 2 
 3 public class Logon {
 4     /**
 5      * 帐号密码长度大于六位字符就成功,否则失败!
 6      * */
 7     public String select(String name, String pass) {
 8         if (name.length() > 6 && pass.length() > 6) {
 9             return name + "用户,恭喜你注册成功";
10         }
11         return name + "用户,注册失败,密码长度或者帐号长度不对!";
12     }
13 
14     /**
15      * 帐号密码长度大于六位字符就成功,否则失败!
16      * */
17     public String get(String name, String pass) {
18         if (name.length() > 6 && pass.length() > 6) {
19             return name + "用户,恭喜你登录成功";
20         }
21         return name + "用户,登录失败,密码和帐号不匹配!";
22     }
23 }
Logon.java 实体类代码
 1 package com.obtk.reflect;
 2 
 3 import java.io.InputStream;
 4 import java.util.HashMap;
 5 import java.util.Iterator;
 6 import java.util.Map;
 7 import org.dom4j.Document;
 8 import org.dom4j.Element;
 9 import org.dom4j.io.SAXReader;
10 
11 public class LogonReflect {
12 
13     private Map<String, Object> beans = new HashMap<String, Object>();
14 
15     /**
16      * 解析xml文档
17      * */
18     public LogonReflect(String xmlFile) {
19         try {
20             // 获取xm文档解析
21             SAXReader reader = new SAXReader();
22             // 获取加载器
23             ClassLoader loader = Thread.currentThread().getContextClassLoader();
24             // classes文件夹读取配置文件
25             InputStream is = loader.getResourceAsStream(xmlFile);
26             // 从文件流读取数据构建xml文档对象
27             Document doc = reader.read(is);
28             // 获取xml的根节点(beans)
29             Element root = doc.getRootElement();
30             // 获取根节点所有的子节点(bean)
31             Iterator<Element> beanEI = root.elementIterator("bean");
32             // 循环所有的子节点
33             while (beanEI.hasNext()) {
34                 // 获取本次循环的子节点
35                 Element eBean = beanEI.next();
36                 // 获取bean节点的id的文本内容
37                 String id = eBean.attribute("id").getText();
38                 // 获取bean节点的class的文本内容
39                 String className = eBean.attribute("class").getText();
40                 // 第一个个 参数座位id,第二个参数做为一个类的实例化对象
41                 beans.put(id, Class.forName(className).newInstance());
42             }
43 
44         } catch (Exception e) {
45             e.printStackTrace();
46         }
47     }
48 
49     /**
50      * 根据id获取所对的对象
51      * */
52     public Object getBean(String beanName) {
53         return beans.get(beanName);
54     }
55 }
LogonReflect.java 实体类代码
 1 package com.obtk.reflect;
 2 
 3 public class LogonTest {
 4     public static void main(String[] args) {
 5         //传一个xml路径,
 6         LogonReflect lReflect = new LogonReflect("Logon.xml");
 7         //根据id去xml中获取实体类,默认是Object类型的,所以要强制转换
 8         Logon logon = (Logon) lReflect.getBean("logon");
 9         //获取对象任何就直接调用方法
10         System.out.println(logon.get("123456789", "987654321"));
11         System.out.println(logon.select("qqqqqqq", "qqqqqqq"));
12     }
13 }
测试类的代码
1 <beans>
2     <bean id="logon" class="com.obtk.reflect.Logon" />
3 </beans>
beans.xml 配置xml
  1. Reflection的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起(调用)其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection

  2. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的。这种动态获取类的信息,以及动态调用对象的方法的功能来自于Java语言的反射(Reflection)机制。Java反射机制主要提供了以下功能:

  • 在运行时判断任意一个对象所属的类;

  • 在运行时构造任意一个类的对象;

  • 在运行时判断任意一个类所具有的成员变量和方法;

  • 在运行时调用任意一个对象的方法;

  • 生成动态代理。

  • 文件名 

    说 明

    getFields()
    getDeclaredFields()
    getField(String name)
    getMethods()
    getMethod (String name,Class [] args)
    getConstrutors()
    getConstrutor(Class[] args)
    newInstance()
    getName()
    getPackage()
    getSuperclass()

    获得类的public类型的属性。
    获得类的所有属性
    获得类的指定属性
    获得类的public类型的方法
    获得类的指定方法
    获得类的public类型的构造方法
    获得类的特定构造方法
    通过类的无参构造方法创建该类的一个对象
    获得类的完整名字
    获取此类所属的包
    获得此类的父类对应的Class对象