0
点赞
收藏
分享

微信扫一扫

Java基础知识回顾10-代理模式

一、简介

代理模式是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。

抽象角色:通过接口或抽象类声明真实角色实现的业务方法。

代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

优点:

1.职责清晰:真实角色就是实现实际业务逻辑,不用关心其他非本职的事务,通过后期的代理完成一件完成事务。

2.保护对象: 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。

二、模式结构

一个是真正的你要访问的对象,一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。代理模式分为静态代理和动态代理。

静态代理是由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。

三、静态代理

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

1.定义业务接口

package day02;

/**
 * @author qx
 * @date 2023/10/27
 * @des 定义业务接口
 */
public interface DogService {

    void eat();
}

2.目标实现类 + 实现业务功能

package day02;

/**
 * @author qx
 * @date 2023/10/27
 * @des 目标实现类 + 实现业务功能
 */
public class Dog implements DogService {
    @Override
    public void eat() {
        System.out.println("狗吃狗粮");
    }
}

3.代理实现类+ 增强功能访问

package day02;

/**
 * @author qx
 * @date 2023/10/27
 * @des 代理实现类+ 增强功能访问
 */
public class DogSuper implements DogService {
    @Override
    public void eat() {
        System.out.println("狗可以自己找骨头");
        // 使用代理类
        Dog dog = new Dog();
        dog.eat();
    }
}

四、动态代理

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

package day02;

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

/**
 * @author qx
 * @date 2023/10/27
 * @des
 */
public class ProxyInvocationHandler implements InvocationHandler {
    private Object target;

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    /**
     * 生成得到代理类
     *
     * @return
     */
    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName());
        // 动态代理的本质就是使用反射机制来实现
        return method.invoke(target, args);
    }
}

创建业务接口:

package day02;

/**
 * @author qx
 * @date 2023/10/27
 * @des 定义业务接口
 */
public interface DogService {

    void eat();
}

创建目标实现类:

package day02;

/**
 * @author qx
 * @date 2023/10/27
 * @des 目标实现类 + 实现业务功能
 */
public class DogServiceImpl implements DogService {
    @Override
    public void eat() {
        System.out.println("狗吃狗粮");
    }
}

动态代理测试:

package day02;

/**
 * @author qx
 * @date 2023/10/27
 * @des 多态代理测试
 */
public class ProxyTest {
    public static void main(String[] args) {
        // 真实角色
        DogService dogService = new DogServiceImpl();

        // 代理角色
        ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
        // 通过调用程序处理角色来处理我们要调用的接口对象
        proxyInvocationHandler.setTarget(dogService);

        DogService proxy = (DogService) proxyInvocationHandler.getProxy();
        proxy.eat();
    }
}

输出:

eat
狗吃狗粮

举报

相关推荐

0 条评论