Spring 容器AOP的实现原理——动态代理
参考:http://wiki.jikexueyuan.com/project/ssh-noob-learning/dynamic-proxy.html(from极客学院)
一、介绍
Spring的动态代理有两种:一是JDK的动态代理;另一个是cglib动态代理(通过修改字节码来实现代理)。
今天主要讨论JDK动态代理的方式。
JDK的代理方式主要就是通过反射跟动态编译来实现的,主要搭配InvocationHandler和Proxy来实现,下面的例子中使用了两层代理(即代理上加了一层代理)。
二、实例
1. 公共接口
package com.tgb.proxy;
public interface UserMgr {
void addUser();
void delUser();
}
2. 实现类
package com.tgb.proxy;
public class UserMgrImpl implements UserMgr {
@Override
public void addUser() {
System.out.println("添加用户....");
}
@Override
public void delUser() {
System.out.println("删除用户.....");
}
}
3. TransactionHandler(InvocationHandler的实现)
package com.tgb.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class TransactionHandler implements InvocationHandler { private Object target; public TransactionHandler(Object target){
super();
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开启事务..."); method.invoke(target); System.out.println("提交事务..."); return null;
} }
4. TimeHandler(InvocationHandler的实现)
package com.tgb.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Calendar; public class TimeHandler implements InvocationHandler { private Object target; public TimeHandler(Object target) {
super();
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Calendar calendar = Calendar.getInstance(); System.out.println("start time:" + calendar.get(Calendar.HOUR_OF_DAY)); method.invoke(target); System.out.println("end time:" + calendar.get(Calendar.HOUR_OF_DAY)); return null;
} }
5. 测试类
package com.tgb.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { UserMgr userMgr = new UserMgrImpl(); // 1.第一层代理----------通过动态代理,添加事务处理
InvocationHandler handler = new TransactionHandler(userMgr);
UserMgr userMgrProxy = (UserMgr) Proxy.newProxyInstance(userMgr.getClass().getClassLoader(),
userMgr.getClass().getInterfaces(), handler); // 2.第二层代理----------通过动态代理,添加时间处理
InvocationHandler handler2 = new TimeHandler(userMgrProxy);
UserMgr userMgrProxy2 = (UserMgr) Proxy.newProxyInstance(userMgrProxy.getClass().getClassLoader(),
userMgrProxy.getClass().getInterfaces(), handler2); userMgrProxy2.addUser(); System.out.println("========================================"); userMgrProxy2.delUser(); }
}
输出结果:
start time:Tue Aug 09 23:54:54 CST 2016
开启事务...
添加用户....
提交事务...
end time:Tue Aug 09 23:54:54 CST 2016
========================================
start time:Tue Aug 09 23:54:54 CST 2016
开启事务...
删除用户.....
提交事务...
end time:Tue Aug 09 23:54:54 CST 2016
Spring 容器AOP的实现原理——动态代理的更多相关文章
- 菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理
之前写了一篇关于IOC的博客——<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP,换句话说,容器的两大特性就是IOC和AOP. ...
- Spring容器AOP的实现原理——动态代理(转)
文章转自http://blog.csdn.net/liushuijinger/article/details/37829049#comments
- 浅析Spring中AOP的实现原理——动态代理
一.前言 最近在复习Spring的相关内容,刚刚大致研究了一下Spring中,AOP的实现原理.这篇博客就来简单地聊一聊Spring的AOP是如何实现的,并通过一个简单的测试用例来验证一下.废话不 ...
- AOP的实现原理——动态代理
IOC负责将对象动态的 注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果,可谓是招之则来,挥之则去.想想都觉得爽,如果现实生活中也有这本事那就爽 歪歪了,至于有多爽,各位自己脑 ...
- 七 MyBatis整合Spring,DAO开发(传统DAO&动态代理DAO)
整合思路: 1.SQLSessionFactory对象应该放到Spring中作为单例存在 2.传统dao开发方式中,应该从Spring容器中获得SqlSession对象 3.Mapper代理行驶中,应 ...
- Hibernate学习--hibernate延迟加载原理-动态代理(阿里电面)
在正式说hibernate延迟加载时,先说说一个比较奇怪的现象吧:hibernate中,在many-to-one时,如果我们设置了延迟加载,会发现我们在eclipse的调试框中查看one对应对象时,它 ...
- spring框架中JDK和CGLIB动态代理区别
转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/ ...
- 新秀学习SSH(十四)——Spring集装箱AOP其原理——动态代理
之前写了一篇文章IOC该博客--<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP. IOC负责将对象动态的注入到容器,从而达到 ...
- Spring AOP实现原理-动态代理
目录 代理模式 静态代理 动态代理 代理模式 我们知道,Spring AOP的主要作用就是不通过修改源代码的方式.将非核心功能代码织入来实现对方法的增强.那么Spring AOP的底层如何实现对方法的 ...
随机推荐
- 将Render博客搬至GIT(偷懒)
SmallEngine 一个特别小的研究引擎[用于各种实验] 框架上设计上采用Unreal.Unity的设计思路[偷懒了] https://github.com/daozhangXDZ/DZSmall ...
- java并发总览
- mysql 主从配置笔记
1.master配置 server-id=1 log-bin=mysql-bin binlog-do-db=testdata binlog-ignore-db=mysql 2.master增加用户 g ...
- [HNOI2017]影魔
题意: 给定 \(n\) 个数的排列,\(m\) 次询问,每次询问询问一个区间内所有子区间的贡献. 每个区间如果两个端点分别是最大值和次大值,我们就算 \(P1\) 的贡献. 如果两个端点一个是最大值 ...
- maven 安装、配置
简介: maven 大大提高项目开发速度 编译---打包---测试--安装 一条龙 maven将项目构建的过程标准化,每一个阶段使用一个命令完成,下面是构建过程一些阶段 清理 mvn cl ...
- Rightmost Digit(最后一位数字)
Description Given a positive integer N, you should output the most right digit of N^N. Input The ...
- Thunder团队第五周 - Scrum会议7
Scrum会议7 小组名称:Thunder 项目名称:i阅app Scrum Master:苗威 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...
- Python学习之路5 - 函数
函数 定义方式: def func(): "这里面写函数的描述" 这里写代码 return x #如果没有返回值就叫"过程",函数和过程的区别就是有无返回值 实 ...
- window对象与document对象的区别
[window对象] 它是一个顶层对象,而不是另一个对象的属性,即浏览器的窗口. 属性 defaultStatus 缺省的状态条消息 document 当前显示的文档(该属性本身也是一个对象) fra ...
- java键盘IO
public class IO { public static void main(String[] args) throws Throwable { ScannerTest(); // testSc ...