SpringAOP--代理
前言
在Spring或者SpringBoot中,可以通过@Aspect注解和切点表达式等配置切面,实现对某一功能的织入。然而其内部到底是如何实现的呢?
实际上,Spring在启动时为切点方法所在类生成了代理类,通过操作代理类代替操作实际类,从而实现在真正调用方法之前或之后,插入一些我们自定义的逻辑。
如何生成代理类呢?
JDK动态代理
- JDK动态代理要求 被代理类必须有接口抽象。
- 通过实现 InvocationHandler 接口并实现 invoke(Object proxy, Method method, Object[] args) 方法进行自定义逻辑的织入:
- proxy :当前的代理类实例;
- method:被代理的方法;
- args:方法入参;
invoke方法的官方说明如下:即在
* Processes a method invocation on a proxy instance and returns
* the result. This method will be invoked on an invocation handler
* when a method is invoked on a proxy instance that it is
* associated with.
使用示例:
1、被代理的方法:
// 方法实现
public class HelloAOPImpl implements HelloAOP {
@Override
public String sayHello() {
String hello = "你好,AOP";
System.out.println(hello);
return hello;
}
}
2、配置自定义调用处理器
public class MyInvocationHandler implements InvocationHandler {
private Object target;
// 通过构造函数将配代理对象注入
public MyInvocationHandler(Object target) {
this.target = target;
}
//回调
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是代理,有人让我对你说:");
/**调用前,自定义业务*/
Object res = method.invoke(target, args);
/**调用后,自定义业务*/
return res;
}
//获取代理类实例
public <T> T getProxyInstance(){
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
}
2:调用与输出:
public static void main(String[] args) {
HelloAOPImpl helloAOP = new HelloAOPImpl();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(helloAOP);
HelloAOP proxy = myInvocationHandler.getProxyInstance();
proxy.sayHello();
}
// 输出
我是代理,有人让我对你说:
你好,AOP
一个疑问:代理类如何取代被代理类的呢?
CGLIB动态代理
CGLIB动态代理不需要代理对象实现某个接口:
1、被代理类(没有接口实现)
public class HelloAOPImpl2 {
public void sayHello() {
String s = "你好,AOP";
System.out.println(s);
}
}
2、CGLIB代理
public class CgibAOP2 implements MethodInterceptor {
private Object target;
/**
* 通过构造函数设置被代理对象
* @param target
*/
public CgibAOP2(Object target) {
this.target = target;
}
/**
* 回调该方法。
* @param o
* @param method
* @param objects
* @param methodProxy
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("say之前:"+ method+"1");
Object res = method.invoke(target, objects);
System.out.println("say之后:"+ method+"1");
return res;
}
/**
* 生成代理实例
* @return
*/
public Object getProxy(){
// 通过增强实现
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this); //设置回调
Object res = enhancer.create();
return res;
}
}
3、测试:
public class Test {
public static void main(String[] args) {
HelloAOPImpl2 helloAOP = new HelloAOPImpl2();
HelloAOPImpl2 proxy = (HelloAOPImpl2)new CgibAOP2(helloAOP).getProxy();
proxy.sayHello();
}
}
输出:
say之前:public void com.wht.springaop.DynamicProxy.Cglib.HelloAOPImpl2.sayHello()1
你好,AOP
say之后:public void com.wht.springaop.DynamicProxy.Cglib.HelloAOPImpl2.sayHello()1
SpringAOP--代理的更多相关文章
- SpringAOP代理报错问题
public class BaseDataSyncPushJob implements StatefulJob{ /*** 日志 */ private static final Log LOG = L ...
- spring-aop代理的生效原理
主要说下spring里aop的生效的原理吧,并不是讲底层的cglib和gdk动态代理. 还是老一套的分析流程,先找到了aop的标签的handler,然后看下在解析这个标签的时候,都干了些什么,其实主要 ...
- SpringAOP深入学习
----------------------Spring AOP介绍------------------ 1.编程范式概念 面向过程编程:C 面向对象编程:c++,Java 函数式编程 事件驱动编程: ...
- spring源码学习之路---深入AOP(终)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...
- 教育单元测试mock框架优化之路(中)
转载:https://sq.163yun.com/blog/article/169564470918451200 三.间接依赖的bean的mock替换 对于前面提供的@Mock,@Spy+@Injec ...
- 面试真题--------spring源码解析AOP
接着上一章对IOC的理解之后,再看看AOP的底层是如何工作的. 1.实现AOP的过程 首先我们要明白,Spring中实现AOP,就是生成一个代理,然后在使用的时候调用代理. 1.1 创建代理工厂 ...
- Spring中AOP实现
1.什么是SpringAOP 什么是aop:Aspect Oriented Programming的缩写,面向切面编程,通过预编译和动态代理实现程序功能的 统一维护的一种技术 主要功能:日志记录,性能 ...
- Spring5参考指南:AspectJ注解
文章目录 什么是AspectJ注解 启用AOP 定义Aspect 定义Pointcut 切入点指示符(PCD) 切入点组合 Advice 访问JoinPoint Advice参数 Advice参数和泛 ...
- @Transactional-同一个类中方法自调,调用方法事物失效
问题分析 一个类中的方法调用另一个事物传播性为创建事物的方法,调用的方法事物失效? SpringAOP 代理的Service对象调用了其方法,这个方法再去调用这个Service中的其他方法是没有使用A ...
- Spring事务的介绍,以及基于注解@Transactional的声明式事务
前言 事务是一个非常重要的知识点,前面的文章已经有介绍了关于SpringAOP代理的实现过程:事务管理也是AOP的一个重要的功能. 事务的基本介绍 数据库事务特性: 原子性 一致性 隔离性 持久性 事 ...
随机推荐
- MyBatis功能点一应用:二级缓存整合redis
Mybatis提供了默认的cache实现PerpetualCache,那为什么还要整合第三方的框架redis?因为Mybatis提供的cache实现为单机版,无法实现分布式存储(即本机存储的数据,其他 ...
- Asp.Net Core: Swagger 与 Identity Server 4
Swagger不用多说,可以自动生成Web Api的接口文档和客户端调用代码,方便开发人员进行测试.通常我们只需要几行代码就可以实现这个功能: ... builder.Services.AddSwag ...
- v-model指令的学习
v-model的原理 v-model="message" ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓就相当于先用一个v-bind绑定一个 ...
- VBS病毒实验
实验目的 探讨VBS病毒实现原理,为更好的深入防御和查杀病毒 实验原理 VBS病毒发生机理 实验内容 编写简单VBS病毒,并实现功能,学习VBS病毒发生机理 实验环境描述 VPC1(虚拟PC) 操作系 ...
- ISISv6协议测试——信而泰网络测试仪实操
文章关键词 ISIS协议:路由协议:协议测试: 一.前言: isis是一种与ospf很相似的网络协议(属于动态路由协议),它被应用在巨大规模网络,如运营商以及银行等.同样的它也是基于链路状态算法,支持 ...
- kibana操作记录
GET _search { "query": { "match_all": {} } } GET _cat/nodes GET _cat/health GET ...
- Windows11中如何使用旧版本IE浏览器打开网页
Windows11删除了旧版本IE浏览器,完全采用了Edge,但是我们进行网站测试时有时仍会用到IE浏览器,那么可以按照以下步骤启用: 1.进入Edge浏览器中,打开设置,进入默认浏览器选项下: 修改 ...
- Spring Cloud Gateway 不小心换了个 Web 容器就不能用了,我 TM 人傻了
个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...
- windows禁止iis开机自启
按Win 和R,打开运行窗口.输入services.msc确定打开服务窗口.找到World Wide Web Publishing Service禁用并停止.
- TP5框架中实现多条件登录(自写代码,密码未md5()加密)
HTML代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...