一、简介
代理模式是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
优点:
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
狗吃狗粮
标签:10,Java,角色,对象,代理,接口,基础知识,实现,public
From: https://blog.51cto.com/u_13312531/8379599