代理模式 -- 学习笔记

代理模式学习笔记

什么是代理?

代理是一种设计模式,用户可以通过代理操作,而真正去进行处理的是我们的目标对象,代理可以在方法增强(如:记录日志,添加事务,监控等)

拿一个例子说话。

Uservice.java:接口,有个一保存用户的接口

java 复制代码
public interface UserService {
    void save();
}

实现类

java 复制代码
public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        System.out.println("添加User");
    }
}

如果现在提出一个需求,需要在Service方法上都要记录日志。那常规做法就是在方法上加上记录日志的逻辑。

java 复制代码
public class UserServiceProxy implements UserService {
    @Override
    public void save() {
    	System.out.println("开启日志--");
        System.out.println("添加User");
    }
}

但是这样,如果接口有很多方法。那就要每一个方法都要去添加这段逻辑。

这个时候就需要请我们的代理来做了,用户通过代理去调用方法,代理就去找目标方法去做事

java 复制代码
public class UserServiceProxy  implements UserService {
    private UserService target;
    public UserServiceProxy(UserService target) {
        this.target = target;
    }

    public void save(){
        System.out.println("开启日志");
        target.save();
    }
}
java 复制代码
public class Main {
    public static void main(String[] args) {
        UserServiceProxy userServiceProxy = new UserServiceProxy(new UserServiceImpl());
        userServiceProxy.save();
    }
}

这样在使用的时候直接传入我们的目标对象给代理,就能每一个方法都能记录日志,其实这个就是静态代理,代理分为静态代理和动态代理两种。静态代理的特点就是要实现接口,如果接口后面要进行拓展修改,就需要我们去手动修改代理对象的方法。

所以这时候就需要动态代理了。

静态代理

上面以及介绍了静态代理了

动态代理

动态代理的特定就是不需要实现接口,但是需要使用JDK的api,用到里面的Proxy
Proxy.newProxyInstance()

参数1ClassLoader:类装载器

参数2interfaces:代理类的接口

参数3InvocationHandler:方法调用执行器

将上述类中方法用动态代理的方式改写

java 复制代码
public class UserServiceProxy{
    UserService userService = new UserServiceImpl();
    public UserService getInstant(){
        return (UserService)Proxy.newProxyInstance(UserServiceProxy.class.getClassLoader(), userService.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * @param proxy 代理对象 --- UserServiceProxy
                     *
                     * @param method 代理对象调用的方法
                     *
                     * @param args 方法参数
                     *
                     * @return
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开启日志--");
                        return method.invoke(userService, args);
                    }
                });
    }
}

调用处:

java 复制代码
public class Main {
    public static void main(String[] args) {
        UserServiceProxy userServiceProxy = new UserServiceProxy();
        UserService proxyInstant = userServiceProxy.getInstant();
        proxyInstant.save();
    }
}

运行结果:

相关推荐
星星火柴93617 分钟前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头18 分钟前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
艾莉丝努力练剑1 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
武昌库里写JAVA2 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习
Cx330❀3 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
杜子不疼.3 小时前
《Python学习之字典(一):基础操作与核心用法》
开发语言·python·学习
小幽余生不加糖3 小时前
电路方案分析(二十二)适用于音频应用的25-50W反激电源方案
人工智能·笔记·学习·音视频
..过云雨4 小时前
01.【数据结构-C语言】数据结构概念&算法效率(时间复杂度和空间复杂度)
c语言·数据结构·笔记·学习
myzzb4 小时前
基于uiautomation的自动化流程RPA开源开发演示
运维·python·学习·算法·自动化·rpa
岑梓铭5 小时前
考研408《计算机组成原理》复习笔记,第五章(3)——CPU的【数据通路】
笔记·考研·408·计算机组成原理·计组