Java代理学习笔记
- 代理模式
- 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
- 按照代理的创建时期,代理类可以分为两种。
- 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
- 动态代理:在程序运行时,运用反射机制动态创建而成。
- AOP(面向切面编程),就是针对代理的一种应用。
- 下面以一个简单示例开始:
- public interface Hello {
- void say(String name);
- }
- public class HelloImpl implements Hello {
- @Override
- public void say(String name) {
- System.out.println("Hello! "+name);
- }
- }
- ---------------main------------------------
- Hello hello = new HelloImpl();
- hello.say("Jack");
- ---------------console------------------------
- Hello! Jack
- 现在有个需求,在say()方法执行前后分别执行相关逻辑。下面分别通过静态代理和动态代理来实现。
- 1.静态代理(GoF代理模式)
- public class HelloProxy implements Hello {
- private Hello hello;
- public HelloProxy(){
- hello = new HelloImpl();
- }
- @Override
- public void say(String name) {
- before();
- hello.say(name);
- after();
- }
- private void before(){
- System.out.println("Before");
- }
- private void after(){
- System.out.println("After");
- }
- }
- ---------------main------------------------
- Hello hp = new HelloProxy();
- hp.say("Tom");
- ---------------console------------------------
- Before
- Hello! Tom
- After
- 2.动态代理(JDK动态代理,CGLIB动态代理)
- (1).JDK动态代理
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- public class DynamicProxy implements InvocationHandler {
- private Object target;
- public DynamicProxy(Object target){
- this.target = target;
- }
- @SuppressWarnings("unchecked")
- public <T> T getProxy() {
- return (T) Proxy.newProxyInstance(
- target.getClass().getClassLoader(),
- target.getClass().getInterfaces(),
- this
- );
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- before();
- Object result = method.invoke(target, args);
- after();
- return result;
- }
- private void before(){
- System.out.println("Before");
- }
- private void after(){
- System.out.println("After");
- }
- }
- ----------------main-----------------------
- DynamicProxy dp = new DynamicProxy(new HelloImpl());
- Hello helloProxy = dp.getProxy();
- helloProxy.say("Grace");
- -----------------console----------------------
- Before
- Hello! Grace
- After
- JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
- (2).CGLib实现动态代理
- 需要引入两个jar: cglib-2.2.2.jar, asm-3.3.jar
- ASM:一个轻量级的字节码生成及转换器。
- CGLIB:一个功能强大的动态代理代码工具,可以根据指定的类动态生成一个子类,并提供了方法拦截的相关机制,并且在大量的流行开源框架(如 Hibernate、Spring 等)中得到使用。
- import java.lang.reflect.Method;
- import net.sf.cglib.proxy.Enhancer;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.MethodProxy;
- public class CGLibProxy implements MethodInterceptor {
- private static CGLibProxy instance = new CGLibProxy();
- private CGLibProxy() {
- }
- public static CGLibProxy getInstance() {
- return instance;
- }
- @SuppressWarnings("unchecked")
- public <T> T getProxy(Class<T> cls) {
- return (T) Enhancer.create(cls, this);
- }
- @Override
- public Object intercept(Object obj, Method method, Object[] args,
- MethodProxy proxy) throws Throwable {
- before();
- Object result = proxy.invokeSuper(obj, args);
- after();
- return result;
- }
- private void before(){
- System.out.println("Before");
- }
- private void after(){
- System.out.println("After");
- }
- }
- ----------------main-----------------------
- HelloImpl helloImpl = CGLibProxy.getInstance().getProxy(HelloImpl.class);
- helloImpl.say("Victor");
- ---------------console------------------------
- Before
- Hello! Victor
- After
- 参考:
- 1.http://my.oschina.net/huangyong/blog/159788 Proxy那点事儿
- 2.http://my.oschina.net/huangyong/blog/161338 AOP那点事儿
- 3.http://jinnianshilongnian.iteye.com/blog/1474325 我对AOP的理解
- 4.http://kiral.iteye.com/blog/1198982 AOP实现机制
Java代理学习笔记的更多相关文章
- Java 代理学习笔记
http://blog.csdn.net/mr_seaturtle_/article/details/52686516
- Android(java)学习笔记227:服务(service)之服务的生命周期 与 两种启动服务的区别
1.之前我们在Android(java)学习笔记171:Service生命周期 (2015-08-18 10:56)说明过,可以回头看看: 2.Service 的两种启动方法和区别: (1)Servi ...
- Android(java)学习笔记170:服务(service)之服务的生命周期 与 两种启动服务的区别
1.之前我们在Android(java)学习笔记171:Service生命周期 (2015-08-18 10:56)说明过,可以回头看看: 2.Service 的两种启动方法和区别: (1)Servi ...
- 尚学堂JAVA基础学习笔记
目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...
- JAVA Web学习笔记
JAVA Web学习笔记 1.JSP (java服务器页面) 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . JSP全名为Java Server Pages,中文名叫java服务器 ...
- 20145213《Java程序设计学习笔记》第六周学习总结
20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...
- [原创]java WEB学习笔记95:Hibernate 目录
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- java JDK8 学习笔记——助教学习博客汇总
java JDK8 学习笔记——助教学习博客汇总 1-6章 (by肖昱) Java学习笔记第一章——Java平台概论 Java学习笔记第二章——从JDK到IDEJava学习笔记第三章——基础语法Jav ...
- java JDK8 学习笔记——第16章 整合数据库
第十六章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程 ...
随机推荐
- Jmeter测试https协议
- PostgreSQL 全文索引
-- 首先要创建自定义的词典,在不使用停用词文件的情况下创建自定义词典,例如: CREATE TEXT SEARCH DICTIONARY english_stem_nostop ( Template ...
- linux dd命令创建一定大小的文件
http://www.cnblogs.com/jikexianfeng/p/6103500.html
- javascript学习笔记 - 引用类型 RegExp
四 RegExp 格式: var expression = / pattern / flags; 1.flags 为标志.分别为g.i.m. g:表示全局模式.即模式将匹配所有的字符串,而不是在发现第 ...
- Scrum基础知识图谱
啰嗦一下 最近在学习scrum项目管理的知识,书上知识点分散,很难有整体的视角来看scrum有哪些核心知识,故制作了思维导图,望给和我一样容易迷失的人一样,起到一个指引作用,废话不多说,直接上图 图谱
- 九度oj 题目1366:栈的压入、弹出序列
题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈 ...
- POJ 2353 Ministry
Ministry Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4220 Accepted: 1348 Specia ...
- iOS学习笔记41-Swift(一)基础部分
一.Swift语言介绍 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题. Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种 ...
- iOS学习笔记29-系统服务(二)通讯录
一.通讯录 iOS中的通讯录是存储在数据库中的,由于iOS的权限设计,开发人员是不允许直接访问通讯录数据库的,实现通讯录操作需要使用到AddressBook.framework框架. AddressB ...
- 通过rabbitmqadmin管理rabbitmq
# 安装rabbitmq $ sudo apt install rabbitmq-server # 下载rabbitmqadmin管理工具 sudo rabbitmq-plugins enable r ...