一、静态代理

根据被代理的类的时机的不同,如果在编译阶段就能确定下来的被代理的类是哪一个,那么,就可以使用静态代理的方式。

申明一个接口:

 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description
* @date 2018/7/23
*/
public interface Person {
void sayHello(String content, int age);
}

实现类,即需要被代理的类:

 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description 需要被代理的类 实现接口
* @date 2018/7/23
*/
public class Student implements Person {
@Override
public void sayHello(String content, int age) {
System.out.println("student say hello " + content + " "+ age);
}
}

实现类:

 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description
* @date 2018/7/23
*/
public class StaticProxyTest implements Person{
//接口对象
private Person o; public StaticProxyTest(Person o){
this.o = o;
} public static void main(String[] args) {
// TODO Auto-generated method stub
//s为被代理的对象,某些情况下 我们不希望修改已有的代码,我们采用代理来间接访问
//在代理类中引入被代理的对象
Student s = new Student();
//创建代理类对象 s是接口的实例
StaticProxyTest proxy = new StaticProxyTest(s);
//调用代理类对象的方法
proxy.sayHello("welcome to java", 20);
} @Override
public void sayHello(String content, int age) {
// TODO Auto-generated method stub
System.out.println("ProxyTest sayHello begin");
//在代理类的方法中 间接访问被代理对象的方法
o.sayHello(content, age);
System.out.println("ProxyTest sayHello end");
}
}

二、动态代理

如果不能在代码的编译阶段就去确定需要代理的类是哪一个的话,就可以使用类的动态代理机制,在代码运行期间去动态加载类的信息。

Java动态代理和Cglib方式的代理的重要区别:

Java动态代理只能对接口进行代理,如果要代理的类是一个普通的类,没有接口则需要使用Cglib来实现。
Java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
Cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

创建接口:

 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description
* @date 2018/7/23
*/
public interface IStudent {
void action();
}
 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description
* @date 2018/7/23
*/
public class StudentImpl implements IStudent{
@Override
public void action() {
System.out.println("Student action");
}
}
基于jdk的动态代理 该动态代理一定要实现InvocationHandler
 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description 基于jdk的动态代理 该动态代理一定要实现InvocationHandler
* @date 2018/7/23
*/
public class JavaProxy implements InvocationHandler {
private Object target; /**
* 绑定委托对象并返回一个代理类
*
* @param target
* @return
*/
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); // 要绑定接口
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result;
//在这里可以做拦截前的操作
System.out.println("【java代理】调用实际方法前");
// 执行方法
result = method.invoke(target, args);
//在这里可以做拦截后的操作
System.out.println("【java代理】调用实际方法后");
return result;
}
}
 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description
* @date 2018/7/23
*/
public class TestProxy {
public static void main(String[] args) {
//创建代理对象
JavaProxy proxy = new JavaProxy();
//绑定接口对象
IStudent student = (IStudent) proxy.bind(new StudentImpl());
//调用接口方法
student.action();
}
}

三、基于cglib的动态代理

可以对任何的普通类进行代理

 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description 一个普通类
* @date 2018/7/23
*/
public class StudentImpl {
public void action() {
System.out.println("[Student]实际方法。。。");
}
}

代理类要去实现MethosInterceptor接口:

 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description
* @date 2018/7/23
*/
public class CgLibProxy implements MethodInterceptor {
private Object target; /**
* 创建代理对象
*
* @param target
* @return
*/
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
} // 回调方法 拦截方法 在调用具体的业务逻辑前和后 进行其他的相关处理
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("[cglib代理]调用实际方法前");
proxy.invokeSuper(obj, args);
System.out.println("[cglib代理]调用实际方法后");
return null;
}
}
 /**
* @author jiaqing.xu@hand-china.com
* @version 1.0
* @name
* @description
* @date 2018/7/23
*/
public class TestProxy {
public static void main(String[] args) {
CgLibProxy cglib = new CgLibProxy();
StudentImpl student = (StudentImpl) cglib.getInstance(new StudentImpl());
student.action();
}
}

Java静态代理&动态代理&Cglib代理详解的更多相关文章

  1. 静态代理和动态代理(jdk/cglib)详解

    1.静态代理模式 代理模式上,基本上有Subject角色,RealSubject角色,Proxy角色.其中:Subject角色负责定义RealSubject和Proxy角色应该实现的接口:RealSu ...

  2. 转 Java虚拟机5:Java垃圾回收(GC)机制详解

    转 Java虚拟机5:Java垃圾回收(GC)机制详解 Java虚拟机5:Java垃圾回收(GC)机制详解 哪些内存需要回收? 哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无 ...

  3. [ 转载 ] Java开发中的23种设计模式详解(转)

    Java开发中的23种设计模式详解(转)   设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...

  4. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

  5. Java工程师 基础+实战 完整路线图(详解版)

    Java工程师 基础+实战 完整路线图(详解版)   Java 基础 Java 是一门纯粹的面向对象的编程语言,所以除了基础语法之外,必须得弄懂它的 oop 特性:封装.继承.多态.此外还有泛型.反射 ...

  6. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  7. Java进阶(三十二) HttpClient使用详解

    Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们 ...

  8. Java多线程编程中Future模式的详解<转>

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  9. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

  10. Java web 入门知识 及HTTP协议详解

     Java  web  入门知识 及HTTP协议详解 WEB入门 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资 ...

随机推荐

  1. BZOJ3170 [Tjoi2013]松鼠聚会 切比雪夫距离 - 曼哈顿距离 - 前缀和

    BZOJ3170 题意: 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最 ...

  2. 树莓派的Respbian或者ubuntu系统下安装opencv最有效的方法

    第一种方法当然首选和其他安装包相同的方法pip install opencv-python安装失败后果断选择第二种方法,这第二种方法尝试过很多次了,屡试不爽 第二种方法:sudo apt-get in ...

  3. github初学者搭建自己的网站

    如何利用github打造博客专属域名 感谢园友的无私共享-- http://www.cnblogs.com/xuehaoyue/p/6551217.html 选分支 建立好库,在设置 这里选择博客类型 ...

  4. 漫谈JavaScript中的作用域(scope)

    什么是作用域 程序的执行,离不开作用域,也必须在作用域中才能将代码正确的执行. 所以作用域到底是什么,通俗的说,可以这样理解:作用域就是定义变量的位置,是变量和函数的可访问范围,控制着变量和函数的可见 ...

  5. Jmeter 之 逻辑控制器 if 控制器

    最近工作不忙,利用空闲时间整理了下Jmeter的相关知识,下面给大家分享下Jmeter中 如果(if)控制的使用和应用. 如下图:线程组 > 添加 > 逻辑控制器 > 如果 (if) ...

  6. 使用dig/nslookup命令查看dns解析详情

    dig-DNS lookup utility 当域名出现访问故障时,可通过域名解析来判断是否有错误的解析导致的问题. 可以看到有请求段和应答段,最后解析出的A记录有两条 dig命令做迭代查询 dig ...

  7. Git使用(二)版本库创建及文件修改

    一.创建版本库 1.安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功! 安装完成后,还需要最后一步设置,在命令行输入: $ gi ...

  8. 获得本机IP和访问服务的端口号(Java)

    1. //获取本机ip地址 InetAddress addr = InetAddress.getLocalHost(); String ip=addr.getHostAddress().toStrin ...

  9. Java并发笔记——单例与双重检测

    单例模式可以使得一个类只有一个对象实例,能够减少频繁创建对象的时间和空间开销.单线程模式下一个典型的单例模式代码如下: ① class Singleton{ private static Single ...

  10. jps虚拟机进程状态工具

    jps(JVM Process Status Tool) jps工具可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine ...