AOP的动态代理

3 篇文章 0 订阅
订阅专栏

AOP的动态代理

该文章代码来源:
JDK动态代理-B站学习视频
CGLI动态代理-B站学习视频

AOP

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。

AOP动态代理的方式主要分为两种:

  • CGLIB
  • JDK动态代理

动态代理

简介:
动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。可以理解为运行期间,对象中方法的动态拦截,在拦截方法的前后执行功能操作

JDK动态代理

JDK的动态代理是通过java.lang.reflect.Proxy 类来实现的,我们可以调用Proxy类的newProxyInstance()方法来创建代理对象。对于使用业务接口的类,Spring会默认使用JDK的动态代理来实现AOP

Proxy类

JDK1.8的官方文档的介绍是:Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。

第一版代码

创建一个接口(接口是JDK代理必不可少的一环
public interface UserDao {
    public int addUser();
    public void editUser();
}
创建一个实现类
public class UserDaoImpl implements UserDao{
    @Override
    public int addUser() {
        System.out.println("添加用户");
        return 0;
    }

    @Override
    public void editUser() {
        System.out.println("修改用户");
    }
}

我们先看看没有加动态代理之前的打印

public class JdkTest {
    public static void main(String[] args) {
        UserDaoImpl userDao = new UserDaoImpl();
        userDao.addUser();
    }
}

在这里插入图片描述
就是普通的功能打印

第二版代码

创建一个增强功能的类
public class MyAspect {
    public void check_permission(){
        System.out.println("权限检查");
    }
    public void log(){
        System.out.println("日志记录");
    }
}
创建动态代理类

动态代理类 (以下简称为代理类 )是一个实现在类创建时在运行时指定的接口列表的类,具有如下所述的行为:

  • 代理接口是由代理类实现的接口
  • 代理实例是代理类的一个实例
  • 每个代理实例都有一个关联的调用处理程序对象,它实现了接口InvocationHandler
  • 通过其代理接口之一的代理实例上的方法调用将被分派到实例调用处理程序的invoke方法,传递代理实例, java.lang.reflect.Method被调用方法的java.lang.reflect.Method对象以及包含参数的类型Object Object的数组
public class MyInvocationHandler implements InvocationHandler {

    //代理的动态对象
    private Object obj;

    //给其一个有参的构造器
    public MyInvocationHandler(Object obj){
        this.obj=obj;
    }

    /**
     * @param proxy 代理类的实例对象
     * @param method 用户请求的方法
     * @param args   这是该方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MyAspect myAspect = new MyAspect();
        myAspect.check_permission();//前置增强
        Object result = method.invoke(obj, args);
        myAspect.log();//后置增强
        return result;
    }
}

使用MyAspect类的方法对被代理类进行了前后置的增强

Method类

java.lang.reflect.Method
reflect(反射),该类是在反射包下的
其功能是:提供类或者接口的信息就可以访问调用对应的方法

invoke

作用:调用所提供的方法以及调用方法的参数来完成动态调用
重新编写测试类
public class JdkTest {
    public static void main(String[] args) {
//         代理的目标对象
        UserDaoImpl userDao = new UserDaoImpl();
//        调用织入代理类的Handler
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(userDao);

//        调用JDK动态代理的 proxy代理方法 动态生成原始类实例实现接口的动态代理类实例 返回动态代理类的实例
        /**
         * newProxyInstance(ClassLoader loader,Class<?>[] interfaces,Invocation,Handler h) 
         * classloader:用来加载动态生成的字节码的
         * interface:被代理对象所有的接口(接口数组)
         * handler:教我们如何写实现
         */
        UserDao UserDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
                UserDaoImpl.class.getInterfaces(),
                myInvocationHandler);
//        调用方法
        UserDaoProxy.addUser();

        //UserDaoProxy是Proxy的子类
        System.out.println(UserDaoProxy instanceof Proxy);
    }
}

newProxyInstance()

返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
在这里插入图片描述

参数:
loader - 类加载器来定义代理类 
interfaces - 代理类实现的接口列表 
h - 调度方法调用的调用处理函数 

添加代理后的打印
在这里插入图片描述
完成了前置和后置的增强,打印的true表示虽然调用的是被代理类的方法,但是真正被调用的是代理类,是代理类代替了被代理类完成了操作

在这里插入图片描述

JDK动态代理,主要实现的是对Jdk只能实现对接口的动态代理,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以用CGLib动态代理

CGLib动态代理

因为JDK动态代理的局限性,因为JDK动态代理的对象必须实现一个或多个接口,因此CGLib代理产生了,CGlib是为了解决没有实现接口的类

CGLIB

CGLIB(Code Generation Library)是一个开源项目。
是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Hibernate支持它来实现PO(Persistent Object 持久化对象)字节码的动态生成。

开始编码

为了与接口做区分这次直接创建一个类

导包

使用CGLIB是需要导包的

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>
创建实体类
/**
 *目标类  被代理类
 */
public class UserDao {
    public void saveUser(){
        System.out.println("新增用户");
    }
}
功能增强类
public class MyAspect {
    public void check_permission(){
        System.out.println("权限检查");
    }
    public void log(){
        System.out.println("日志记录");
    }
}
代理类
/**
 * 代理类
 */
public class CglibProxy implements MethodInterceptor {
//    被代理对象 目标对象
    private Object target;

    public Object createProxy(Object target){
        this.target=target;
        //最核心的代理   通过cglib增强代码

//        用来生成代理的 工厂类
        Enhancer enhancer = new Enhancer();
//        生成目标类对象的子类 进行增强
//        设置被代理的类的类型type
        enhancer.setSuperclass(target.getClass());
//        如何增强
//        需要传入一个Callback接口的实现,MethodInterceptor就是Callback接口的子接口
        enhancer.setCallback(this);
//        生成代理类的字节码文件
        Object proxy = enhancer.create();
        return proxy;
    }

    /**
     * 描述如何增强父类
     * @param proxy  代理对象 引用
     * @param method  被代理对象方法的描述引用
     * @param args    方法的参数
     * @param methodProxy 代理对象的 对目标对象的方法描述
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//        增强代码
        MyAspect aspect = new MyAspect();
        aspect.check_permission(); //前置增强


//        调用原始方法 这两个方法功能一样
        //1.代理类对象进行调用
        Object invokeSuper = methodProxy.invokeSuper(proxy, args);
        //2.原对象
//        Object invoke = method.invoke(target, args);


        aspect.log();//后置增强
        return invokeSuper;
    }
}

对指定的类生成一个子类,覆盖其中的方法,对其进行增强

测试类
public class CgilbTest {
    public static void main(String[] args) {
//        首先需要原对象
        UserDao target = new UserDao();
//        创建 一个 proxy工厂实例
        CglibProxy cglibProxy = new CglibProxy();
        UserDao proxy = (UserDao) cglibProxy.createProxy(target);
        proxy.saveUser();
    }
}

代码打印结果
在这里插入图片描述

两种代理的区别

JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进行,通过修改其字节码生成子类来处理

  • 需要代理的目标如果实现了接口,默认情况一定是采用JDK的动态代理来实现AOP
  • 如果需要代理的目标没有实现接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间转换
动态代理AOP
weixin_70676044的博客
03-28 1849
AOP(Aspect Oriented Programming)即面向切面编程,是一种编程思想和技术。在传统的编程中,我们会将系统的业务逻辑分散在各个模块或类中,导致代码重复、难以维护。而 AOP 则通过将系统的横切关注点(如日志、事务、安全等)抽取出来,形成一组切面,然后将这些切面应用到系统中的多个模块或类中,从而实现了代码的复用和解耦。
Spring AOP中的动态代理
weixin_34163553的博客
01-24 102
0 前言 1 动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2 Spring AOP中的动态代理机制 2.1JdkDynamicAopProxy 2.2CglibAopProxy 3 总结 0 前言 前一个季度旅游TD...
Spring高手之路21——深入剖析Spring AOP代理对象的创建
最新发布
卓越无关环境,保持空杯心态——靡不有初,鲜克有终
07-27 1万+
本文详细介绍了Spring AOP代理对象的创建过程,分为三个核心步骤:判断是否增强、匹配增强器和创建代理对象。通过源码分析和时序图展示,深入剖析了Spring AOP的工作原理,帮助读者全面理解Spring AOP代理对象的生成机制及其实现细节。
AOP动态代理
qq_50896786的博客
07-06 4625
目录1.IOC、AOP概念2.为何使用动态代理2.1 JDK原生动态代理 2.1.1 MathService接口类2.1.2 MathServiceImpl实现接口类2.1.3 ProxyFactory动态代理工厂2.1.4 测试类2.2 cglib动态代理 2.2.1 MathServiceImpl类2.2.2 ProxyFactory动态代理工厂2.2.3 测试类3.AOP动态代理3.1 添加对应依赖3.2 配置spring.xml文件3.3 MathService接口类 3.4 MathService
动态代理(2)----动态代理AOP
weixin_30788731的博客
02-28 87
根据前面介绍的Proxy和InvocationHandler,实在很难看出这种动态代理的优势,下面介绍一种更实用的动态代理机制.只要我们开发一个实际使用的软件系统,总会出现相同代码重复出现的情形,在这种情形下,最常见的做法是:选中那些代码一路“复制”、“粘贴”立即实现系统的功能,如果仅仅从软件功能上来看,他们确实已经完成了软件的开发。对于采用上述方法实现的系统,在软件开发期间可能会觉得无...
动态代理
weixin_47216239的博客
08-19 231
1、Java.lang.reflect.Proxy类可以直接生成一个代理对象 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)生成一个代理对象 参数1:ClassLoader loader 代理对象的类加载器 一般使用被代理对象的类加载器 (表名你要用那个类加载器去加载生成的代理类。) 参数2:Class<?>[] interfaces 代理对象的要实现的接口
Spring AOP 动态代理(二)
01-20
Spring AOP 的本质其实就是实现了动态代理,这个和Aspectj不一样,AspectJ 是直接修改你的字节码 完成的 代理模式其实很简单 主要包括 接口+真实的实现类+代理类 在真实类的实例化的时候 使用代理类,所以需要 ...
Spring框架+SpringAOP动态代理
03-22
### Spring框架+SpringAOP动态代理 #### 一、Spring AOP 动态代理概述 在探讨Spring AOP(Aspect-Oriented Programming,面向切面编程)中的动态代理之前,我们首先简要回顾一下AOP的基本概念。面向切面编程是一种...
反射实现 AOP 动态代理模式(Spring AOP 的实现原理)
08-26
动态代理是实现AOP的一种常用技术,它允许在运行时创建代理对象,拦截对真实对象的调用,并在调用前后添加额外的行为。 在Java开发中,反射机制是实现动态代理的关键技术之一。反射提供了在运行时访问和操作类的...
AOP动态代理(反射机制)
06-30
动态代理是实现AOP的一种常见方式,特别是在Java中。 在Java中,动态代理主要涉及到两个类:java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler。Proxy类用于创建一个实现了特定接口的代理对象,而...
反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -
05-30
Spring框架是Java中实现AOP的一个流行工具,它通过动态代理机制实现了这一功能。本文将深入探讨Spring AOP的实现原理,以及如何使用反射来实现动态代理模式。 首先,我们需要了解AOP的基本概念。AOP的核心思想是切...
springAOP动态代理
09-06
springAOP动态代理),包括jdk动态代理和CGLib动态代理
AOP 动态代理
学而时习之,不亦说乎。
11-30 230
  AOP 动态代理 指在程序运行期间动态的将某段代码切入到指定位置进行的编程方式; 1、导入aop模块,spring aopspring-aspects 2、定义一个业务逻辑,在业务逻辑运行的时候将日志进行打印 3、定义一个日志切面类(logAsects):切面类里面的方法将动态感知业务逻辑方法运行到哪   通知方法:前置通知 后置通知 返回通知 异常通知 环绕通知...
AOP动态代理
当一堆用不熄灭的柴火
03-11 828
前言 都说面向切面编程是代理模式的延续,今天就来研究一下这两者之间的关系 代理模式:一个类代表另一个类的功能。 静态代理的DEMO话不多说,先看个关于静态代理的例子:有一个shape的接口,rectangle和simpleproxy,都实现shape的接口,这个接口中有draw和erase两个方法,simpleproxy保存一个rectangle的引用,代替实体去实现“画”和“清除”的方法 接
AOP实现动态代理
qq_28175477的博客
08-12 428
Proxy与AOP 什么是代理?什么是AOP代理 代理(Proxy):设计模式的一种, 某些不可以、不方便、不想直接被外界使用的目标类, 使用代理类的模式统一接收外界的请求后, 再去访问目标类。可分为静态代理、JDK动态代理、CGLib动态代理AOP(Aspect Oriented Programming):面向切面编程, 通过预编译方式和运行期动态代理实现程序功能的统一维护。AOP是OOP的补充, AOP通过动态代理的方式将OOP编程中每个类必须实现又重复冗余代码抽离处理统一处理。 AOP提供功能:
SpringAOP动态代理
a55566999的博客
06-23 1784
动态代理介绍
spring aop 动态代理
08-29
Spring AOP 是构建在动态代理基础上的一种实现方式。它使用了 JDK Proxy 和 CGLIB 两种方式实现动态代理。默认情况下,如果一个类实现了接口,Spring AOP 会基于 JDK 生成代理类;如果一个类没有实现接口,Spring AOP 会基于 CGLIB 生成代理类。 这样的动态代理实现使得 Spring AOP 能够在方法级别进行拦截和增强操作。与 AspectJ 直接修改字节码不同,Spring AOP 通过动态代理对目标对象进行包装,实现了切面的织入。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Spring AOP 动态代理](https://blog.csdn.net/qq15035899256/article/details/126560766)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Spring AOP 动态代理(二)](https://download.csdn.net/download/weixin_38648800/14852146)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
写文章

热门文章

  • JavaSE面试题解(37题) 6718
  • EMQX安装、处理安装遇到的问题 6462
  • hutool实现导入、导出功能 3524
  • AOP的动态代理 2058
  • Redis入门(1)- redis的数据类型 1624

分类专栏

  • shardingsphere 1篇
  • redis 6篇
  • 中间件 1篇
  • 面试题 3篇
  • MySQL 2篇
  • spring cloud 1篇
  • spring 3篇
  • EMQX 1篇
  • java 1篇
  • Vue 2篇
  • 工具 1篇
  • MongoDB 4篇

最新评论

  • EMQX安装、处理安装遇到的问题

    wudidedafeiji: 你好,我查看端口,没用18083端口怎么办

  • hutool实现导入、导出功能

    是程小姐呀: https://blog.csdn.net/qq_24845091/article/details/108516290是不是版本问题,遇到报错就打开百度复制粘贴

  • hutool实现导入、导出功能

    森林老虎: NoSuchMethodError: org.apache.poi.ss.usermodel.WorkbookFactory.create(Z)Lorg/apache/poi/ss/usermodel/Workbook;报这个错是什么问题

  • JavaSE面试题解(37题)

    Saneinup: 第8点:实例变量可以实现让多个对象共享内存 这个每创建一个对象会新产生新的实例吧,博主是不是少写了个不字

  • hutool实现导入、导出功能

    土豆你个番茄: 我想问下生成的表格,能不能使用公式做一些总结统计的功能?

大家在看

  • Maven配置过程,Maven在Myeclipse中配置,如何下载架包添加(超详细!!!)
  • 花8000元去培训机构学习网络安全值得吗,学成后就业前景如何? 666
  • C++ Lambda 812
  • 什么是存储过程(Stored Procedure)?它有什么用途?
  • 入门网络安全工程师要学习哪些内容 535

最新文章

  • shardingsphere-jdbc(1):实现数据库主从同步、读写分离
  • Redis 的 缓存雪崩、缓存击穿、缓存穿透
  • Redis入门(2)-- redis的持久化方式
2024年1篇
2023年7篇
2022年17篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司电商运营与网站优化那个好洛阳网站优化渠道电话开封seo网站优化哪家便宜网站排名优化建设宁乡网站优化推广软件黄山安徽网站优化北辰区网站优化推广长春放心的电商网站优化主关键词优化网站网站优化的流程福州市网站优化模式网站优化按词按天收费福田电影网站优化方式有哪些广州优化网站关键词优化网站的软件优质商家怎么优化一个网站网站优化的布局网站优化关键词多久能到首页延吉网站优化推广许昌网站关键词优化排名软件vue网站的优化方案益阳网站优化公司地址2021网站优化周期网站搜索引擎优化诊断南昌网站排名优化报高港区网站优化要多少钱茂名排名网站优化价格邢台哪家网站优化好辽宁销售行业网站优化技巧厚街网站优化方法大全歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化