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

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

    博客分类:
  • 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
*/

 

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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics