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!
相关推荐
fake_ss1987 小时前
AI时代学习全栈项目开发的新范式
java·人工智能·学习·架构·个人开发·学习方法
未若君雅裁7 小时前
Spring AOP、日志切面与声明式事务原理
java·后端·spring
Upsy-Daisy7 小时前
AI Agent 项目学习笔记(二):Spring AI 与 ChatClient 主链路解析
人工智能·笔记·学习
C+++Python9 小时前
C++ 进阶学习完整指南
java·c++·学习
sulikey10 小时前
个人Linux操作系统学习笔记2 - gcc与库的理解
linux·笔记·学习·操作系统·gcc·
南浦别a10 小时前
第102天--时隔多日的书写
学习·程序人生
Jackyzhe10 小时前
从零学习Kafka:消费者组重平衡
分布式·学习·kafka
吃好睡好便好10 小时前
在Creo中如何把新建零件文件时的默认模板设置为公制单位
学习·3d·信息可视化
优橙教育10 小时前
5G网络优化关键参数解读:从入门到实战
网络·学习·5g
WG_1711 小时前
虚拟机共享文件挂载
学习