代理模式
代理模式是常用的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. 大数据学习——scala类相关操作

    1 类的定义 package com /** * Created by Administrator on 2019/6/3. */ //类并不用声明为public. class Person { // ...

  2. Leetcode 464.我能赢吗

    我能赢吗 在 "100 game" 这个游戏中,两名玩家轮流选择从 1 到 10 的任意整数,累计整数和,先使得累计整数和达到 100 的玩家,即为胜者. 如果我们将游戏规则改为 ...

  3. maven无法下载依赖jar包—几种仓库的区别

    一.问题背景 最近这两天,感觉自己智商急剧退化,到了自己都捉急的地步,呃,有必要记录下来,以后智商被人甩几条街的时候,看看这篇文字,找找灵感也是好的! 这个项目呢,是用IDEA开发的,我一切都弄好了, ...

  4. CMMI5

    了解CMMI5是什么? 这种解决问题的思想很有用.

  5. 【bzoj4247】挂饰 背包dp

    题目描述 JOI君有N个装在手机上的挂饰,编号为1...N. JOI君可以将其中的一些装在手机上. JOI君的挂饰有一些与众不同——其中的一些挂饰附有可以挂其他挂件的挂钩.每个挂件要么直接挂在手机上, ...

  6. 【Luogu】P3224永无乡(splay)

    题目链接 splay模板,启发式合并(其实就是暴力插入)即可. 顺便吐槽时限,带垃圾回收而已……不至于最后一个点死活不让过吧? #include<cstdio> #include<c ...

  7. NOJ——1508火烧赤壁2(并查集+启发式合并+逆序加边)

    [1508] 火烧赤壁2 时间限制: 1000 ms 内存限制: 65535 K 问题描述 上次出了一道火烧赤壁的题目给当时的新生,也就是你们的上一届学长们做,那么这次,我又想到了另一个想法. 上次的 ...

  8. poj3728The merchant

    The merchant Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 4800   Accepted: 1666 Desc ...

  9. java面试题之什么是线程ThreadLocal?作用是什么?

    定义:线程局部变量是局限于线程内的变量,属于线程自身所有,不在多个线程间共享.java提供ThreadLocal类来支持线程局部变量,是一个实现线程安全的方式. 任何线程局部变量一旦在工作完成后没有释 ...

  10. CentOS7开启docker远程访问

    在 CentOS 中没有 /etc/default/docker,另外在 CentOS7 中也没有找到 /etc/sysconfig/docker这个配置文件. 在 /usr/lib/systemd/ ...