spring_代理模式_学习笔记

代理模式到aop的学习

1 静态代理模式

例一:
直接采用一个日常租房的例子来理解
首先 租房这个行为是租客、中介、房东都会去执行的行为,但是房东租房由中介去代理完成
定义Renting接口

java 复制代码
public interface Renting {
    //租房
    void rent();
}

房东Landlord实现接口

java 复制代码
public class Landlord implements Renting{
    @Override
    public void rent() {
        System.out.println("劳资要租房!!");
    }
}

中介Agent实现接口

中介除了会代理租房外,还会帮助办理一些其他的事务

这里我们使用组合来获取房东的属性

java 复制代码
public class Agent implements Renting{
    //组合
    private Landlord landlord;

    public void setLandlord(Landlord landlord) {
        this.landlord = landlord;
    }
    //代理租房
    @Override
    public void rent() {
        contract();
        landlord.rent();
    }
    //会帮助房东办理相关手续
    public void contract(){
        System.out.println("中介帮你办你签合同");
    }
}

服务类Client 完成租房

java 复制代码
public class Client {
    public static void main(String[] args) {
        //房东
        Landlord landlord = new Landlord();

        Agent agent = new Agent();
        //注入相关属性
        agent.setLandlord(landlord);

        agent.rent();
    }
}

结果示例

txt 复制代码
中介帮你办你签合同
劳资要租房!!

例二:
采用一个对用户的CRUD的例子来理解
定义接口

java 复制代码
public interface UserService {
    void add();
    void delete();
    void update();
    void query();
}

实现接口

java 复制代码
public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加了一个User!");
    }
    @Override
    public void delete() {
        System.out.println("删除了一个User!");
    }
    @Override
    public void update() {
        System.out.println("更新了一个User!");
    }
    @Override
    public void query() {
        System.out.println("查询了一个User!");
    }
}

创建代理类

此代理类首先代理实现了CRUD功能

此外,如果我还需要对原有的操作进行功能的扩展,可以不对其原来的代码进行修改,直接新增,这就是代理模式的好处

java 复制代码
public class UserServiceProxy implements UserService{
    //组合获取相关属性
    UserServiceImpl userService;
    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }
    //好处是不用去修改原来的业务代码
    @Override
    public void add() {
        printDebug("add");
        userService.add();
    }
    @Override
    public void delete() {
        printDebug("delete");
        userService.delete();
    }
    @Override
    public void update() {
        printDebug("update");
        userService.update();
    }
    @Override
    public void query() {
        printDebug("query");
        userService.query();
    }
    //新增的功能
    public void printDebug(String method){
        System.out.println("[DEBUG] 调用了"+method+"方法");
    }
}

服务类Client 完成相关操作

java 复制代码
public class Client {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();

        UserServiceProxy userServiceProxy = new UserServiceProxy();
        userServiceProxy.setUserService(userService);
        userServiceProxy.add();
    }
}

结果示例

txt 复制代码
[DEBUG] 调用了add方法
增加了一个User!

2 动态代理模式

静态代理和动态代理的区别

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

动态代理:动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

仍采用上面那个例子

UserService与UserServiceImpl与上同
创建ProxyInvocationHandler 实现 InvocationHandler接口

java 复制代码
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }
    //生成得到代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
    }
    //重写invoke方法 处理代理实例 并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        printDebug(method.getName());
        Object result = method.invoke(target,args);
        return result;
    }
    public void printDebug(String method){
        System.out.println("[DEBUG] 调用了"+method+"方法");
    }
}
//可以复用此模板

实现类

java 复制代码
public class Client {
    public static void main(String[] args) {
        //真实角色
        UserServiceImpl userService = new UserServiceImpl();
        //代理角色 不存在
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //设置要代理的对象
        pih.setTarget(userService);
        //动态生成代理类
        UserService proxy = (UserService) pih.getProxy();
        proxy.add();
    }
}

结果示例

txt 复制代码
[DEBUG] 调用了add方法
增加了一个User!
相关推荐
视觉小萌新9 小时前
AI Class 3 · Chapter 1:变量、字符串、list/dict、if/for(python学习-小白版-有经验可跳过)
python·学习·list
霸道流氓气质10 小时前
AI 流式对话与实时聊天平台:SSE 解码竞态、有状态会话隔离与背压取消的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
yyyang8812 小时前
蓝牙系统整体架构详解
学习·信息与通信
Linux-lucky12 小时前
46-Linux学习之旅之LVS负载均衡与keepalived高可用
linux·运维·学习·ubuntu·负载均衡·lvs
frjc14 小时前
Spring AI 高级实战:ChatMemory、Tool Calling 与 MCP 架构解析
人工智能·spring·架构
金色光环14 小时前
【DSP学习】C2000_ADC中断_笔记
笔记·学习
Дерек的学习记录14 小时前
Unreal Engine 5:第三人称运动系统和人物动画
开发语言·学习·ue5
zhangrelay14 小时前
mrpt杂乱笔记-26-10-31
笔记·学习
衡石科技15 小时前
让多轮问数保持口径一致:Data Agent 的上下文、偏好与学习开关
人工智能·学习·安全
T量子永生15 小时前
Unisoc(紫光展锐) Kernel 6.18 DDK 编译框架详解
linux·运维·spring