Java反射机制(三)

来源:互联网 发布:淘宝仓库宝贝多久删除 编辑:程序博客网 时间:2024/04/30 18:13
动态代理
实现动态代理机制,需要使用到java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类
InvocationHandler接口的定义如下
public interface invocationHandler
{
    public Object invoke(Object Proxy,Method method,Object[] args) throws Throwable;
}
InvocationHandler接口中只有一个invoke()方法,此方法3个参数的含义为
Object Proxy:被代理的对象
Method Method:要调用的方法
Object[] args:调用的方法所需要的参数


Proxy类可以为一个或多个接口动态的生成实现类,Proxy类提供的操作方法如下:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
通过newProxyInstance方法可以动态的生成实现类,此方法中3个参数的含义为:
ClassLoader loader:类加载器
Class<?> interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的实例
PS:
ClassLoader是类加载器,java中主要有3中类加载器:
Bootstrap ClassLoader:此加载器使用C++编写,一般在开发中看不到的
Extension ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
AppClassLoader:加载Classpath指定的类,是最常用的一种加载器


范例1:
取得类加载器
package com.zgy.proxy;


public class Person 
{


}






package com.zgy.proxy;


public class ClassLoaderTest 
{


public static void main(String[] args) 
{
Person per = new Person();
System.out.println("类加载器:"+per.getClass().getClassLoader().getClass().getName());
}


}
结果输出:
类加载器:sun.misc.Launcher$AppClassLoader
由此看以看出,默认的类加载器就是AppClassLoader


范例2:
定义一个InvocationHandler接口的实现类
package com.zgy.proxy;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


/*
 * 定义MuInvacationHandler类实现InvacationHandler接口
 */
public class MyInvocationHandler implements InvocationHandler 
{
    private Object obj; //真实的主题
    public Object bind(Object obj) //绑定真实的主题
    {
    this.obj = obj;
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), 
    this); //取得代理对象
    }
    public Object invoke(Object proxy,Method method,Object[]args) throws Throwable
    { //动态调用方法
    Object temp = method.invoke(this.obj,args);//调用方法,传入真实的主题和参数
    return temp;//返回方法的信息
    }
}




定义接口
package com.zgy.proxy;


public interface Subject //定义Subject接口
{
    public String say(String name,int age); //定义抽象方法
}






定义真实主题实现类
package com.zgy.proxy;


public class RealSubject implements Subject
{
    public String say(String name,int age) //实现接口中的抽象方法
    {
    return "姓名"+name+"  "
    + "年龄"+age;
    }
}






定义动态代理测试类
package com.zgy.proxy;


public class DynamicProxyTest 
{


public static void main(String[] args) 
{
MyInvocationHandler mh = new MyInvocationHandler();//实例化代理操作类
        Subject sub = (Subject)mh.bind(new RealSubject());//绑定对象
        String info = sub.say("张三", 24); //通过动态代理调用方法
        System.out.println(info);
}


}
















利用反射实现工厂设计模式
范例:
1.创建接口Fruit
package com.zgy.factory;


public interface Fruit 
{
    public void eat();
}
2.创建接口的实现类Apple
package com.zgy.factory;


public class Apple implements Fruit
{
    public void eat()
    {
    System.out.println("吃苹果");
    }
}
3.创建接口的实现类Orange
package com.zgy.factory;


public class Orange implements Fruit
{
    public void eat()
    {
    System.out.println("吃橘子");
    }
}
4.创建工厂类
package com.zgy.factory;


public class Factory 
{
    public static Fruit getInstance(String className)
    {
    Fruit fruit = null;
    try
    {
    fruit = (Fruit)Class.forName(className).newInstance();//根据传入的类名实例化Fruit接口
    }
    catch(Exception e)
    {
    e.printStackTrace();
    }
    return fruit;
    }
}
5.实现测试类
package com.zgy.factory;


public class FactoryTest 
{


public static void main(String[] args) 
{
Fruit apple = Factory.getInstance("com.zgy.factory.Apple");
apple.eat();
}


}
以上操作可以看出,无论新增多少子类,工厂类Factory都不必做修改。










结合属性文件的工厂模式
以上的操作中要写入类完整的包.类名称,但是用户无法知道一个接口到底有多少实现类,此时可以通过属性文件的形式配置所需要的子类信息
范例:
1.创建接口Fruit
package com.zgy.factory;


public interface Fruit 
{
    public void eat();
}
2.创建接口的实现类Apple
package com.zgy.factory;


public class Apple implements Fruit
{
    public void eat()
    {
    System.out.println("吃苹果");
    }
}
3.创建接口的实现类Orange
package com.zgy.factory;


public class Orange implements Fruit
{
    public void eat()
    {
    System.out.println("吃橘子");
    }
}
4.创建工厂类
package com.zgy.factory;


public class Factory 
{
    public static Fruit getInstance(String className)
    {
    Fruit fruit = null;
    try
    {
    fruit = (Fruit)Class.forName(className).newInstance();//根据传入的类名实例化Fruit接口
    }
    catch(Exception e)
    {
    e.printStackTrace();
    }
    return fruit;
    }
}
5.创建操作属性类
package com.zgy.factory;
/*
 * 此类主要是取得属性文件中的内容,如果属性文件存在这读取,如果属性文件不存在则创建
 */
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;


public class Init 
{
    public static Properties getPro()
    {
    Properties pro = new Properties();
    File f = new File("D:"+File.separator+"fruit.properties");
    try
    {
    if(f.exists())//属性文件存在
    {
    pro.load(new FileInputStream(f));//读取属性
    }
    else //属性文件不存在,创建并设置默认值
    {
    pro.setProperty("apple", "com.zgy.factory.Apple");
    pro.setProperty("orange", "com.zgy.factory.Orange");
    }
    }
    catch(Exception e)
    {
    e.printStackTrace();
    }
    return pro;
    }
}
6.创建测试类
package com.zgy.factory;


import java.util.Properties;


public class FactoryTest02 
{


public static void main(String[] args) 
{
Properties pro = Init.getPro();
Fruit orange = Factory.getInstance(pro.getProperty("orange"));
if(orange != null)
{
orange.eat();
}
}


}



0 0
原创粉丝点击