Spring AOP解析

AOP: Aspect Oriented Programming 面向切面编程。

AOP底层实现原理:代理模式

什么是代理模式?

通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。既(AOP微实现) ,AOP核心技术面向切面编程。

代理模式分为静态代理与动态代理

 

静态代理:

什么是静态代理?

由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

通过别的类B代理这个类A,这个类的具体情况,调用的类C并不知道

 

动态代理:

什么是动态代理?

1.代理对象,不需要实现接口

2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)

3.动态代理也叫做:JDK代理,接口代理

 

JDK动态代理:

实现方式:

1.通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);

2.通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});

3.通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});

4.通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

需要被代理的类:

public interface Subject
{public void rent();public void hello(String str);
}
public class RealSubject implements Subject
{@Overridepublic void rent(){System.out.println("I want to rent my house");}@Overridepublic void hello(String str){System.out.println("hello: " + str);}
}

动态代理类:


public class DynamicProxy implements InvocationHandler
{// 这个就是我们要代理的真实对象private Object subject;// 构造方法,给我们要代理的真实对象赋初值public DynamicProxy(Object subject){this.subject = subject;}@Overridepublic Object invoke(Object object, Method method, Object[] args)throws Throwable{// 在代理真实对象前我们可以添加一些自己的操作System.out.println("before rent house");System.out.println("Method:" + method);// 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用method.invoke(subject, args);// 在代理真实对象后我们也可以添加一些自己的操作System.out.println("after rent house");return null;}
}

调用:

public static void main(String[] args){// 我们要代理的真实对象Subject realSubject = new RealSubject();// 我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的InvocationHandler handler = new DynamicProxy(realSubject);/** 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数* 第一个参数handler.getClass().getClassLoader(),我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象* 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了* 第三个参数handler,我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上*/Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler);System.out.println(subject.getClass().getName());subject.rent();subject.hello("world");}

结果:


$Proxy0before rent house
Method:public abstract void com.xiaoluo.dynamicproxy.Subject.rent()
I want to rent my house
after rent housebefore rent house
Method:public abstract void com.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)
hello: world
after rent house

总结:AOP主要是通过InvocationHandler(Interface)和 Proxy(Class)来实现

invoke是InvocationHandler的唯一方法

 

通过被代理的类,接口,以及我们实现的InvocationHandler作为参数,调用newProxyInstance

这样就把完成了代理

调用时通过invoke方法进行处理,我们可以在处理前后加上一些其他处理。

 

 

CGLIB动态代理:


public class CglibProxy implements MethodInterceptor {private Object targetObject;// 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理public Object getInstance(Object target) {// 设置需要创建子类的类this.targetObject = target;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return enhancer.create();}
​public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("开启事物");Object result = proxy.invoke(targetObject, args);System.out.println("关闭事物");// 返回代理对象return result;}public static void main(String[] args) {CglibProxy cglibProxy = new CglibProxy();UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao());userDao.save();}
}

java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

 

编程中注解的AOP实现:


@Component
@Aspect
public class AopLog {
​// 前置通知@Before("execution(* com.service.UserService.add(..))")public void begin() {System.out.println("前置通知");}
​
​// 后置通知@After("execution(* com.service.UserService.add(..))")public void commit() {System.out.println("后置通知");}
​// 运行通知@AfterReturning("execution(* com.service.UserService.add(..))")public void returning() {System.out.println("运行通知");}
​// 异常通知@AfterThrowing("execution(* com.service.UserService.add(..))")public void afterThrowing() {System.out.println("异常通知");}
​// 环绕通知@Around("execution(* com.service.UserService.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("环绕通知开始");proceedingJoinPoint.proceed();System.out.println("环绕通知结束");}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/484958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

杜克大学和Facebook联手开发更好的光通信

来源:IEEE电气电子工程师Illustration: Duke UniversityA close-up depiction of the new fiber-free optical WiFi antenna. Silver nanocubes are spaced just a few nanometers above a silver base, with fluorescent dyes sandwiched in between. The physical…

Leetcode--287. 寻找重复数(Java)

给定一个包含 n 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。 示例 1: 输入: [1,3,4,2,2] 输出: 2 示例 2: 输入: [3,1,3,4…

优动漫PAINT核心功能介绍

优动漫PAINT是一款功能强大的动漫绘图软件,适用于个人和专业团队创作,分为个人版和EX版。搭载了绘制漫画和插画所需的所有功能——丰富的笔工具、超强的笔压感应和手颤修正功能,可分别满足画师对于插画、漫画和动画创作的针对性需求。 1. 实现…

2020图灵奖颁给“龙书”两位作者!合作数十年,他们让计算机读懂码农代码

来源:大数据文摘作者:Caleb就在昨天,2020年图灵奖公布了获奖名单。哥伦比亚大学计算机科学名誉教授Alfred Vaino Aho和斯坦福大学计算机科学名誉教授Jeffrey David Ullman共享了这一殊荣。根据国际计算机协会(ACM)报道…

C语言例题4

1.以下程序运行后&#xff0c;输出结果是 9.5 #include<stdio.h> #define PT 5.5 #define S(x) PT*x*x     int main( )     { int a1&#xff0c;b2;     printf(“%4.1f\n”&#xff0c;S(ab))     } PT*ab*ab5.5*12*129.5 2. 下列对字符串的定义中…

volatile关键字解析

volatile&#xff1a; 1.保证可见性 2.禁止重排序 我们先来看看一个问题&#xff0c;关于ii1的问题。 首先&#xff0c;他不是一个原子性的操作&#xff0c;我们通常将不可拆分的操作称为原子操作 而ii1需要先在主存中取得i的值&#xff0c;之后复制到高速缓存之中&#x…

HTML5/CSS3基础

1. HTML 1.1 什么是HTML HTML是用来制作网页的标记语言HTML是Hypertext Markup Language的英文缩写,即超文本标记语言HTML语言是一种标记语言,不需要编译,直接由浏览器执行HTML文件是一个文本文件,包含了一些HTML元素,标签等HTML文件必须使用.html或.htm为文件名后缀HTML是大小…

机器学习泰斗迈克尔 · 乔丹:不是什么都叫AI的

来源&#xff1a;IEEE Spectrum作者&#xff1a;Kathy Pretz编译&#xff1a;机器之心编辑&#xff1a;小舟、张倩「人工智能系统还远远不够先进&#xff0c;无法在涉及推理、运用现实世界知识和社交互动等许多任务中替代人类。」机器学习先驱迈克尔 欧文 乔丹&#xff08;Mi…

synchronized和lock的区别

公平锁。syn是非公平锁&#xff0c;无法保证线程按照申请锁的顺序获得锁&#xff0c;而Lock锁提供了可选参数&#xff0c;可以配置成公平锁&#xff0c;也可以配置成非公平锁。通常来说&#xff0c;非公平锁的效率比公平锁要高。 可中断锁。一个线程使用syn获取锁&#xff0c;除…

经典数值优化算法--专题学习

通用的损失函数最优化的数值方法&#xff0c;来源于泰勒展开式&#xff0c;多元函数的泰勒展开式为&#xff1a; 一、一阶逼近与一阶方法 一阶泰勒展开式&#xff1a; 其中&#xff0c;是代表了β变化的可能性&#xff0c;t在之后说到的梯度下降方法中演变成了学习速率。 现在&…

美国雷神公司对第六代战斗机的任务系统提出六点预测

来源&#xff1a;转载自公众号 “空天防务观察”图片&#xff1a;来源于网络编辑&#xff1a;朱锦锟审阅&#xff1a;原熙文2021年3月29日&#xff0c;美国雷神技术公司旗下的雷神情报与太空公司刊文&#xff0c;称该公司的工程师们针对可在未来“第六代”战斗机上运行的任务系…

Leetcode--394. 字符串解码(Java)

给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;输入字符串中没有额外的空格&#xff0c;且…

人机猜拳

import java.util.Scanner;public class Person { Scanner input new Scanner(System.in); String name; int score; String action; int num; public void method() { System.out.println("\n请出拳&#xff1a;1.剪刀 2.石头 3.布"); boolean a true; do { num…

【专家观点】张亚勤、张宏江:人工智能的未来是什么?

来源&#xff1a;智能研究院“我们打造一个规模庞大的系统时&#xff0c;更需要具备系统思维&#xff0c;同时拥有动手能力、喜欢搭系统的人才……诞生至今&#xff0c;智源一直肩负着三项重要任务&#xff1a;一是构筑一个社区。二是打造一个真正适合青年科学家成长的平台。三…

Leetcode--837. 新21点(java)

爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏&#xff0c;描述如下&#xff1a; 爱丽丝以 0 分开始&#xff0c;并在她的得分少于 K 分时抽取数字。 抽取时&#xff0c;她从 [1, W] 的范围中随机获得一个整数作为分数进行累计&#xff0c;其中 W 是整数。 每次抽取都是…

python文件操作,自动关闭

with opne("text.txt", encoding"utf8") as f, open("text2.txt", encoding"utf8") as f2 : pass with代码块执行完就自动close文件、转载于:https://www.cnblogs.com/somethingintheway/p/9789650.html

近亿台物联网设备或遭劫持,这家IoT云平台遭遇“灾难性”入侵事件

来源&#xff1a;互联网安全内参参考来源&#xff1a;krebsonsecurity.com编译&#xff1a;安全内参近日&#xff0c;一位熟悉该事件内情的消息人士表示&#xff0c;Ubiquiti对外刻意削弱了此次事件的“灾难性”后果&#xff0c;希望降低对股价的打击。涉事第三方云服务商也发布…

第一范式,第二范式,第三范式,BCNF范式理解

基础知识 实体&#xff1a;现实世界中客观存在并可以被区别的事物。比如“一个学生”、“一本书”、“一门课”等等。值得强调的是这里所说的“事物”不仅仅是看得见摸得着的“东西”&#xff0c;它也可以是虚拟的&#xff0c;比如说“老师与学校的关系”。 属性&#xff1a;教…

国产光刻设备第一股:从官司缠身到国产希望?

来源&#xff1a;传感器技术作者&#xff1a;温淑编辑&#xff1a;心缘科创板“国产直写光刻设备第一股”正式登陆A股市场&#xff01;在经过约10个月的审查后&#xff0c;国产半导体设备供应商合肥芯碁微装终于在4月1日正式敲钟&#xff0c;首次公开发行A股约3220万股&#xf…

Leetcode--1014. 最佳观光组合(java)

给定正整数数组 A&#xff0c;A[i] 表示第 i 个观光景点的评分&#xff0c;并且两个景点 i 和 j 之间的距离为 j - i。 一对景点&#xff08;i < j&#xff09;组成的观光组合的得分为&#xff08;A[i] A[j] i - j&#xff09;&#xff1a;景点的评分之和减去它们两者之间…