`

代理模式Dynamic Proxies(四、Struts2.0拦截器Interceptor)

 
阅读更多

一、概念和注意点:
    Once you write a dynamic proxy class, you can use it to wrap any object, so

long as the object is an instance of a class that implements an interface that

declares the behavior you want to intercept.
    动态代理可以用来包裹任何类,拦截这个类实现的接口中的某些方法,在执行这些方法

的前后加入适当动作。
    Dynamic proxies in Java let you wrap an object with a proxy that intercepts

the object's calls and that can add behavior before or after passing the call

along.This lets you create reusable behavior that you can drop in on an arbitrary

object, in a fashion similar to aspect-oriented programming.
    在被拦截的方法前后加入适当操作——提高了“可重用性”,类似AOP的做法。
    In AOP, an aspect is a combination of aspect——code that you want to drop in

——and point cuts——definitions of execution points in your code where you want

the drop-in code to run.
    理解AOP中的两个概念:
    1)aspect——可重用代码
    2)point cuts——执行点

 

Sam的总结: Dynamic Proxies就是一个拦截器,在某些操作的前后加上可重用代码。记住

Java中实现动态代理需要实现的接口和方法。

 

二、代码

 

动态代理的使用ShowDynamicProxy.java

      原来的对象HashSet s 被代理后,可以转化为HashSet的(任意)父接口Set,在执行Set中声明的任意方法时,会在外围包裹拦截动作^_^

package app.proxy.dynamic;

import java.util.HashSet;
import java.util.Set;

import com.oozinoz.firework.Firecracker;
import com.oozinoz.firework.Sparkler;
import com.oozinoz.utility.Dollars;

/**
 * Show an example of using a dynamic proxy to add behavior to an object. In
 * this example, we add an element of impatience, complaining if any method
 * takes too long to execute.
 */
public class ShowDynamicProxy {
    public static void main(String[] args) {
        Set s = new HashSet();
        s = (Set) ImpatientProxy.newInstance(s); /* 代理后可以强制转化为原来类实现的任何接口类型 */
        s.add(new Sparkler("Mr. Twinkle", new Dollars(0.05)));
        s.add(new BadApple("Lemon"));
        s.add(new Firecracker("Mr. Boomy", new Dollars(0.25)));

        System.out.println("The set contains " + s.size() + " things.");
    }
}

 

动态代理类ImpatientProxy.java

      1)动态代理类必须实现InvocationHandler接口,以及该接口中的invoke(...)方法;

      2)背下来:静态实例化方法newInstance(...)的实现。

package app.proxy.dynamic;

import java.lang.reflect.*;

/**
 * This class is an example of a dynamic proxy. Instances of this class wrap a
 * proxied object. This class simply forwards calls to the object it wraps.
 * However, if any method takes a long time to execute, this class will print a
 * warning message.
 */
public class ImpatientProxy implements InvocationHandler {

    private Object obj;

    /**
     * Construct a dynamic proxy around the given object.
     * @param obj the object to wrap
     * @return the proxy
     */
    public static Object newInstance(Object obj) {
        ClassLoader loader = obj.getClass().getClassLoader();	/* 获取“被代理类”的加载器 */
        Class[] classes = obj.getClass().getInterfaces();		/* 获取“被代理类”实现的接口 */
        return Proxy.newProxyInstance(loader, classes, new ImpatientProxy(obj));	/* 返回Object类型的代理 */
        /*
         * 注意:The returned object will implement all the interfaces that the wrapped
         * object's class implements. We can cast the returned object to any of these 
         * interfaces.
         */
    }

    private ImpatientProxy(Object obj) {
        this.obj = obj;
    }

    /**
     * The method that all dynamic proxies must implement. This dynamic proxy
     * complains when a method takes a long time to return.
     */
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        Object result;
        long t1 = System.currentTimeMillis();
        result = m.invoke(obj, args);
        long t2 = System.currentTimeMillis();
        if (t2 - t1 > 10) {
            System.out.println("> It takes " + (t2 - t1) + " millis to invoke " + m.getName()
                    + "() with");
            for (int i = 0; i < args.length; i++) 
                System.out.println(">     arg[" + i + "]: " + args[i]);
        }
        return result;
    }
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics