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!
相关推荐
爱倒腾的老唐19 分钟前
0、元器件——电阻
学习
sunshine22 girl1 小时前
Java学习七 Java 项目实战2-注册业务
java·学习
sunshine22 girl3 小时前
Java学习七 Java 项目实战1-项目创建和主页面搭建
java·开发语言·学习
传奇开心果编程4 小时前
【SwiftUI提高练中学】第8课 网络层架构:拦截器、重试、缓存与离线优先
学习·macos·ui·ios·swiftui
一条破秋裤4 小时前
内核驱动的意义与课程学习规划
学习
Bug收容所4 小时前
学习LangChain day1
学习·langchain·llm·agent
传奇开心果编程4 小时前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
我命由我123456 小时前
Photoshop - Photoshop 矢量蒙版
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·photoshop
熊猫钓鱼>_>7 小时前
越顺,越空:当 AI 把学习 “优化“ 到消失
人工智能·学习·ai·llm·agent·ai编程·metaai
一条破秋裤7 小时前
02_注册设备号_从主次设备号到成对注销
学习