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!
相关推荐
勤匠1 小时前
spring shell 基础使用
java·linux·spring
Code季风2 小时前
测试驱动开发(TDD)实战:在 Spring 框架实现中践行 “红 - 绿 - 重构“ 循环
java·驱动开发·后端·spring·设计模式·springboot·tdd
想要成为祖国的花朵2 小时前
Java_Springboot技术框架讲解部分(二)
java·开发语言·spring boot·spring
Pocker_Spades_A2 小时前
TextIn:文档全能助手,让学习效率飙升的良心软件~
学习·textln
我.佛.糍.粑3 小时前
Shusen Wang推荐系统学习 --召回 矩阵补充 双塔模型
人工智能·学习·机器学习·矩阵·推荐算法
好奇龙猫3 小时前
日语学习-日语知识点小记-构建基础-JLPT-N3阶段(3):语法+单词+復習
学习
iam_leeqing3 小时前
Lambda表达式
java·spring
JouJz4 小时前
设计模式之代理模式:掌控对象访问的优雅之道
java·spring·设计模式·系统安全·代理模式
今天背单词了吗9804 小时前
算法学习笔记:16.哈希算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题
笔记·学习·算法
ta叫我小白4 小时前
Spring Boot 设置滚动日志logback
java·spring boot·spring·logback