IOC模式与JAVA反射机制

在Java中反射和动态代理机制很强大,通过反射机制在运行时获取信息。用于实现IOC。

代理是Java基本的设计模式,提供向对象插入额外的或不同的操作。Java的动态代理能动态的创建代理对象,以及动态的调用代理方法。用于实现AOP。
一、Java反射机制
1、作用
(1)在运行时判断任意一个对象所属的类;
(2)在运行时获取类的对象;
(3)在运行时获得类所具有的成员变量和方法等;
2、Reflection类:
package com.makocn.reflection;
import java.lang.reflect.Method;
import java.util.Hashtable;

public class Reflection {
 public static void main(String[] args) throws Exception {
  Reflection reflection = new Reflection();
  reflection.getNameTest();
  System.out.println("*****************************************");
  reflection.getMethodTest();
 }
 public void getNameTest() throws Exception {
  String name = "马可中国";
  Class cls = name.getClass();
  System.out.println("String类名: " + cls.getName());
  Class superBtnClass = cls.getSuperclass();
  System.out.println("String的父类名: " + superBtnClass.getName());
  Class clsTest = Class.forName("java.util.Date");
  System.out.println("clsTest name: " + clsTest.getName());
 }
 public void getMethodTest() throws Exception {
  Class cls = Class.forName("com.makocn.reflection.Reflection");
  Class ptypes[] = new Class[2];
  ptypes[0] = Class.forName("java.lang.String");
  ptypes[1] = Class.forName("java.util.Hashtable");
  Method method = cls.getMethod("testMethod", ptypes);
  Object args[] = new Object[2];
  args[0] = "oh, my dear!";
  Hashtable ht = new Hashtable();
  ht.put("name", "马可中国");
  args[1] = ht;
  String returnStr = (String) method.invoke(new Reflection(), args);
  System.out.println("returnStr= " + returnStr);
 }
 public String testMethod(String str, Hashtable ht) throws Exception {
  String returnStr = "返回值";
  System.out.println("测试testMethod()方法调用");
  System.out.println("str= " + str);
  System.out.println("名字= " + (String) ht.get("name"));
  System.out.println("结束testMethod()方法调用");
  return returnStr;
 }
}
3、运行结果:
String类名: java.lang.String
String的父类名: java.lang.Object
clsTest name: java.util.Date
*****************************************
测试testMethod()方法调用
str= oh, my dear!
名字= 马可中国
结束testMethod()方法调用
returnStr= 返回值
二、Java耦合例子
1、Chinese类:
package com.makocn.reflection;
public class Chinese{
 public void sayHello(String name) {
  String helloWorld = "你好," + name;
  System.out.println(helloWorld);
 }
}
2、American类
package com.makocn.reflection;
public class American{
 public void sayHello(String name) {
   String helloWorld = "Hello," + name;
  System.out.println(helloWorld);
 }
}
3、HelloWorld类:
package com.makocn.reflection;
public class HelloWorld {
 public static void main(String[] args) {
  Chinese chinese = new Chinese();
  chinese.sayHello("马可中国");
  American american = new American();
  american.sayHello("makocn");
 }
}
从HelloWorld可以看到,该类与Chinese.java类和American.java类都存在强耦合关系。
4、运行结果:
你好,马可中国
Hello,makocn
三、工厂模式解耦例子
1、Human接口:
package com.makocn.reflection;
public interface Human {
  public void sayHello(String name);
}
2、Chinese类:
package com.makocn.reflection;
public class Chinese implements Human{
 public void sayHello(String name) {
  String helloWorld = "你好," + name;
  System.out.println(helloWorld);
 }
}
3、American类:
package com.makocn.reflection;
public class American implements Human{
 public void sayHello(String name) {
   String helloWorld = "Hello," + name;
  System.out.println(helloWorld);
 }
}
4、HumanFactory工厂类:
package com.makocn.reflection;
public class HumanFactory {
 public Human getHuman(String type) {
  if ("chinese".equals(type)) {
   return new Chinese();
  } else {
   return new American();
  }
 }
}
5、HelloWorld类:
package com.makocn.reflection;
public class HelloWorld {
 public static void main(String[] args) {
  HumanFactory factory = new HumanFactory();
         Human human1 = factory.getHuman("chinese");
         human1.sayHello("马可中国");       
         Human human2 = factory.getHuman("american");
         human2.sayHello("makocn");
 }
}
6、运行结果:
你好,马可中国
Hello,makocn
利用工厂HumanFactory,我们不再与具体的实现类Chinese和American存在耦合关系,而只是与接口类Human存在耦合关系,具体对象的获取只是通过传入字符串来获取,降低了类与类之间的耦合性。但如果我们要换具体类的实现时,则我们还需修改工厂类中的字符串。
四、IOC实现
IOC(Inverse of Control)翻译为控制反转,也称DI(Dependence Injection)依赖注入。实现好莱坞原则:不用你主动来找我,我会通知你。
通过IOC可以将实现类、参数信息等配置在其对应的配置文件中,当需要更改实现类或参数信息时,只需要修改配置文件即可,进一步降低了类与类之间的耦合。同时还可以对某对象所需要的其它对象进行注入。
Spring的IOC的实现原理就是Java反射机制, 同时Spring还充当了工厂角色,Spring的工厂类读取配置文件、利用反射机制注入对象等。程序可通过bean的名称获取对应的对象。
1、BeanFactory工厂类
package com.makocn.reflection;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class BeanFactory {
 private Map beanMap = new HashMap();
 public void init(String xml) {
  try {
   // 读取指定的配置文件
   SAXReader reader = new SAXReader();
   ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
   // 从class目录下获取指定的xml文件
   InputStream ins = classLoader.getResourceAsStream(xml);
   Document doc = reader.read(ins);
   Element root = doc.getRootElement();
   Element foo;
   // 遍历bean
   for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
    foo = (Element) i.next();
    // 获取bean的属性id和class
    Attribute id = foo.attribute("id");
    Attribute cls = foo.attribute("class");
    // 利用Java反射机制,通过class的名称获取Class对象
    Class bean = Class.forName(cls.getText());
    // 获取对应class的信息
    java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
    // 获取其属性描述
    java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
    // 设置值的方法
    Method mSet = null;
    // 创建一个对象
    Object obj = bean.newInstance();
    // 遍历该bean的property属性
  

你可能感兴趣的:(Java,spring)