最新要闻
- 快看:本周最火AutoGPT!GitHub3.6万+标星:解决复杂任务全程无需人类插手
- 环球微速讯:性能升级 13代酷睿来了? 华为MateBook笔记本新品即将发布
- 曾力推每天睡4小时 张朝阳建议年轻人别睡懒觉不要熬夜
- 每日动态!李书福抢跑马斯克发小钢炮!冰箱彩电大沙发全标配:理想直呼内行
- 【环球热闻】售价高达15000元!宾得专为黑白摄影推出K-3 Mark III Monochrome
- 金色的草地课文朗读音频_金色的草地课文
- Intel突然杀死服务器整机业务!新CEO连砍十余刀挽救亏损
- 马保国直播带货现演“闪电五连鞭”:销量惨淡 网友只看不买
- 克里克森_克里克拉克
- 每日速递:日本部分地区出现大量黄沙:能见度不足10公里
- 环球热点!高颜值!关晓彤晒华为nova 11:本月发
- 每日资讯:开启影像光学新时代!小米13 Ultra搭载全焦段5000万像素徕卡四摄
- 真反向虚标!实测比亚迪秦PLUS EV冠军版:标610开出646.5
- 5.98万起真不贵!五菱缤果上市两周狂卖10000台:再成爆款
- 【大兴调查研究】临夏税务:“把脉问诊”助企纾困
- 今日热闻!新款特斯拉Model 3实车首曝:大灯更精神、颜值再提升
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
天天最资讯丨动态代理与Spring AOP
JDK 动态代理
被代理类
JDK动态代理基于接口创建代理,所以业务类必须至少实现一个接口。
(相关资料图)
public interface SmsService { String send(String message); void print();}public class SmsServiceImpl implements SmsService{ @Override public String send(String message) { // TODO Auto-generated method stub System.out.println("send message:" + message); return message; } @Override public void print() { // TODO Auto-generated method stub System.out.println("execute print method!"); }}
代理类
JDK动态代理类必须实现
InvocationHandler
接口,重写自己的invoke()
方法
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class JDKProxy implements InvocationHandler{ private final Object target; // 被代理对象 public JDKProxy(Object target) { this.target = target; } /** * 当调用被代理对象的方法时, 会自动跳转到代理对象的invoke()方法 * 可以通过 method.getName() 指定被代理的方法 * 默认会代理所有方法 * * @param proxy 动态生成的代理对象 * @param method 实际调用的方法 * @param args 实际调用方法的入参 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result = null; if (method.getName().equals("send")) { System.out.println("Before: " + method.getName()); result = method.invoke(target, args); System.out.println("After: " + method.getName()); } else { result = method.invoke(target, args); } return result; } }
Proxy动态创建代理类
利用反射机制创建实现被代理对象接口的代理类,在调用具体方法时,调用
InvocationHandler
处理。
import java.lang.reflect.Proxy;public class JDKProxyFactory { public static Object getJDKProxy(Object target) { // 动态创建代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new JDKProxy(target)); }}
测试JDK动态代理
public class JDKProxyTest { public static void main(String[] args) { SmsService smsService = (SmsService) JDKProxyFactory.getJDKProxy(new SmsServiceImpl()); smsService.send("message"); smsService.print(); }}
Before: sendsend message:messageAfter: sendexecute print method!
sned()
方法被代理增强print()
方法未被代理
Cglib 动态代理
被代理类
Cglib动态代理基于子类创建代理,所以对于未实现接口的类可以考虑使用Cglib实现代理。但是如果被代理类被
final
关键字修饰则代理无法创建。
public class SmsServiceClass { public String send(String message) { // TODO Auto-generated method stub System.out.println("send message:" + message); return message; } public void print() { // TODO Auto-generated method stub System.out.println("execute print method!"); }}
代理类
Cglib动态代理类则必须实现
MethodInterceptor
接口,并重写自己的intercept()
方法。
import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CglibProxy implements MethodInterceptor { /** * @param obj 动态生成的代理对象 * @param method 实际调用的方法 * @param args 实际调用方法的入参 * @param methodProxy Method代理方法 * @return * @throws Throwable */ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object result = null; // 增强 print 方法 if (method.getName().equals("print")) { System.out.println("Before: " + method.getName()); // 执行被代理类的逻辑 result = methodProxy.invokeSuper(obj, args); System.out.println("After: " + method.getName()); } else { result = methodProxy.invokeSuper(obj, args); } return result; }}
Enhancer动态创建代理类
利用
org.objectweb.asm
软件包,加载代理对象的class
文件,通过修改字节码生成子类实现代理。
import net.sf.cglib.proxy.Enhancer;public class CglibProxyFactory { public static Object getCglibProxy(Object target) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(new CglibProxy()); return enhancer.create(); }}
setSupperClass()方法源码
public void setSuperclass(Class superclass) { if (superclass != null && superclass.isInterface()) { this.setInterfaces(new Class[]{superclass}); } else if (superclass != null && superclass.equals(Object.class)) { this.superclass = null; } else { this.superclass = superclass; }}
所以 Cglib 即可以代理未实现接口的类(supperClass),也可以代理实现了接口的类(setInterfaces)。
测试Cglib动态代理
public class CglibTest { public static void main(String[] args) { // 获取代理类 SmsServiceClass smsServiceClass = (SmsServiceClass) CglibProxyFactory.getCglibProxy(new SmsServiceClass()); smsServiceClass.send("message"); smsServiceClass.print(); }}
send message:messageBefore: printexecute print method!After: print
send()
方法未被代理print()
被代理增强
小结
代理类型 | 实现机制 | 创建方式 | 应用场景 |
---|---|---|---|
JDK动态代理 | 代理类和目标类都实现了同样的接口,代理类委托 InvocationHandler 去调用目标类的原始方法 | 反射 | 目标类实现了接口 |
Cglib动态代理 | 代理类继承并重写了目标类的方法,通过回调函数 MethodInterceptor 调用父类方法执行原始方法 | ASM | 非final 类、非final 方法 |
Spring AOP
AOP(Aspect Orient Programming): 面向切面编程,即可以在不修改原有代码的情况下给系统添加额外的功能。AOP可以拦截指定的业务方法,并对其进行增强,而且无需入侵到具体业务代码中,使得业务代码与增强处理逻辑分离。
AOP主要应用体现在:
- 事务处理
- 日志管理
- 权限控制
- 异常处理
Spring AOP 简单概念理解
Advice
: 通知,描述切面何时执行以及如何增强处理join point
: 连接点,描述可以被动态代理拦截的目标类方法PointCut
: 切点,真正被拦截的连接点Aspect
: 切面,即通知和切点的结合Weaving
: 织入,描述增强逻辑应用到目标类上,生成代理对象的过程
AspectJ基于注解实现切面
创建接口及其实现类
public interface SmsService { String send(String message);}@Componentpublic class SmsServiceImpl implements SmsService{ @Override public String send(String message) { // TODO Auto-generated method stub System.out.println("send message:" + message); return message; }}
定义切面类
@Aspect@Componentpublic class SmsServiceAspectJ { // 声明切点表达式 @Pointcut("execution(String com.lzy.aopdemo.test.SmsService.send(String))") public void point(){} @Before("point()") public void beforeMethod() { System.out.println("Execute before!"); } @After("point()") public void afterMethod() { System.out.println("Execute after!"); } @AfterReturning("point()") public void afterReturningMethod() { System.out.println("Execute after returning!"); } @Around("point()") public void aroundMethod(ProceedingJoinPoint pjp) { try { System.out.println("Around before"); pjp.proceed(); System.out.println("Around after"); } catch (Throwable throwable) { throwable.printStackTrace(); } }}
切点表达式 execution(* com.lzy.aopdemo.test.SmsService.send(..))
- execution: 标识方法执行时触发
- *: 返回任意类型(不关心返回值类型)
- com.lzy.aopdemo.test.SmsService: 方法所属类或接口
- send: 特定方法
- ..: 使用任意参数(不关心入参)
Spring AOP通知类型
通知类型 | 描述 |
---|---|
@Before | 在目标方法调用之前执行 |
@After | 在目标方法调用之后执行 |
@AfterReturning | 在目标方法返回后调用 |
@AfterThrowing | 在目标方法抛出异常后调用 |
@Around | 将目标方法封装起来 |
注意@Around的执行顺序
@Around \(\rightarrow\) @Before \(\rightarrow\) @Around \(\rightarrow\) @After \(\rightarrow\) @AfterReturning
配置启用AOP
proxyTargetClass
- true: 使用Cglib动态代理
- false: 使用JDK动态代理
@Configuration@ComponentScan(basePackageClasses = {com.lzy.aopdemo.test.SmsService.class})@EnableAspectJAutoProxy(proxyTargetClass = false)public class AOPConfiguration {}
参考文章
- Spring AOP —— Spring中面向切面编程
- JDK动态代理和CGLIB动态代理
关键词:
天天最资讯丨动态代理与Spring AOP
在LINQPad中使用FreeSql查询数据库
minio分片上传
12函数进阶
环球快看点丨[Docker]Namespace与Cgroups
快看:本周最火AutoGPT!GitHub3.6万+标星:解决复杂任务全程无需人类插手
环球微速讯:性能升级 13代酷睿来了? 华为MateBook笔记本新品即将发布
曾力推每天睡4小时 张朝阳建议年轻人别睡懒觉不要熬夜
每日动态!李书福抢跑马斯克发小钢炮!冰箱彩电大沙发全标配:理想直呼内行
【环球热闻】售价高达15000元!宾得专为黑白摄影推出K-3 Mark III Monochrome
金色的草地课文朗读音频_金色的草地课文
焦点精选!论结构化、系统性的学习
【天天热闻】RocketMQ是是如何管理消费进度的?又是如何保证消息成功消费的?
【天天聚看点】C# 根据前台传入实体名称,动态查询数据
每日关注!电商流量分析怎么做?试试这款数据工具 DataLeap!
Intel突然杀死服务器整机业务!新CEO连砍十余刀挽救亏损
马保国直播带货现演“闪电五连鞭”:销量惨淡 网友只看不买
手把手教你如何免费Midjourney Adobe FireFly AI绘图—Window本地快速部署stable diffusion AI绘图及使用指南(小白
克里克森_克里克拉克
每日速递:日本部分地区出现大量黄沙:能见度不足10公里
环球热点!高颜值!关晓彤晒华为nova 11:本月发
每日资讯:开启影像光学新时代!小米13 Ultra搭载全焦段5000万像素徕卡四摄
真反向虚标!实测比亚迪秦PLUS EV冠军版:标610开出646.5
5.98万起真不贵!五菱缤果上市两周狂卖10000台:再成爆款
【3D建模工具】上海道宁与McNeel为您提供强大的专业3D造型软件
环球快资讯丨学系统集成项目管理工程师(中项)系列04c_项目管理一般知识(下)
【大兴调查研究】临夏税务:“把脉问诊”助企纾困
今日热闻!新款特斯拉Model 3实车首曝:大灯更精神、颜值再提升
焦点短讯!张艺谋:《满江红》票房让我很意外 20亿就是伟大胜利
观热点:美曾通报生物实验室感染病毒的小白鼠逃了:去年还发生实验猴逃窜
世界快看:5.58万起 五菱荣光新卡上市:2.0L动力、3.3米货厢
当前看点!微信推送8.0.35测试版:和Android 5.0说再见
华硕A52J笔记本最大存储空间是多少?华硕a52j笔记本参数
金立GN105手机怎么换屏幕?金立gn105手机参数配置
ATI HD4500是集成显卡吗?ATI HD4500参数配置
华硕y581c是什么系列?华硕y581c笔记本电脑配置
苹果iPhone7有几种颜色?苹果iphone7怎么截长图?
环球速递!《梦西游》4月14日合服维护公告
环球快消息!C#--TextBox的四种禁止编辑方法
热点评!4月22日,云数据库技术沙龙【杭州站】来了
用java做一个并发10W的网站,需要用到的技术有这些!
释放1英寸全部实力!小米13 Ultra支持可变光圈:重金打造
埃安Hyper GT摊牌了:比特斯拉贵 但你会选我
广东惠东发现“世界最神秘的鸟”:中国特产、比大熊猫还稀少
世界通讯!《名侦探柯南》优衣库联名T恤引争议 柯哀党PK新兰党
观焦点:小米平板6系列正式官宣:5000万摄像头 超强生产力工具
环球微速讯:093期杨光福彩3D预测奖号:定位直选参考
天天时讯:百度文心大模型API测试
世界通讯!浅析DNS Rebinding
Linux运维进阶之路
环球观点:美国通胀降温 油价随宽松预期下上行
天天日报丨男子要求抹零被拒与店员起争执 就为10元打女服务员:网友吐槽没必要
世界快资讯:打车去拉萨的超远订单显著增加 车费超1.3万 滴滴:希望大家理性下单
每日动态!曾是第一大股东 软银抛售阿里巴巴股份:快清空了
世界热资讯!剧版《哈利·波特》官宣 先导预告发布:JK罗琳监制 忠于原著的十年大剧
每日速递:和iPhone一样四边等宽!华为nova 11正面照泄露
天天报道:1、内网渗透基础知识
4月13日生意社二氯甲烷基准价为2607.50元/吨
【国际大宗商品早报】国际油价显著上涨超2% 基本金属全线走高
喊话北京打车太便宜应涨价!乘联会秘书长:燃油车用户纳税但未享受权益
世界速看:中老铁路首趟国际旅客列车发车:昆明当日通达万象 二等座470元
白玉兰奖《狂飙》张颂文呼声最高:国产电视剧质量、口碑爆发
有7/14nm光刻机国产芯片就能赶上来?全球半导体设备、材料核心已被全垄断
【读财报】房企3月融资:境内信用债发行规模环比翻倍 美元债发行回落
焦点滚动:银河证券:继续看好银行板块投资机会
每日动态!四大证券报精华摘要:4月13日
微头条丨高校围捕1.26米40斤“鳄雀鳝”:人为放生 长嘴如鳄鱼
兰博基尼推出插电混动超级跑车 60万美元迅速卖光
比亚迪汉、唐车主狂喜!今年内可OTA升级云辇系统 车型一览
焦点滚动:小米13 Ultra跑分出炉:第二代骁龙8 顶配16GB内存
天天时讯:俄罗斯国家空间站计划2027年开建:最新构型图正式公布
每日播报!信贷投放靠前发力为经济发展注入活力
比亚迪又放大招 直接对标奔驰
今日最新!403秒!我国人造太阳创造新的世界纪录:可控核聚变又近一步
世界滚动:校园内最美的舞蹈
四则运算练习&竞赛系统(结对编程)
世界滚动:[GIT]GIT之删除远程仓库中的目录或文件
神谷英树发文怒喷Switch:想把这垃圾砸碎!
世界快讯:10nm以下最强候选 中国半导体性单壁碳纳米管获突破
快看点丨被吐槽像绿皮火车!空姐飞机上推销商品吆喝40分钟 业内人士:不违规
【天天新视野】世界上最孤独的鲸鱼死了:圈养44年 5个孩子全部夭折
世界观焦点:技嘉发布韩国特供版RTX 4070:真花哨
穗是哪个城市的简称_广州的简称
全球看点:美国3月消费者价格指数环比增长0.1%
最新:面试题百日百刷-kafka篇(二)
全球看热讯:融创达成复牌指引 明起正式复牌
柯纳米员工袭击老板
每日快讯!是兄弟就来找ChatGPT漏洞 最高赏金2万刀:你敢来吗
当前头条:AMD 3D缓存大杀四方!Intel 14代酷睿上四级缓存
我国首颗太阳专用卫星 夸父一号观测数据将向国内外试开放
Vulnhub Mercy Walkthrough
java命令执行漏洞
环球新资讯:打印圣诞树
天天速讯:09字典(dict)与集合(set)
环球消息!懒人家常糖饼,和面方式不一般,出锅鼓泡不漏糖,松软甜蜜不会硬
索泰首发三款RTX 4070:天启功耗解锁250W!5399元
第三代“风雪”散热器 小巧高颜值!耕升RTX 4070踏雪显卡图赏
【新视野】发售一年的《幽灵线:东京》游戏上了D加密:学习版早已满天飞 玩家不解
从柯哀亲嘴到作者“去世” 又一场滑稽的互联网闹剧
正逆转设计 技嘉RTX 4070风魔OC 12G显卡图赏