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

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

    博客分类:
  • JAVA
 
阅读更多

      动态反射代理实现机制两例代码比较,最近研究设计模式,略作深入分析基于JDK1.3以来的Java动态反射代理,也结合最新的JDK1.6版本以上的新特性进行比较。

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

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

第一种实现代码如下(基于JDK1.3以上的):

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

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
public interface IVehicle extends java.io.Serializable {

    /**
    * 业务处理A方法
    * @param name
    */
    void doMethod1(String name);

    /**
    * 业务处理B方法
    * @param name
    */
    void doMethod2(String name);

    /**
     *
     * add
     * @param a
     * @param b
     * @return the int
     */
    int add(int a, int b);

    /**
     *
     * getPerson
     * @param id
     * @return the Person
     */
   Person getPerson(Long id);
}

 

 代理接口实现类Vehicle.java

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
public class Vehicle implements IVehicle {
    private static final long serialVersionUID = -4242273039478355706L;

    public void doMethod1(String name) {
        System.out.println("Hello, " + name);
    }

    public void doMethod2(String name) {
        System.out.println(name + ", GoodBye!");
    }

    public int add(int a, int b) {
        return a + b;
    }

    @Override
    public Person getPerson(Long id) {
        final Person p = new Person("ABO", 33, 1l);
        p.setName("xiangzhouAPJ");
        p.setId(id);
        return p;
    }
}

 

 使用到Javabean类Person.java

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
public class Person implements java.io.Serializable {
    private static final long serialVersionUID = 4341973142110996341L;
    private String name;
    private int age;
    private Long id;

    public Person(String name, int age, Long id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String toString() {
        return "id = " + this.id + ", name = " + this.name;
    }
}

 

日志等级枚举类Level.java

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
public enum Level {
    INFO,WARN,DEBUG;
}

 

日志记录类Logger.java

import java.util.Date;

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
public class Logger {
    /** */
    /**
    * 根据等级记录日志
    * @param level
    * @param contont
    */
    @SuppressWarnings("deprecation")
    public static void logging(Level level, String contont) {
        if (level.equals(Level.INFO)) {
            System.out.println(String.format("%1$10s |%2$20s |%3$5s |%4$10s ", new Date().toLocaleString(), contont, "test", "日志记录开始...."));
        }
        if (level.equals(Level.DEBUG)) {
            System.out.println(String.format("%1$10s |%2$20s |%3$5s |%4$10s ", new Date().toLocaleString(), contont, "test", "日志记录结束。"));
        }
    }
}

 

操作类接口类IOperation.java

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
public interface IOperation extends java.io.Serializable {

    /**
    * 方法执行之前的操作
    * @param method
    */
    void start(String name);

    /**
    * 方法执行之后的操作
    * @param method
    */
    void end(String name);
}

 

操作类接口实现类LoggerOperation.java

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
public class LoggerOperation implements IOperation {
    private static final long serialVersionUID = -140781378476709074L;
    private String start;
    private String end;
    /**
     * @param start
     * @param end
     */
    public LoggerOperation(String start, String end) {
        super();
        this.start = start;
        this.end = end;
    }

    public void end(String name) {
        Logger.logging(Level.DEBUG, end + " Method end .");
    }

    public void start(String name) {
        Logger.logging(Level.INFO, start + " Method Start!");
    }

    public String getStart() {
        return start;
    }

    public void setStart(String start) {
        this.start = start;
    }

    public String getEnd() {
        return end;
    }

    public void setEnd(String end) {
        this.end = end;
    }
}

 关键的动态代理类DynamicProxy.java

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class DynamicProxy implements InvocationHandler {

    /**
    * 操作者,记录额外操作者
    */
    private Object proxy;

    /**
    * 被代理者
    */
    private Object delegate;

    /**
    * 动态生成方法被处理过后的对象 (写法固定)
    * @param delegate
    * @param proxy
    * @return Object
    */
    public Object bind(Object delegate, Object proxy) {
        this.proxy = proxy;
        this.delegate = delegate;
        return Proxy.newProxyInstance(
                    this.delegate.getClass().getClassLoader(), this.delegate
                           .getClass().getInterfaces(), this);
    }

    /**
     * 自动动态处理调用对象的所有方法, 可以封装日志、事务、权限等
     */
    @SuppressWarnings("unchecked")
    public synchronized Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
        Object result = null;
        try {
            //得到操作者的实例
            Class clazz = this.proxy.getClass();;
            Method[] ms = clazz.getDeclaredMethods();
            //前面对操作者追加内容的反射代理处理
            for (Method m : ms) {
                if("start".equals(m.getName())) {
                    Method start = clazz.getDeclaredMethod("start", m.getParameterTypes());
                    start.invoke(this.proxy, new Object[]{""});
                    break;
                }
            }
            //执行要处理对象的原本方法 真正执行的方法
            result = method.invoke(this.delegate, args);
            //后面对操作者追加内容的反射代理处理
            for (Method m : ms) {
                if("end".equals(m.getName())) {
                    Method end = clazz.getDeclaredMethod("end", m.getParameterTypes());
                    end.invoke(this.proxy, new Object[]{""});
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

 

测试类Test.java,以及测试结果

/**
 * @author Dennis Zhao
 * @createdTime:Mar 22, 2013
 */
public class Test {
    public static void main(String[] args) {
        IVehicle v = (IVehicle) new DynamicProxy().bind(new Vehicle(), new LoggerOperation("first", "second"));
        v.doMethod1("Double fish");
        v.doMethod2("Red king dragon");
        System.out.println(v.add(1, 4));
        System.out.println(v.getPerson(1L));
    }
}
/*
Mar 29, 2013 2:28:57 PM | first Method Start! | test |日志记录开始.... 
Hello, Double fish
Mar 29, 2013 2:28:57 PM | second Method end . | test |   日志记录结束。 
Mar 29, 2013 2:28:57 PM | first Method Start! | test |日志记录开始.... 
Red king dragon, GoodBye!
Mar 29, 2013 2:28:57 PM | second Method end . | test |   日志记录结束。 
Mar 29, 2013 2:28:57 PM | first Method Start! | test |日志记录开始.... 
Mar 29, 2013 2:28:57 PM | second Method end . | test |   日志记录结束。 
5
Mar 29, 2013 2:28:57 PM | first Method Start! | test |日志记录开始.... 
Mar 29, 2013 2:28:57 PM | second Method end . | test |   日志记录结束。 
id = 1, name = xiangzhouAPJ
*/

 

 第一种实现方式,接着请看第二篇文章.............^_^

 

分享到:
评论

相关推荐

    反射实现 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和反射的底层工作原理,也能帮助我们更好地利用这些工具,解决实际开发中的问题。

    JAVA实例编程100例2

    7. 实例70:这可能是一个关于反射的实例,JAVA反射机制允许程序在运行时动态访问类的信息,创建和调用对象。虽然不常用,但在一些特定场景下,如插件开发、动态代理等,反射具有很高的实用性。 8. 实例52:可能涉及...

    JAVA编程100例

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

    java程序设计100例

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

    spring常见问题

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

    java编程1-50例

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

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

    反射则是.NET Framework的一种特性,它允许在运行时动态地获取和操作类型的信息。通过反射,我们可以动态地创建对象、调用方法、访问属性和字段,甚至检查和使用未知类型的成员。反射的核心类是`System.Type`,它...

    Java高级编程百例

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

    Java设计100例

    《Java设计100例》是一份专注于Java编程语言的设计模式和最佳实践的资源集合,旨在帮助开发者提升软件设计能力和代码质量。这份资料可能包含了100个不同的Java设计示例,涵盖了各种常见和重要的设计原则、模式以及...

    cglib.jar免费下载

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

    Java实效编程百例

    在《Java实效编程百例》中,我们涵盖了Java编程实践中一系列关键知识点,旨在提升开发者在实际项目中的效率和代码质量。以下是对这些知识点的详细解释: 1. **基础语法**:Java的基础包括变量、数据类型、运算符、...

    JAVA实用编程100例

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

    Java程序设计100例

    通过"Java程序设计100例"这个资源,学习者可以逐步深入每一个知识点,通过实际编写和运行代码来巩固理论知识,提升编程技能。实践是检验理解的最好方式,因此,每个例子都是一次宝贵的学习机会。

    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