您的位置:首页 > 编程语言 > Java开发

Java静态代理和动态代理

2017-03-21 17:04 597 查看

静态代理

静态代理是在写代码的时候就确定了代理接口、代理接口实现类、代理类全部确定,编译后就无法改变,因此很难扩展并且耦合度高,一旦代理接口发生改变,代理类也要修改。代理类和代理接口实现类都要实现代理接口。
/**
* 代理的接口
*/
public interface Calculate {
void add(int i, int j);

void subtract(int i, int j);
}
/**
* 代理的接口实现类
*/
public class CalculateImpl implements Calculate {
@Override
public void add(int i, int j) {
System.out.println(i + "+" + j + "=" + (i + j));
}

@Override
public void subtract(int i, int j) {
System.out.println(i + "-" + j + "=" + (i - j));
}
}
/**
* 静态代理类
*/
public class Proxy implements Calculate {
private Calculate calculate;

public Proxy(Calculate calculate) {
this.calculate = calculate;
}

@Override
public void add(int i, int j) {
long start = System.currentTimeMillis();
calculate.add(i, j);
System.out.println("加法耗时:" + (System.currentTimeMillis() - start) + "毫秒");
}

@Override
public void subtract(int i, int j) {
long start = System.currentTimeMillis();
calculate.subtract(i, j);
System.out.println("减法耗时:" + (System.currentTimeMillis() - start) + "毫秒");
}
}
public static void main(String[] args) {
CalculateImpl calculate = new CalculateImpl();
Proxy proxy = new Proxy(calculate);
proxy.add(10, 5);
proxy.subtract(10, 5);
}
10+5=15
加法耗时:0毫秒
10-5=5
减法耗时:0毫秒

动态代理

动态代理可以在程序运行期间根据需要动态的创建代理类实例,需要用到java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler,可以代理各种接口,也只能代理接口而不能代理类。
InvocationHandler类只有一个方法,Object invoke(Object proxy,Method method,Object[] args)throws Throwable,第一个参数是代理类实例,第二个参数表示被包装对象上调用的方法,第三个参数表示方法参数,返回值是被包装对象上调用的方法的返回值。
Proxy中要用到的方法是,public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException,第一个参数是类加载器,第二个参数是代理类实例要实现的接口列表,第三个参数是实现了InvocationHandler接口的调用处理程序,类加载器需要设置和被包装对象一样,代理类实例实现的接口列表中所有的方法都会被实现了InvocationHandler接口的调用处理程序拦截,这样我们就可以在方法调用前后做一些处理。
public class SelfHandler implements InvocationHandler {
    private Object object;

    public Object SelfHandler(Object object) {
        this.object = object;
        return Proxy.newProxyInstance(object.getClass().getClassLoader(),
                object.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(proxy.getClass().getName());
        long start = System.currentTimeMillis();
        Object o = method.invoke(object, args);
        System.out.println(method.getName() + "方法耗时:" + (System.currentTimeMillis() - start) + "毫秒");
        return o;
    }
}
public static void main(String[] args) {
Set set = new HashSet();
set = (Set) new SelfHandler().SelfHandler(set);
set.add(1);
set.remove(2);
}
com.sun.proxy.$Proxy0
add方法耗时:0毫秒
com.sun.proxy.$Proxy0
remove方法耗时:0毫秒
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: