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!
相关推荐
im_AMBER15 分钟前
数据结构 06 线性结构
数据结构·学习·算法
Main. 247 小时前
从0到1学习Qt -- 创建第一个Hello World项目
学习
壹号用户7 小时前
python学习之生成器&三者关系
学习
new coder7 小时前
[c++语法学习]Day10:c++引用
开发语言·c++·学习
星域智链7 小时前
宠物智能用品:当毛孩子遇上 AI,是便利还是过度?
人工智能·科技·学习·宠物
呱呱巨基8 小时前
vim编辑器
linux·笔记·学习·编辑器·vim
AntBlack8 小时前
虽迟但到 :盘一盘 SpringAI 现在发展得怎么样了?
后端·spring·openai
"菠萝"8 小时前
C#知识学习-017(修饰符_6)
学习·c#
早睡冠军候选人8 小时前
Ansible学习----Ansible Playbook
运维·服务器·学习·云原生·容器·ansible
楼田莉子8 小时前
C++学习:C++11扩展:constexpr特性
开发语言·c++·学习