代理模式(静态代理/动态代理)

在了解静态代理和动态代理前,请先了解代理类Proxy代理类Proxy
 

代理模式

为其他对象提供一个代理以控制对某个对象的访问。代理类不现实具体服务,而是利用委托类来完成服务,并将执行结果封装处理。

其实就是代理类被代理类预处理消息、过滤消息并在此之后将消息转发给被代理类,之后还能进行消息的后置处理。

 

静态代理

创建一个接口,然后创建被代理类实现该接口并且实现该接口中的抽象方法。之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法。

接口:

public interface HelloInterface {
    void sayHello();
}

被代理类:

public class Hello implements HelloInterface{
    @Override
    public void sayHello() {
        System.out.println("Hello!!!!");
    }
}

代理类:

public class HelloProxy implements HelloInterface{
    private HelloInterface helloInterface = new Hello();
    @Override
    public void sayHello() {
        System.out.println("Before invoke sayHello" );
        helloInterface.sayHello();
        System.out.println("After invoke sayHello");
    }
}

代理类调用:
被代理类被传递给了代理类HelloProxy,代理类在执行具体方法时通过所持用的被代理类完成调用。

public static void main(String[] args) {
    HelloProxy helloProxy = new HelloProxy();
    helloProxy.sayHello();
}

输出:

Before invoke sayHello
Hello!!!!
After invoke sayHello

使用静态代理很容易就完成了对一个类的代理操作。但是静态代理的缺点也暴露了出来:由于代理只能为一个类服务,如果需要代理的类很多,那么就需要编写大量的代理类,比较繁琐。

 

动态代理

动态代理关键在于
Object proxyObject = Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler h);

通过此方法返回一个实现指定接口的实例(实现了interfaces接口的proxyObject对象)。

ClassLoader : 类加载器-通常使用被代理类的类加载器
Class[] interfaces : 要实现的接口
InvocationHandler : 调用处理器

利用反射机制在运行时创建代理类。
接口、被代理类不变,我们构建一个handler类来实现InvocationHandler接口。

public class ProxyHandler implements InvocationHandler{
    private Object object;
    public ProxyHandler(Object object){
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before invoke "  + method.getName());
        method.invoke(object, args);
        System.out.println("After invoke " + method.getName());
        return null;
    }
}

执行动态代理:

public static void main(String[] args) {

HelloInterface hello = new Hello();
    
InvocationHandler handler = new ProxyHandler(hello);

HelloInterface proxyHello = (HelloInterface) Proxy.newProxyInstance(hello.getClass().getClassLoader(), hello.getClass().getInterfaces(), handler);

proxyHello.sayHello();
}

输出:

Before invoke sayHello
Hello!!!!
After invoke sayHello

通过Proxy类的静态方法newProxyInstance返回一个接口的代理实例。针对不同的代理类,传入相应的代理程序控制器InvocationHandler
如果新来一个被代理类Bye,如:

public interface ByeInterface {
    void sayBye();
}
public class Bye implements ByeInterface {
    @Override
    public void sayBye() {
        System.out.println("Bye!!!!");
    }
}

那么执行过程:

public static void main(String[] args) {
    HelloInterface hello = new Hello();
    InvocationHandler handler = new ProxyHandler(hello);
	HelloInterface proxyHello = (HelloInterface) Proxy.newProxyInstance(hello.getClass().getClassLoader(), hello.getClass().getInterfaces(), handler);
	proxyHello.sayHello();
	
	System.out.println();

    ByeInterface bye = new Bye();
    InvocationHandler handler1 = new ProxyHandler(bye);
	ByeInterface proxyBye = (ByeInterface) Proxy.newProxyInstance(bye.getClass().getClassLoader(), bye.getClass().getInterfaces(), handler1);
    proxyBye.sayBye();
}

输出:

Before invoke sayHello
Hello!!!!
After invoke sayHello

Before invoke sayBye
Bye!!!!
After invoke sayBye
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值