1

代理的分类

代理分为静态和动态代理。
静态代理:硬编码实现的代理类,在程序被编译成.class文件时代理类就已经存在。
动态代理:代理类在运行时产生,运用jdk的反射机制动态创建而成。

静态代理

静态代理可以通过组合的方式来实现,下面看具体的demo实现:

public class ProxyTest {

    @Test
    public void proxyMethodTest() {
       
        StaticProxy staticProxy = new StaticProxy(new ClientObject());
        System.out.println(staticProxy.get());
    }
}

interface ClientObjectInterface {
    public String get ();
}

class ClientObject implements ClientObjectInterface {
    public String get () {
        return "hi";
    }
}

class StaticProxy implements ClientObjectInterface {
    ClientObject clientObject;

    public StaticProxy(ClientObject clientObject) {
        this.clientObject = clientObject;
    }

    public String get() {
        return "proxy " + clientObject.get();
    }
}

运行结果:
proxy hi

当我们在使用的过程中发现ClientObject这个类随着业务需求的变化已经变得不够用了,这是我们该怎么办?保持着对修改关闭,扩展开放的原则,我们可以通过上面那种静态代理的方式来实现业务需求的变化,当然下面还有一种比较灵活的动态代理的方式来处理上面这种case。

动态代理

动态代理又可以分为jdk库提供的和cglib库提供,这里我们主要讲讲jdk提供的动态代理。jdk代理对象是通过java.lang.reflect.Proxy#newProxyInstance来进行创建的。

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

loader:被代理对象的classloader。
interfaces:被代理对象实现的接口。
h:invocation handler,用于分派执行代理方法。

下面看下具体的代理实现demo:

public class ProxyTest {

    @Test
    public void proxyMethodTest() {
        ClientObject clientObject = new ClientObject();
        ClientObjectInterface object = (ClientObjectInterface) Proxy.newProxyInstance(
            clientObject.getClass().getClassLoader(), clientObject.getClass().getInterfaces(),
            new ObjectProxy());
        System.out.println(object.get());
    }

}

interface ClientObjectInterface {
    public String get ();
}

class ClientObject implements ClientObjectInterface {
    public String get () {
        return "hi";
    }
}


class ObjectProxy implements InvocationHandler {

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("methodName: " + method.getName());
        return "no hi";
    }
}

运行结果:
methodName: get
no hi

当然可以在代理对象里面做很多事情,本demo只是简单的替换了被代理对象的函数体。

使用场景

代理的使用场景主要集中在,某一业务需要委托代理类集中处理某一业务然后再执行具体的实现类的业务逻辑。


博予liutxer
266 声望14 粉丝

专业写代码的代码仔。


下一篇 »
Hello Netty