JAVA代理模式
代理模式:通过代理类访问被代理类,用于对被代理类功能的加强与功能的扩展
用户可以通过访问代理类来调用被代理类的功能
代理模式类图:
假设:用户需要验证信息后访问管理员
角色:
- 用户:用于访问管理员对象
- 管理员:对数据进行操作
- 管理员代理:代表管理员进行数据操作,并对原来的管理员进行增强
静态代理
静态代理模式在不改变目标对象的前提下,实现了对目标对象的功能扩展。
不足:静态代理实现了目标对象的所有方法,一旦目标接口增加方法,代理对象和目标对象都要进行相应的修改,增加维护成本。
管理员接口
Admin:代理类与被代理的委托类共有的方法,用于让代理与委托的方法统一
public interface Admin {
void update();
void select();
}
委托类
AdminDelegatorInter:委托类的接口,用于实现委托对象的多态实现
public interface AdminProxyInter extends Admin {
}
AdminDelegator:管理员实现类(委托类)
public class AdminDelegator implements AdminDelegatorInter {
@Override
public void update() {
System.out.println("上传数据");
}
@Override
public void select() {
System.out.println("查询数据");
}
}
UserAdminDelegator:用户管理员实现类(委托类)
public class UserAdminDelegator implements top.xtijie.staticProxy.delegator.AdminDelegatorInter {
@Override
public void update() {
System.out.println("上传用户数据");
}
@Override
public void select() {
System.out.println("查询用户数据");
}
}
代理类
AdminProxyInter:代理类的接口,实现代理对象的多态实现
public interface AdminProxyInter extends Admin {
}
AdminProxy:代理管理员的实现类(代理类)
import top.xtijie.staticProxy.delegator.AdminDelegatorInter;
public class AdminProxy implements AdminProxyInter {
private final AdminDelegatorInter adminDelegator;
public AdminProxy(AdminDelegatorInter adminDelegator) {
this.adminDelegator = adminDelegator;
}
@Override
public void update() {
System.out.println("查询管理员权限");
adminDelegator.update();
}
@Override
public void select() {
System.out.println("查询查询权限");
adminDelegator.select();
}
}
UserAdminProxy:代理用户管理员实现类(代理类)
import top.xtijie.staticProxy.delegator.AdminDelegatorInter;
public class UserAdminProxy implements AdminProxyInter {
private final AdminDelegatorInter delegatorInter;
public UserAdminProxy(AdminDelegatorInter delegatorInter) {
this.delegatorInter = delegatorInter;
}
@Override
public void update() {
System.out.println("查询用户管理权限");
delegatorInter.update();
}
@Override
public void select() {
System.out.println("查询用户权限");
delegatorInter.select();
}
}
用户访问
public class APP {
public static void main(String[] args) {
// 创建管理员委托实例
// AdminDelegatorInter adminDelegator = new AdminDelegator();
AdminDelegatorInter adminDelegator = new UserAdminDelegator();
// 创建代理管理员实例
// AdminProxyInter adminProxy = new AdminProxy(adminDelegator);
AdminProxyInter adminProxy = new UserAdminProxy(adminDelegator);
adminProxy.update();
}
}
代理类的中需要有委托类的对象
用户只需创建不同的委托对象,并将委托对象放入不同的代理对象,即可实现对功能的扩展
动态代理
Java自带动态代理类:Proxy
为解决静态代理对象必须实现接口的所有方法的问题,Java给出了动态代理,动态代理具有如下特点:
- Proxy对象不需要implements接口
- Proxy对象的生成利用JDK的Api,在JVM内存中动态的构建Proxy对象。需要使用
Java动态代理中,代理对象不需要自己手动创建,由Java自带对象Proxy进行创建
Invocation:Java进行动态代理时需要的调用器
管理员接口
Admin:代理类与被代理的委托类共有的方法,用于让代理与委托的方法统一
public interface Admin {
public void select();
public void update();
}
调用器
AdminInvocation:管理员调用器,通过实现InvocationHandler接口,可以实现对委托类的调用
import top.xtijie.dynamicProxy.delegator.AdminDelegator;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class AdminInvocation implements InvocationHandler {
private final AdminDelegator adminDelegator;
public AdminInvocation(AdminDelegator adminDelegator) {
this.adminDelegator = adminDelegator;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("检查权限");
return method.invoke(adminDelegator, args);
// return proxy;
}
}
invoke方法:
参数:
- proxy:代理对象
- method:调用的方法
- args:方法中的参数
返回值:
- 当返回method.invoke(adminDelegator, args);时,代理对象将执行当前方法中的其他代码,并返回代理对象
- 当返回参数中的proxy时,代理对象将直接返回委托类中的方法,不执行当前方法中的其他代码,不对功能进行扩展
委托类
AdminDelegator:委托类
import top.xtijie.dynamicProxy.mapp.Admin;
public class AdminDelegator implements Admin {
@Override
public void update() {
System.out.println("上传数据");
}
@Override
public void select() {
System.out.println("查询数据");
}
}
用户访问
public class APP {
public static void main(String[] args) {
AdminDelegator adminDelegator = new AdminDelegator();
AdminInvocation adminInvocation = new AdminInvocation(adminDelegator);
Admin proxy = (Admin) Proxy.newProxyInstance(
adminDelegator.getClass().getClassLoader(),
new Class[]{Admin.class},
adminInvocation);
proxy.update();
}
}
用户仍然需要创建管理员委托对象,并将委托类置于调用器中,调用器执行完方法后会返回当前的代理对象
委托类创建Proxy.newProxyInstance()
的参数描述:
- adminDelegator.getClass().getClassLoader():管理员委托类的类加载器,用于Java加载该对象
- new Class[]{Admin.class}:委托类所实现的接口的Class对象的数组,用于指定当前委托类的接口
- adminInvocation:委托类的调用加载程序
参考:
Java代理(Proxy)模式 - 简书 (jianshu.com)
设计模式之代理模式(Proxy Pattern) - 有点小白的菜鸟 - 博客园 (cnblogs.com)
(44条消息) Java中InvocationHandler接口中第一个参数proxy详解_艾米莉Emily的博客-CSDN博客_invocationhandler接口