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的底层如何实现对方法的 ...
随机推荐
- 垃圾收集器与内存分配策略(深入理解Java虚拟机)
3.1 概述 垃圾收集器要解决哪些问题? 哪些内存需要回收 什么时候回收 如何回收 引用计数算法:当有一个地方引用,+1,引用失效,-1. 缺点:对象之间相互循环引用的问题. 可达性分析算法: ...
- sparksql读写hbase
//写入hbase(hfile方式) org.apache.hadoop.hbase.client.Connection conn = null; try { SparkLog.debug(" ...
- lr 常用操作
lr脚本编写语法: web_add_cookie();:服务器注入cookies lr_save_string("网址或其他","参数2");:一个保存函数,它 ...
- JSP页面无法使用EL导致"java.sql.SQLException: No suitable driver found for ${snapshot}"的问题
使用JSTL来连接mysql,这个问题折腾了半天,老以为是Mysql驱动的问题,还好最后偶然发现了是EL表达式识别不了,报错: javax.servlet.ServletException: java ...
- Python3 数值类型与运算符
1.数值类型与进制 (1)基本类型 整型:int 浮点型:float 布尔类型:bool 复数:complex print(type(1)) print(type(1.1)) print(type(F ...
- chameleon-Mini(迷你变色龙)
Chameleon Mini(迷你变色龙)是一个比一般信用卡稍大的小型开发板,是开源产品. 如图 Chameleon Mini可以完全复制许多商业非接触式智能卡包括UID卡,在内的全部内容,因此可以用 ...
- iscroll手册
概述: 大家在日常工作中最常用的插件是什么,jQurey?Lazyload?但是这些都是在PC端,但是在移动端最常用的插件莫过于iScroll了,iScroll到底是什么东西,应该怎么用?iScrol ...
- 网络编程--System.Net
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Android Shimmer 发光微光动画
这是Facebook提供的一个类库(题外话http://code.facebook.com,这里有很多好玩有趣有用的Facebook开源的类库) 这么炫酷的发光动画效果,想必很多Android码农都会 ...
- datepicker约束开始时间和结束时间
datepicker约束开始时间和结束时间作用就是:选择要搜索的日期范围. <!DOCTYPE html> <html lang="en"> <hea ...