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

框架

使用代理的好处在于:当用户要求添加功能时,可以避免修改业务层代码,通过修改代理层即可实现。
在这里插入图片描述

静态代理

静态代理有一个缺点:代理层需要实现一遍抽象层的方法,将代码量增加一倍;

抽象层

package com.tl.demo01;

/**
 * @author tl
 */
public interface Rent {
    public void rent();
    public void go();
    public void send();
}

真实层

package com.tl.demo01;

/**
 * @author tl
 */
public class Host implements Rent{
    public void rent() {
        System.out.println("租你3个月");
    }

    public void go() {
        System.out.println("走吧,不租了");
    }

    public void send() {
        System.out.println("不要钱,这房子送你了");
    }
}

代理层

package com.tl.demo01;

/**
 * @author tl
 */
public class Proxy implements Rent{
    //组合
    private Host host;

    public void setHost(Host host) {
        this.host = host;
    }

    public void rent() {
        host.rent();
    }

    public void go() {
        host.go();
        add();
    }

    public void send() {
        host.send();
        delete();
    }

    public void add(){
        System.out.println("得加钱");
    }
    public void delete(){
        System.out.println("你说了算");
    }
}

测试

import com.tl.demo01.Host;
import com.tl.demo01.Proxy;

/**
 * @author tl
 */
public class Test {
    @org.junit.Test
    public void test1(){
        Proxy proxy = new Proxy();
        proxy.setHost(new Host());
        proxy.rent();
        proxy.go();
        proxy.send();
    }
}

在这里插入图片描述
静态代理太笨重了,需要动态代理。

动态代理

这里使用的是java jdk8中的动态代理(基于接口)

创建调用处理程序类

该类实现了InvocationHandler接口

package com.tl.demo01;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author tl
 * 调用处理程序
 * Invocation单词意思为召唤
 * 每个代理实例都有一个关联的调用处理程序。
 * 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。
 */
public class ProxyInvocationHandler implements InvocationHandler {
	//组合抽象层(接口)
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }
	//获取代理实例
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                rent.getClass().getInterfaces(),this);
    }
    //处理代理实例上的方法调用并返回结果。
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    	log(method.getName());
        add();
        return method.invoke(rent,args);
    }
	
	public void add(){
        System.out.println("得加钱");
    }
    public void log(String msg){
        System.out.println("[Debug] 使用了一个"+msg+"方法");
    }
}

抽象层(接口)

package com.tl.demo01;

/**
 * @author tl
 */
public interface Rent {
    public void rent();
    public void go();
    public void send();
}

真实层

package com.tl.demo01;

/**
 * @author tl
 */
public class Host implements Rent{
    public void rent() {
        System.out.println("租你3个月");
    }

    public void go() {
        System.out.println("走吧,不租了");
    }

    public void send() {
        System.out.println("不要钱,这房子送你了");
    }
}

测试

import com.tl.demo01.Host;
import com.tl.demo01.ProxyInvocationHandler;
import com.tl.demo01.Rent;

/**
 * @author tl
 */
public class Test {
    @org.junit.Test
    public void test1(){
        ProxyInvocationHandler handler = new ProxyInvocationHandler();
        //传入接口实现类
        handler.setRent(new Host());
        //获取相应的代理实例
        Rent proxy = (Rent) handler.getProxy();
        proxy.send();
        proxy.go();
        proxy.rent();
    }
}

在这里插入图片描述
动态代理不需要手写代理类了,并且,在调用处理程序中添加一个方法,就可以将该方法内容添加到每一个抽象方法中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值