代理设计模式,框架AOP思想

文章目录

引言🤪

代理 (proxy) ,举个生活中常见的现象,在之前网路还未走进大众的时代里,如果我们想买一些东西,只是直接去店里,现在网络普及了,互联网+shopping,使我们足不出户就可以办很多事,比如网上购物,注意啊,网上购物大多数都是有一个代收点,而不是直接送到你的手上,家里,为什么呢?,因为那样的代价会很大,影响效率,所以出现了代收点,我们再去代收点去拿到网购的货物,完成网购,那么,根据这个现象,如果放在编程中,我们就可以把这个代收点比做成是一个代理对象,在整个购物的过程中起到了一个代收的作用,同时他也介入了购物的一部分,OK

代理对象(Proxy)

代理:指的是一种设计模式

作用:在整个业务中完成一些 业务之外的附加操作,同时也可以中断整个业务

好处:专注于业务开发,对于一些附加操作,交予代理完成一些繁琐的重复的操作,好耶!

如何开发一个代理对象

1.代理对象要和原始业务对象有用一个规定,放在面向对象中就是实现同一个接口(interface)

2.代理对象依赖业务对象

开发中的业务层代码冗余问题

ShopService接口

java 复制代码
//商品业务的接口
public interface ShopService {
    //添加商品
    void add();
    //下架商品
    void remove();
    //......
}

ShopService接口实现类ShopServiceImpl

java 复制代码
public class ShopServiceImpl implements ShopService {
    @Override
    public void add() {
        try {
            System.out.println("开启事务");
            System.out.println("处理添加商品业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void remove() {
        try {
            System.out.println("开启事务");
            System.out.println("处理添下架商品业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }
}

测试一下

java 复制代码
public class ShopTest {
    public static void main(String[] args) {
        ShopServiceImpl shopService = new ShopServiceImpl();
        shopService.add();
        shopService.remove();
    }
}

是没有任何问题的,但是你会发现service控制事务的代码大量冗余,一点也不优雅,在做重复的事情,如果是你,你会怎么优化呢?问题给到你,🤪

java 复制代码
开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务

开发静态代理类

ShopServiceStaticProxy

java 复制代码
/*静态代理类和业务类实现同一个接口*/
public class ShopServiceStaticProxy implements ShopService {

    /*静态代理类依赖业务类*/
    private ShopService shopService;

    public void setShopService(ShopService shopService) {
        this.shopService = shopService;
    }

    @Override
    public void add() {
        try {
            System.out.println("开启事务");
            shopService.add();
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void remove() {
        try {
            System.out.println("开启事务");
            shopService.remove();
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }
}

ShopServiceImpl优化后的专注于业务

java 复制代码
public class ShopServiceImpl implements ShopService {
    @Override
    public void add() {
        System.out.println("处理添加商品业务逻辑,调用DAO~~~");
    }

    @Override
    public void remove() {
        System.out.println("处理添下架商品业务逻辑,调用DAO~~~");
    }
}

能否可行,测试,必须行

java 复制代码
public class ShopTest {
    public static void main(String[] args) {
        ShopServiceImpl shopService = new ShopServiceImpl();
        ShopServiceStaticProxy shopServiceStaticProxy = new ShopServiceStaticProxy();
        shopServiceStaticProxy.setShopService(shopService);
        shopServiceStaticProxy.add();
        shopServiceStaticProxy.remove();
    }
}
java 复制代码
开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务

perfect,现在看起来优雅很多了

往往在开发我们书写的不仅仅是一个业务层,两个业务层,而我们的业务层会有很多,如果为每一个业务层开发一个静态代理类,不仅没有减轻工作量,甚至让我们的工作量多了一倍不止怎么解决以上这个问题呢?
解决方案:

为业务层在运行过程中动态创建代理类,通过动态代理类去解决我们现有业务层中业务代码冗余的问题

动态代理

有了静态代理的基础之后,来看看更好玩的动态代理,它是spring框架AOP的实现原理,以及很多框架的核心思想及落地实现

GO

通过jdk提供的 Proxy 类,动态为现有的业务生成代理类

参数一:当前线程类加载器 classLoader

参数二:生成代理类的接口类型

参数三:通过代理类对象调用方法时会优先进入参数三中的invoke方Proxy.newProxyInstance(loader, interfaces, h);//返回值就是动态代理对象

AOP的原理就是对动态代理的封装

还有 MyBatis 框架中的 getMapper(xxx.class),就是使用了动态代理对象

java 复制代码
public class TestDynamicProxy {
    public static void main(String[] args) {
        //参数1: classLoader 类加载器
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        //参数2: Class[] 动态代理对象的接口类型的数组
        Class[] classes = {ShopService.class};
        //参数3: InvocationHandler接口类型 invoke 方法 写附加操作

        ShopService userServiceDyProxy = (ShopService) Proxy.newProxyInstance(classLoader, classes, new InvocationHandler() {
            @Override
            //通过动态代理对象调用自己里面代理方法时会优先指定InvocationHandler类中invoke
            // invoke方法参数
            //1. 当前创建好的代理对象
            //2. 当前代理对象执行的方法对象
            //3. 当前代理对象执行方法的参数
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("当前执行的方法:" + method.getName());
                try {
                    System.out.println("开启事务");
                    //调用目标类中的业务方法
                    Object invoke = method.invoke(new ShopServiceImpl(), args);
                    System.out.println("提交事务");
                    return invoke;
                }catch (Exception e){
                    System.out.println("回滚事务");
                    e.printStackTrace();
                }
                return null;
            }
        });
        System.out.println(userServiceDyProxy.getClass());
        userServiceDyProxy.remove();
        userServiceDyProxy.add();
    }
}
java 复制代码
class com.sun.proxy.$Proxy0
当前执行的方法:remove
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务
当前执行的方法:add
开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务

完美完成,Perfect realization,尽管动态代理的代码很难理解,但是这是必经之路,加油,战胜它,奥里给,这就是全部内容了,拜拜了 🚀

相关推荐
重生之后端学习9 分钟前
day08-Elasticsearch
后端·elasticsearch·spring cloud·中间件·全文检索·jenkins
东阳马生架构24 分钟前
订单初版—5.售后退货链路中的技术问题说明文档
java
小小寂寞的城29 分钟前
JAVA策略模式demo【设计模式系列】
java·设计模式·策略模式
志辉AI编程44 分钟前
别人还在入门,你已经精通!Claude Code进阶必备14招
后端·ai编程
JAVA学习通1 小时前
图书管理系统(完结版)
java·开发语言
代码老y1 小时前
Spring Boot项目中大文件上传的高级实践与性能优化
spring boot·后端·性能优化
abigalexy1 小时前
深入Java锁机制
java
paishishaba1 小时前
处理Web请求路径参数
java·开发语言·后端
神仙别闹1 小时前
基于Java+MySQL实现(Web)可扩展的程序在线评测系统
java·前端·mysql
程序无bug1 小时前
Java中的8中基本数据类型转换
java·后端