- 代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
- 代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。
从JDK 1.3开始,Java提供了动态代理技术,允许开发者在运行时创建接口的代理实例,在java中有多种动态代理技术,比如JDK、CGLib、Javassist、ASM,其中最常用的动态代理技术有两种:一种是JDK动态代理,这是JDK自带的功能;一种是CGLib,这是第三方提供的一个技术。目前,Spring常用JDK和CGLib,而mybatis还使用了javassist,无论哪种代理技术,他们的理念都是相似的。
在JDK动态代理中,要实现代理逻辑类必须去实现 java.lang.reflect.InvocationHandler接口,它里面定义了一个invoke方法,并提供接口数组用于下挂代理对象,如下代码所示:
public class JDKProxyFactory implements InvocationHandler{
//目标对象
private Object target;
/**
* 建立代理对象和目标对象的代理关系,并返回代理对象
* @param target 目标对象
* @return 代理对象
*/
public Object createTargetProxyInstance(Object target) {
this.target = target;
/*
* 第1个参数为类加载器:采用了target本身的类加载器
* 第2个参数为把生成的动态代理对象下挂在哪些接口下,这个写法表示放在target实现的接口下
* 第3个表示实现方法逻辑的代理类,this表示当前对象,它必须实现InvocationHandler的invoke方法
*/
return Proxy.newProxyInstance(this.target.getClass().getClassLoader(),
this.target.getClass().getInterfaces(), this);
}
/**
* 代理方法逻辑
* @param proxy 代理对象
* @param method 当前调度方法
* @param args 当前方法参数
* @return 代理结果返回
* @throws Throwable 异常
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object ret = null;
System.out.println("进入代理逻辑方法,在调度真实对象之前的服务,比如记录日志");
ret = method.invoke(target, args);
System.out.println("调度真实对象之后的服务");
return ret;
}
}
使用Java的动态代理有一个局限性就是代理的类必须要实现接口,虽然面向接口编程是每个优秀的Java程序都知道的规则,但现实往往不尽如人意,对于没有实现接口的类如何为其生成代理呢?继承!继承是最经典的扩展已有代码能力的手段,虽然继承常常被初学者滥用,但继承也常常被进阶的程序员忽视。CGLib采用非常底层的字节码生成技术,通过为一个类创建子类来生成代理,它弥补了Java动态代理的不足,因此Spring中动态代理和CGLib都是创建代理的重要手段,对于实现了接口的类就用动态代理为其生成代理类,而没有实现接口的类就用CGLib通过继承的方式为其创建代理。
public class CGLibProxyFactory implements MethodInterceptor {
//目标对象
private Object target;
/**
* 生成CGLib代理对象
* @param target 目标对象
* @return 目标对象的CGLib代理对象
*/
public Object createProxyInstance(Object target) {
this.target = target;
// 增强类对象
var enhancer = new Enhancer();
//设置增强类型
enhancer.setSuperclass(target.getClass());
//定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor接口
enhancer.setCallback(this);
//生成并返回代理对象
return enhancer.create();
}
/**
* 代理逻辑方法
* @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 {
Object ret = null;
if (权限判断) {//环绕通知(可以决定方法是否被调用(权限拦截))
try {
System.out.println("开启事务"); // 前置通知
//反射调用真实方法
ret = method.invoke(target, args);
//ret = methodProxy.invokeSuper(proxy, args);
System.out.println("提交事务");// 后置通知
} catch (Exception e) {
System.out.println("回滚事务");// 例外通知
} finally {
System.out.println("释放资源,最终操作"); // 最终通知
}
}
return ret;
}
}
Spring AOP中相关概念
连接点:程序执行的某个特定位置(如:某个方法调用前、调用后,方法抛出异常后)。一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就是连接点。Spring仅支持方法的连接点。
切点:如果连接点相当于数据中的记录,那么切点相当于查询条件,一个切点可以匹配多个连接点。Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。
增强:增强是织入到目标类连接点上的一段程序代码。Spring提供的增强接口都是带方位名的,如:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等。很多资料上将增强译为“通知”,这明显是个词不达意的翻译,让很多程序员困惑了许久。
引介:引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过引介功能,可以动态的未该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
织入:织入是将增强添加到目标类具体连接点上的过程,AOP有三种织入方式:
- 编译期织入:需要特殊的Java编译期(例如AspectJ)
- 类装载期织入:要求使用特殊的类加载器
- 动态代理织入:在运行时为目标类生成代理实现增强
Spring采用了动态代理织入,而AspectJ采用了编译期织入和类装载期织入的方式。
切面:切面是由切点和增强(引介)组成的,它包括了对横切关注功能的定义,也包括了对连接点的定义。
横切性关注点
通过对系统需求和实现的识别,我们可以将模块中的这些关注点分为:核心关注点和横切关注点。对于核心关注点而言,通常来说,实现这些关注点的模块是相互独立的,他们分别完成了系统需要的商业逻辑,这些逻辑与具体的业务需求有关。而对于日志、安全、持久化等关注点而言,他们却是商业逻辑模块所共同需要的,这些逻辑分布于核心关注点的各处。在AOP中,诸如这些模块,都称为横切关注点。应用AOP的横切技术,关键就是要实现对关注点的识别。
相关推荐
电子商务之价格优化算法:梯度下降:机器学习在价格优化中的角色.docx
ToadforOracle与Oracle数据库版本兼容性教程.docx
360浏览器银河麒麟版 for X86 适配兆芯 / 海光 / intel / AMD CPU
使用React.js构建,提供多种主题可供选择,并且易于定制。该项目旨在帮助开发者和自由职业者创建自己的个性化投资组合。 主要功能点 多种主题可供选择,包括绿色、黑白、蓝色、红色、橙色、紫色、粉色和黄色 易于定制,可以在src/data文件夹中更新个人信息 包含主页、关于、简历、教育、技能、经验、项目、成就、服务、推荐信、博客和联系等多个部分 支持通过Google表单收集联系信息 提供SEO优化建议 支持多种部署方式,如Netlify、Firebase、Heroku和GitHub Pages 技术栈主要 React.js Material-UI Axios React-fast-marquee React-helmet React-icons React-reveal React-router-dom React-router-hash-link React-slick Slick-carousel Validator
中小型企业财务管理系统 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B
python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。
电子商务之价格优化算法:线性回归:价格优化策略实施.docx
内容概要:报告详细介绍了企业数字化转型的驱动因素、数字化转型方案分类及其应用场景,重点关注了云计算、超连接、数字孪生、人工智能、分布式账本、增材制造、人机接口、数据共享、工业物联网等关键技术。这些技术不仅支持了企业的运营效率提升和业务模式创新,也为实现更快、更开放、更高效的数字化转型提供了支撑。报告最后提出了企业实施数字化转型的六个步骤。 适合人群:企业高级管理人员、技术人员、咨询顾问,以及对工业数字化转型感兴趣的读者。 使用场景及目标:帮助企业制定和实施数字化转型策略,优化运营模式,提升业务效率,增强市场竞争力。同时,也可作为政府部门、研究机构和行业协会的参考文献。 其他说明:报告中提到的关键技术及其应用场景对企业数字化转型具有重要的指导意义,特别是对于那些希望通过数字化转型实现业务创新和升级的企业。
基于java的线上选课系统的设计与实现答辩PPT.pptx
安装前的准备 1、安装Python:确保你的计算机上已经安装了Python。你可以在命令行中输入python --version或python3 --version来检查是否已安装以及安装的版本。 个人建议:在anaconda中自建不同python版本的环境,方法如下(其他版本照葫芦画瓢): 比如创建python3.8环境,anaconda命令终端输入:conda create -n py38 python==3.8 2、安装pip:pip是Python的包管理工具,用于安装和管理Python包。你可以通过输入pip --version或pip3 --version来检查pip是否已安装。 安装WHL安装包 1、打开命令行(或打开anaconda命令行终端): 在Windows上,你可以搜索“cmd”或“命令提示符”并打开它。 在macOS或Linux上,你可以打开“终端”。 2、cd到whl文件所在目录安装: 使用cd命令导航到你下载的whl文件所在的文件夹。 终端输入:pip install xxx.whl安装即可(xxx.whl指的是csdn下载解压出来的whl) 3、等待安装完成: 命令行会显示安装进度,并在安装完成后返回提示符。 以上是简单安装介绍,小白也能会,简单好用,从此再也不怕下载安装超时问题。 使用过程遇到问题可以私信,我可以帮你解决! 收起
电子商务之价格优化算法:贝叶斯定价:贝叶斯网络在电子商务定价中的应用.docx
IMG_20241105_235746.jpg
基于java的毕业设计选题系统答辩PPT.pptx
专升本考试资料全套.7z
Trustwave DbProtect:数据库活动监控策略制定.docx
基于VB的程序实例,可供参考学习使用
本压缩包资源说明,你现在往下拉可以看到压缩包内容目录 我是批量上传的基于SpringBoot+Vue的项目,所以描述都一样;有源码有数据库脚本,系统都是测试过可运行的,看文件名即可区分项目~ |Java|SpringBoot|Vue|前后端分离| 开发语言:Java 框架:SpringBoot,Vue JDK版本:JDK1.8 数据库:MySQL 5.7+(推荐5.7,8.0也可以) 数据库工具:Navicat 开发软件: idea/eclipse(推荐idea) Maven包:Maven3.3.9+ 系统环境:Windows/Mac
该源码项目是一款基于Thinkphp5框架的Java插件设计,包含114个文件,其中Java源文件60个,PNG图片32个,XML配置文件7个,GIF图片7个,Git忽略文件1个,LICENSE文件1个,Markdown文件1个,Xmind文件1个,Idea项目文件1个,以及JAR文件1个。
数据库开发和管理最佳实践.pdf
本压缩包资源说明,你现在往下拉可以看到压缩包内容目录 我是批量上传的基于SpringBoot+Vue的项目,所以描述都一样;有源码有数据库脚本,系统都是测试过可运行的,看文件名即可区分项目~ |Java|SpringBoot|Vue|前后端分离| 开发语言:Java 框架:SpringBoot,Vue JDK版本:JDK1.8 数据库:MySQL 5.7+(推荐5.7,8.0也可以) 数据库工具:Navicat 开发软件: idea/eclipse(推荐idea) Maven包:Maven3.3.9+ 系统环境:Windows/Mac