首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

动态反照代理实现机制两例代码比较(二)

2013-04-07 
动态反射代理实现机制两例代码比较(二)????? 动态反射代理实现机制两例代码比较,最近研究设计模式,略作深

动态反射代理实现机制两例代码比较(二)

????? 动态反射代理实现机制两例代码比较,最近研究设计模式,略作深入分析基于JDK1.3以来的Java动态反射代理,也结合最新的JDK1.6版本以上的新特性进行比较,业界主要有CGLIB、ASM等技术实现生成字节码。

????? 通常我们使用反射代理这种统一处理方式针对一致日志、事务、权限、监控、拦截等这种具有切面点的场景进行一系列的自动处理,减轻程序员的代码编写量,提升代码的耦合度,适当提升代码编写质量,对系统架构的扩展性进一步加强。此吃放在这里做一个参考比较,学习使用,抛砖引玉,以资共享......

由于时间紧迫,先写一个简单日后再完善......

第二种实现代码如下(基于JDK1.6以上的自带新特性):

被代理方法的接口类 Vehicleable.java:

/** * @author Dennis Zhao * @createdTime:Mar 29, 2013 */public interface Vehicleable extends java.io.Serializable {    void run();    void run(Car car);    void run(Car car, MotoCar c);}

?

被代理方法的接口实现类 Vehicle.java:

import java.util.Random;/** * @author Dennis Zhao * @createdTime:Mar 29, 2013 */public class Vehicle implements Vehicleable {    private static final long serialVersionUID = 7633089691765059657L;    @Override    public void run() {        System.out.println("Automatic Moving...");        try {            Thread.sleep(new Random().nextInt(100));        } catch (InterruptedException e) {            e.printStackTrace();        }    }    @Override    public void run(Car car) {        String name = Car.class.getName();        System.out.println(name.substring(name.lastIndexOf(".") + 1) +  " Moving...");        System.out.println("car name == " + car.getName() );        System.out.println("car color == " + car.getColor() );        System.out.println("car age == " + car.getAge() );        try {            Thread.sleep(new Random().nextInt(100));        } catch (InterruptedException e) {            e.printStackTrace();        }    }    @Override    public void run(Car car, MotoCar c) {        String name = Car.class.getName();        String name1 = MotoCar.class.getName();        System.out.println(name.substring(name.lastIndexOf(".") + 1)            + " and " + name1.substring(name1.lastIndexOf(".") + 1) + " Moving...");        System.out.println("car name == " + car.getName() );        System.out.println("car color == " + car.getColor() );        System.out.println("car age == " + car.getAge() );        System.out.println("motocar color == " + c.getColor() );        System.out.println("motocar name == " + c.getName() );        System.out.println("motocar age == " + c.getAge() );        try {            Thread.sleep(new Random().nextInt(100));        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

?

提供两个测试用的Javabea类Car.java, MotoCar.java

/** * @author Dennis Zhao * @createdTime:Mar 29, 2013 */public class Car implements java.io.Serializable {    private static final long serialVersionUID = 1L;    private String name;    private String color;    private int age;    public String getName() {        return name;    }    public Car setName(String name) {        this.name = name;        return this;    }    public String getColor() {        return color;    }    public Car setColor(String color) {        this.color = color;        return this;    }    public int getAge() {        return age;    }    public Car setAge(int age) {        this.age = age;        return this;    }}

?

MotoCar.java

/** * @author Dennis Zhao * @createdTime:Mar 29, 2013 */public class MotoCar implements java.io.Serializable {    private static final long serialVersionUID = 11L;    private String name;    private String color;    private int age;    public String getName() {        return name;    }    public MotoCar setName(String name) {        this.name = name;        return this;    }    public String getColor() {        return color;    }    public MotoCar setColor(String color) {        this.color = color;        return this;    }    public int getAge() {        return age;    }    public MotoCar setAge(int age) {        this.age = age;        return this;    }}

?

自定义一个模拟JDK接口类InvocationHandler.java

/** * 模拟 JDK InvocationHandler处理类 * @author Dennis Zhao * @createdTime:Mar 29, 2013 */public interface InvocationHandler extends java.io.Serializable {    public void invoke(Object o, Method m, Object... obj);}

?

?接口类InvocationHandler的实现类LogHandler.java

import java.lang.reflect.Method;/** * 模拟日志包装处理类 * @author Dennis Zhao * @createdTime:Mar 29, 2013 */public class LogHandler implements InvocationHandler{    private static final long serialVersionUID = -9124608101609510202L;    private Object target;    public LogHandler(Object target) {        super();        this.target = target;    }    @Override    public void invoke(Object o, Method m, Object... obj) {        long start = System.currentTimeMillis();        System.out.println("正式的方法 log :" + start);        //System.out.println(o.getClass().getName());        try {            m.invoke(target, obj);        } catch (Exception e) {            e.printStackTrace();        }        long end = System.currentTimeMillis();        System.out.println("运行 时间 log :" + (end-start));    }}

?

生成隐藏动态代理类HiddenProxy.java

import java.io.File;import java.io.FileWriter;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import javax.tools.JavaCompiler;import javax.tools.StandardJavaFileManager;import javax.tools.ToolProvider;import javax.tools.JavaCompiler.CompilationTask;/** * 隐藏代理类,完全动态生成执行,自定义代码 * @author Dennis Zhao * @createdTime:Mar 29, 2013 */public class HiddenProxy {    @SuppressWarnings("unchecked")    public static Object newProxyInstance(Class<?> interfaces, InvocationHandler h) throws Exception {        StringBuffer methodStr = new StringBuffer("");        String newLine = "\r\n";        String curPath = System.getProperty("user.dir");        String filePath = curPath + File.separator + "tmp" + File.separator;        Method[] methods = interfaces.getMethods();        for(Method m : methods) {            StringBuffer sb = new StringBuffer("");m.getParameterTypes();            StringBuffer sbp = new StringBuffer("");            Class[] cs = m.getParameterTypes();            for (Class c : cs) {                String objName = c.getName();                sb.append(objName).append(" ")                  .append(objName.substring(objName.lastIndexOf(".") + 1).toLowerCase())                  .append(",");                sbp.append(sb.substring(sb.lastIndexOf(" ")+1));            }            String strParam = "";            String param = "";            if(sb.length() > 0) {                strParam = sb.substring(0, sb.length() - 1);                param = "new Object[]{"+ sbp.substring(0, sbp.length() - 1) + "}";            } else {                param = "new Object[]{}";            }            int len = m.getParameterTypes().length;            methodStr.append(newLine).append("@Override").append(newLine)                 .append("public void " + m.getName() + "(" + strParam + ") {" + newLine)                 .append("try {" + newLine )                 .append("System.out.println("自定义事务开始...");" + newLine)                 .append("Method[] mds = " + interfaces.getName() + ".class.getMethods();").append(newLine)                 .append("for(Method m : mds) {").append(newLine)                 .append("if (m.getName().startsWith("" + m.getName() + "")  && ")                 .append(len+"==m.getParameterTypes().length) {").append(newLine)                 .append("h.invoke(this, m, " + param + ");").append(newLine)                 .append("break;").append(newLine)                 .append("}").append(newLine)                 .append("}").append(newLine)                 .append(            newLine )                 .append("System.out.println("自定义事务完毕。 " );" + newLine )                 .append("} catch(Exception e) {").append(newLine)                 .append("e.printStackTrace();" + newLine )                 .append("}" + newLine )                 .append("}" + newLine) ;        }        StringBuffer src = new StringBuffer().append(            "package com.pattern.proxy.aop.proxy;" +  newLine)            .append("import java.lang.reflect.Method;" + newLine)            .append("import com.pattern.proxy.aop.proxy.InvocationHandler;" + newLine)            .append("public class MyProxy implements " + interfaces.getName() + "{" + newLine)            .append("    InvocationHandler h;" + newLine)            .append("    public MyProxy(InvocationHandler h) {" + newLine )            .append("        this.h = h;" + newLine )            .append("    }" + newLine )            .append(methodStr + newLine )            .append("}");        String fileName = filePath +  "com" + File.separator +"pattern" + File.separator            + "proxy" + File.separator +"aop" + File.separator +"proxy" + File.separator;        File f = new File(fileName);        f.mkdirs();        fileName = fileName + "MyProxy.java";        File f1 = new File(fileName);        FileWriter fw = new FileWriter(f1);        fw.write(src.toString());        fw.flush();        fw.close();        //compile        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();        StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);        Iterable units = fileMgr.getJavaFileObjects(fileName);        CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);        t.call();        fileMgr.close();        //load into memory and create an instance        URL[] urls = new URL[] {new URL("file://" + filePath)};        URLClassLoader ul = new URLClassLoader(urls);        Class<?> c = ul.loadClass("com.pattern.proxy.aop.proxy.MyProxy");        Constructor<?> ctr = c.getConstructor(InvocationHandler.class);        Object m = ctr.newInstance(h);        //System.out.println(m.getClass().getName());        return m;    }}

?

最后测试类以及测试结果Test.java

/** * AOP模拟实现动态反射代理机制,基于 JDK1.6以上 * @author Dennis zhaoxiaobo * @createdTime:Mar 29, 2013 */public class Test {    public static void main(String[] args) throws Exception {        Vehicle t = new Vehicle();        InvocationHandler h = new LogHandler(t);        Vehicleable m = (Vehicleable)HiddenProxy.newProxyInstance(Vehicleable.class, h);        m.run();        m.run(new Car().setName("abo car").setAge(12).setColor("black"));        m.run(new Car().setName("my car").setAge(11).setColor("red"),                new MotoCar().setColor("green").setName("Abo's motocar").setAge(100));    }}////可以对任意的对象、任意的接口方法,实现任意的代理, 针对对象,注意(不支持基本数据类型)/*------------ 打印测试结果--------------自定义事务开始...正式的方法 log :1364539212298Automatic Moving...运行 时间 log :62自定义事务完毕。自定义事务开始...正式的方法 log :1364539212360Car Moving...car name == abo carcar color == blackcar age == 12运行 时间 log :78自定义事务完毕。自定义事务开始...正式的方法 log :1364539212438Car and MotoCar Moving...car name == my carcar color == redcar age == 11motocar color == greenmotocar name == Abo's motocarmotocar age == 100运行 时间 log :110自定义事务完毕。*/

?

?指定生成了虚拟的Java类,帮我们做一些本应该由代理类来完成的工作。

?由于工作事情多,有时间再整理做一些文字性补充说明.....^_^

?

?

?

?

热点排行