代理模式

一、代理

  • 代理有三种模式
  • 在静态代理模式之下,我们显示地创建代理类,代理类持有被代理类的对象,实现与被代理类的相同接口,并且增添相应的业务逻辑,以达到代理的效果。

在这里插入图片描述

1、静态代理

代码步骤:
1.接口
2.真实角色
3.代理角色
4.客户端访问代理角色

  • 假设:房东要出租,但是不想要麻烦自己,然后就是装让给中介,就现在,房东是出租房,中介也是出租房,但是中介是管理房东房

/**
 * @Author Lin_Home
 * @Date 2020/8/18 14:51
 * @Version 1.0
 */

/**
 * 静态代理的使用
 * */

//定义一个服务的类
interface Server{
    //定义一个客户询问话题
    void say(String name);
}

//定义一个人工服务对接的实现类
class Waiter implements Server{
    @Override
    public void say(String name) {
        System.out.println(name+"你好,有什么问题需要为你服务");
    }
}


//设置一个代理,目的就是解决一些琐碎的事情
class Proxy implements Server{
    private Waiter  waiter;
    public Proxy(Waiter waiter) {
        this.waiter = waiter;
    }

    @Override
    public void say(String name) {
        System.out.println("欢迎咨询10086"+name);
        waiter.say(name);
        System.out.println("谢谢"+name);
    }
}

public class MainTest {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        Proxy boyPeople = new Proxy(waiter);
        boyPeople.say("小米");
    }

}

2、动态代理

  • 创建一个处理类

    • 必须要实现InvocationHandler 跟 调用Porty 方法

    • 重写invoke(Object proxy, Method method, Object[] args)

      • 参数一:proxy:代理类的对象
      • 参数二:method:代理类对象调用的方法
      • 参数三:args:代理类方法的参数
      • 此方法就是编写代理的逻辑代码增强

在这里插入图片描述

  • 定义一个接口
package porxy.com.cn;

/**
 * @Author Lin_Home
 * @Date 2020/8/6 14:34
 * @Version 1.0
 */
public interface Send {
    void chuzu();
}


  • 实现代理接口
package porxy.com.cn;

/**
 * @Author Lin_Home
 * @Date 2020/8/6 16:13
 * @Version 1.0
 */
public class Person implements Send {
    @Override
    public void chuzu() {
        System.out.println("出租");
    }
}

  • 编写一个代理实现代理接口
package porxy.com.cn;

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

/**
 * @Author Lin_Home
 * @Date 2020/8/6 14:29
 * @Version 1.0
 */

//这个代理你可以想是中介。中介想干什么就干什么
public class JdkPorxy implements InvocationHandler {
    //被代理的接口(用户出租)
    public Person person;

    public JdkPorxy() {
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    //看房
    public void seeHouse(){
        System.out.println("看房");
    }
    //收中介费
    public void fare(){
        System.out.println("签约");
    }


    public JdkPorxy(Person person) {
        this.person = person;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                person.getClass().getInterfaces(),this);
    }

    //处理代理实例,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        Object invoke = method.invoke(person, args);
        fare();
        return invoke;
    }
}

  • 编写一个测试类
package porxy.com.cn;

/**
 * @Author Lin_Home
 * @Date 2020/8/6 16:34
 * @Version 1.0
 */
public class MainTest {
    public static void main(String[] args) {
        JdkPorxy jdkPorxy = new JdkPorxy();
        Person person = new Person();
        jdkPorxy.setPerson(person);
        Send proxy = (Send) jdkPorxy.getProxy(); //动态生成对应的代理类
        proxy.chuzu();
    }
}

3、cglib的动态代理(针对于类)

  • 需要导入cglib的所需要的的库使用

  • 通过cglib的动态代理它能够针对实现没有接口的目标类,进行动态代理。

  • 实现原理

    • cglib它会生成目标类的子类实现,因此目标类作为父类注入,并且调用父类的方法

    • 实现过程

      • 创建目标类,此目标类不需要实现任何的接口

      • 创建方法的拦截器类

        • 此类实现MethodInterceptor
        • 重写intercept方法
  • 写一个类

package porxy.com.cn;

/**
 * @Author Lin_Home
 * @Date 2020/11/6 16:13
 * @Version 1.0
 */
public class Person2 {
    public void chuzu() {
        System.out.println("房屋出租");
    }
}

  • 实现cgLib的核心方法 MethodInterceptor
package porxy.com.cn;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @Author Lin_Home
 * @Date 2020/8/6 17:12
 * @Version 1.0
 */
public class CgLibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        seeHouse();
        Person2 person = new Person2();
        method.invoke(person,objects);
        fare();
        return null;

    }


    //看房
    public void seeHouse(){
        System.out.println("带房客看房");
    }
    //收中介费
    public void fare(){
        System.out.println("收中介费");
    }

}
  • 写一个测试类
package porxy.com.cn;

import net.sf.cglib.proxy.Enhancer;

/**
 * @Author Lin_Home
 * @Date 2020/11/6 16:34
 * @Version 1.0
 */
public class MainTest {
    public static void main(String[] args) {
        //创建处理类的对象
        CgLibProxy interceptor = new CgLibProxy();
        //创建Enhancer对象,目的是增强对象
        Enhancer enhancer = new Enhancer();
        //获取字节文件
        enhancer.setSuperclass(Person2.class);
        //回调函数
        enhancer.setCallback(interceptor);
        //生成代理类对象
        Person2 proxyWaiter = (Person2) enhancer.create();
        proxyWaiter.chuzu();
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值