代理模式
代理模式是常用的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代理学习笔记的更多相关文章

  1. Java 代理学习笔记

    http://blog.csdn.net/mr_seaturtle_/article/details/52686516

  2. Android(java)学习笔记227:服务(service)之服务的生命周期 与 两种启动服务的区别

    1.之前我们在Android(java)学习笔记171:Service生命周期 (2015-08-18 10:56)说明过,可以回头看看: 2.Service 的两种启动方法和区别: (1)Servi ...

  3. Android(java)学习笔记170:服务(service)之服务的生命周期 与 两种启动服务的区别

    1.之前我们在Android(java)学习笔记171:Service生命周期 (2015-08-18 10:56)说明过,可以回头看看: 2.Service 的两种启动方法和区别: (1)Servi ...

  4. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

  5. JAVA Web学习笔记

    JAVA Web学习笔记 1.JSP (java服务器页面) 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . JSP全名为Java Server Pages,中文名叫java服务器 ...

  6. 20145213《Java程序设计学习笔记》第六周学习总结

    20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...

  7. [原创]java WEB学习笔记95:Hibernate 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. java JDK8 学习笔记——助教学习博客汇总

    java JDK8 学习笔记——助教学习博客汇总 1-6章 (by肖昱) Java学习笔记第一章——Java平台概论 Java学习笔记第二章——从JDK到IDEJava学习笔记第三章——基础语法Jav ...

  9. java JDK8 学习笔记——第16章 整合数据库

    第十六章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程 ...

随机推荐

  1. Activity树图

  2. python基础-爬虫

    爬虫引入 爬虫: 1 百度:搜索引擎 爬虫:spider   种子网站开始爬,下载网页,分析链接,作为待抓取的网页 分词 index:词--->某个结果 Page rank(1 网站很大(互链) ...

  3. logging——日志

    导读 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,log ...

  4. Python3异常-AttributeError: module 'sys' has no attribute 'setdefaultencoding'

    基于python3.6.1版本,在一个.py文件中,加入这3行: import requests, re, sys reload(sys) sys.setdefaultencoding("u ...

  5. Leetcode 430.扁平化多级双向链表

    扁平化多级双向链表 您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表.这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示. 扁 ...

  6. Thanks for your encourage!

    将近三个月的学习,我的努力换回了代表荣誉的小黄衫,这令我很开心啊...我想是不是要写点什么来表达自己的心情呢=,=  于是就有了以下文字ahhhhhh... 学习心得: (1)学习中总会有失败和成功, ...

  7. C++大数相加

    c++ string sum(string s1,string s2) { if(s1.length()<s2.length()) { string temp=s1; s1=s2; s2=tem ...

  8. how to write an front-end framework by using vanilla JavaScript?

    how to write an front-end framework by using vanilla javascript? https://www.quora.com/How-can-I-mak ...

  9. 【Luogu】P3327约数个数和(莫比乌斯反演+神奇数论公式)

    题目链接 真TM是神奇数论公式. 注明:如无特殊说明我们的除法都是整数除法,向下取整的那种. 首先有个定理叫$d(ij)=\sum\limits_{i|n}{}\sum\limits_{j|m}{}( ...

  10. caffe编译新问题

    我在一台机子上,配置第二个caffe的时候,复制之前的Makefile文件,直接 make all 居然报错了报错如下 ndefined reference to cv::imread(cv::Str ...