【java】代理

什么是代理

假设有一个核心方法叫转账,为了安全性考虑,不能让用户直接访问接口。此时涉及到了代理,这使得用户只能访问代理类,增加了访问限制。

代理的定义:给目标对象提供一个代理对象,并且由代理对象控制着对目标对象的引用。

代理如何实现
基于JDK的代理
① 静态代理

由代理类代理目标类:

目标类生成一个目标对象,代理类首先会生成代理对象,代理对象代理目标对象,普通用户只能访问代理对象。

一个类中可能有很多方法,代理类怎么知道代理目标类的哪个方法呢?除了直接写过去,我们还可以在接口 当中定义目标类当中需要被代理的方法。让目标类实现一个接口,同时代理类也去实现这个接口。

注意:实现接口的是类,而用户访问的是对象。

为什么有接口:接口定义的方法其子类必须实现**,**让目标类实现在接口当中定义的核心方法(目标类实现了接口),为了通知代理类代理目标类当中的哪个核心方法,我们也让代理类实现接口。

在具体实现的过程中,为了保证职能的单一性,功能增强部分的代码最好不写在目标类里。

如何实现静态代理
java 复制代码
public interface ByClothes {  //代理类和目标类都要继承该接口
    //在接口当中定义需要代理的方法
    public void clothes(String size) ;
}
java 复制代码
public class ClothesFactory implements ByClothes{  //目标类 :制作衣服
    public void clothes(String size) {  //目标类的核心
        System.out.println("已经为您定制好了一件大小为" + size + "的衣服");
    }
}
java 复制代码
public class StaticProxy implements ByClothes{  //代理类
    private ClothesFactory clothesFactory = new ClothesFactory();
    //这个地方就是核心方法
    @Override
    public void clothes(String size) {
        front();  //功能增强
        clothesFactory.clothes(size);  //核心方法
        end();  //功能增强
    }
    public void front() {
        System.out.println("市场调研");
    }
    public void end() {
        System.out.println("售后服务");
    }
}
java 复制代码
public class Test { //用户
    public static void main(String[] args) {
        StaticProxy proxy = new StaticProxy();
        proxy.clothes("XXXL");
    }
}

运行结果

② 动态代理

动态代理指的是一个代理类代理多个目标类。

如何实现?类是创建对象的模板

一个代理类生成多个代理对象即可。

为了实现动态化,我们要想办法告诉代码想要代理的是什么。

如何实现动态代理
java 复制代码
public interface ByClothes {  //代理类和目标类都要继承该接口
    //在接口当中定义需要代理的方法
    public void clothes(String size) ;
}
java 复制代码
public interface ByShoes {
    public void shoes(Integer size); //接口当中不需要具体实现
}
java 复制代码
public class ClothesFactory implements ByClothes{  //目标类 :制作衣服
    public void clothes(String size) {  //目标类的核心
        System.out.println("已经为您定制好了一件大小为" + size + "的衣服");
    }
}
java 复制代码
public class ShoesFactory implements ByShoes{
    @Override
    public void shoes(Integer size) {
        System.out.println("已经为您定制了大小为" + size + "码的鞋子");
    }
}
java 复制代码
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DTProxy implements InvocationHandler {
    //被代理的对象
    private Object factory;
    public DTProxy(Object factory) {
        this.factory = factory;
    }
    //为了能够动态的去实现新增的接口
    //factory.getClass() ---------> 对象名.getClass() == class.forName("全类名")  //生成代理对象
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
    }
    //我们会根据getProxyInstance()方法中所得到的接口信息,得到核心方法
    //我们只需要用反射的方式执行这些方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(factory, args);
        return null;
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        ClothesFactory clothesFactory = new ClothesFactory();
        DTProxy p1 = new DTProxy(clothesFactory);
        ByClothes c1 = (ByClothes) p1.getProxyInstance();
        c1.clothes("XXL");

        ShoesFactory shoesFactory = new ShoesFactory();
        DTProxy p2 = new DTProxy(shoesFactory);
        ByShoes c2 = (ByShoes) p2.getProxyInstance();
        c2.shoes(44);
    }
}

运行结果

相关推荐
好家伙VCC2 分钟前
**InfluxDB实战进阶:基于Golang的高性能时序数据采集与可视化方
java·开发语言·后端·python·golang
yu85939583 分钟前
WinForm 嵌入 WordExcel 实现方案
开发语言·microsoft·c#
斌味代码3 分钟前
Java SpringBoot 微服务实战:企业级架构设计与性能调优完全指南
java·spring boot·微服务
好家伙VCC3 分钟前
**发散创新:基于Go语言的服务网格实践与流量治理实战**在微服务架构日益复杂的今天,**服务网格(S
java·python·微服务·架构·golang
沐知全栈开发4 分钟前
SQLite 常用函数
开发语言
TE-茶叶蛋5 分钟前
PHP入门指南
开发语言·php
lolo大魔王11 分钟前
Go语言的循环语句、判断语句、通道选择语句
开发语言·算法·golang
551只玄猫2 小时前
【数学建模 matlab 实验报告12】聚类分析和判别分析
开发语言·数学建模·matlab·课程设计·聚类·实验报告
小陈工4 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
H Journey4 小时前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake