`
oboaix
  • 浏览: 274429 次
社区版块
存档分类
最新评论

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

    博客分类:
  • JAVA
 
阅读更多

      动态反射代理实现机制两例代码比较,最近研究设计模式,略作深入分析基于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 :1364539212298
Automatic Moving...
运行 时间 log :62
自定义事务完毕。
自定义事务开始...
正式的方法 log :1364539212360
Car Moving...
car name == abo car
car color == black
car age == 12
运行 时间 log :78
自定义事务完毕。
自定义事务开始...
正式的方法 log :1364539212438
Car and MotoCar Moving...
car name == my car
car color == red
car age == 11
motocar color == green
motocar name == Abo's motocar
motocar age == 100
运行 时间 log :110
自定义事务完毕。
*/

 

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

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

 

 

 

 

分享到:
评论

相关推荐

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    在Java开发中,反射机制是实现动态代理的关键技术之一。反射提供了在运行时访问和操作类的能力,这使得动态代理的实现成为可能。在Java中,可以使用java.lang.reflect包下的相关类和接口实现动态代理。 例如,通过...

    23种设计模式静态模式.docx

    Spring AOP通过动态代理机制,可以在方法执行前后插入自定义的行为,例如日志记录、事务管理等。Spring提供了两种动态代理方式:JDK动态代理和CGLIB代理,它们都是在运行时生成代理类,而无需提前编写代理类的代码。...

    spring面试题2.pdf

    在这种情况下,JDK动态代理机制会为这些接口生成一个动态代理类,在运行期间,通过反射机制来调用目标类的方法。其代理类和代理对象的生成都是在程序运行时动态完成的。 2. Cglib动态代理:Cglib动态代理则不需要...

    利用 spring annotation AOP 反射 记录日志

    总的来说,通过Spring的注解式AOP和反射机制,我们可以方便地实现日志记录,提高代码的可维护性和可读性。同时,理解AOP和反射的底层工作原理,也能帮助我们更好地利用这些工具,解决实际开发中的问题。

    spring常见问题

    其中 InvocationHandler 是一个接口,可以通过实现该接口定义横切逻辑,在并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。 什么是 autowire? Autowire 是 Spring 的自动装配机制,通过...

    C#中的程序集和反射介绍

    总的来说,程序集和反射是C#和.NET Framework中不可或缺的部分,它们增强了代码的可维护性和灵活性,同时也提供了在运行时动态操作和扩展应用程序的能力。理解和掌握这两个概念对于深入学习.NET平台的开发至关重要。

    Java高级编程百例

    7. 动态代理:Java提供两种动态代理方式,即JDK动态代理和CGLIB代理,常用于AOP(面向切面编程)框架,实现如日志、事务控制等功能。 8.IO/NIO:Java的I/O流体系和NIO(非阻塞I/O)模块,对于高性能网络编程和大...

    JAVA编程100例

    9. **反射机制**:JAVA反射机制允许我们在运行时动态地获取类的信息并操作对象,这对于插件系统、动态代理等高级功能的实现至关重要。 10. **网络编程**:JAVA提供了Socket编程接口,可以用来创建客户端和服务器端...

    JAVA实例编程100例2

    虽然不常用,但在一些特定场景下,如插件开发、动态代理等,反射具有很高的实用性。 8. 实例52:可能涉及到泛型的应用,泛型提供类型安全,使代码更易于理解和维护。理解如何使用泛型列表、泛型方法等,可以避免...

    java程序设计100例

    9. **反射与动态代理**:反射允许在运行时检查和操作类的信息,动态代理则可以在运行时创建代理对象,提供额外的功能。这些高级特性在某些特定场景下十分有用,比如插件系统或单元测试。 10. **集合框架高级特性和...

    Java实效编程百例

    8. **反射机制**:反射允许程序在运行时检查类、接口、字段和方法的信息,甚至动态创建对象。它在插件系统、序列化、动态代理等领域有广泛应用。 9. **JVM内存管理**:理解Java内存模型(堆、栈、方法区等)以及...

    java编程1-50例

    - 动态代理:在运行时创建代理类,实现AOP(面向切面编程)。 9. **泛型** - 泛型类、泛型方法和泛型接口,理解类型参数和边界。 - 泛型通配符:?的使用,如和。 10. **注解** - 元注解:@Override、@...

    cglib.jar免费下载

    在SSH(Struts + Spring + Hibernate)集成框架中,CGLIB被用作Hibernate的默认代理机制,用于实现对持久化对象的透明代理,提高性能并简化代码。 2. **cglib-nodep-2.2.jar**:这个版本的CGLIB是无依赖版本,不...

    Java程序设计100例

    8. **反射**:反射允许程序在运行时动态地获取类的信息并操作对象。它在插件系统、序列化和动态代理等领域有广泛应用。 9. **泛型**:泛型提高了代码的类型安全性和重用性。学习者需要理解泛型类、泛型方法和通配符...

    JAVA实用编程100例

    8. **反射**:反射机制允许程序在运行时动态获取类的信息并操作类的对象,这在处理动态加载、插件系统、单元测试等方面很有用。 9. **泛型**:泛型是Java 5引入的新特性,它提供了编译时类型安全,减少类型转换的...

    Java设计100例

    除了设计模式,这份资料可能还涵盖了其他关键的Java编程概念,如异常处理、多线程、集合框架、IO流、网络编程、反射机制、注解、模块化系统(Java 9+的模块系统)、JVM内存模型、性能优化等方面的知识。 学习《Java...

    StudyIdeaProject.rar

    Spring支持JDK动态代理和CGLIB代理两种方式,根据目标类是否实现了接口来选择合适的代理策略。 五、依赖注入 依赖注入是Spring的核心特性之一,它负责管理Bean之间的依赖关系。Spring通过反射和元数据来自动装配...

    android Hook DEmo

    这两种 VM 都支持字节码级别的 Hook,例如,我们可以使用 Art 或 Dalvik 的代理类机制(Proxy Classes)或者利用 JVMTI(Java Virtual Machine Tool Interface)进行 Hook。在 Art 中,我们可以使用 MethodHandle 和...

Global site tag (gtag.js) - Google Analytics