文档章节

静态代理,JDK动态代理,CGLib动态代理

D_Kim
 D_Kim
发布于 2017/07/27 18:25
字数 515
阅读 6
收藏 0

JAVA三种代理的代码的实现

目标接口示例

public interface Greeting {
void sayHello(String name);
}

目标实现示例

public class GreetingImpl implements Greeting {

    @Override
    public void sayHello(String name) {
        System.out.println("Hello! "+name);
    }
}

静态代理

public class GreetingProxy implements Greeting {
    private GreetingImpl greetingImpl;

    public GreetingProxy(GreetingImpl greetingImpl) {
        this.greetingImpl = greetingImpl;
    }

    @Override
    public void sayHello(String name) {
        before();
        greetingImpl.sayHello(name);
        after();
    }

    private void before() {
        System.out.println("静态代理===》Before");
    }

    private void after() {
        System.out.println("静态代理===》After");
    }
}

客户端调用

public class Client {
    public static void main(String[] args) {
        Greeting greetingProxy = new GreetingProxy(new GreetingImpl());
        greetingProxy.sayHello("Kim");
}

输出

静态代理===》Before
Hello! Kim
静态代理===》After

JDK 动态代理

public class JDKDynamicProxy implements InvocationHandler {

    private Object target;

    public JDKDynamicProxy(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("JDK动态代理===》Before");
    }

    private void after() {
        System.out.println("JDK动态代理===》After");
    }
}

客户端调用

public class Client {
    public static void main(String[] args) {
       Greeting greeting = new JDKDynamicProxy(new GreetingImpl()).getProxy();
        greeting.sayHello("Kim");
}

输出

JDK动态代理===》Before
Hello! Kim
JDK动态代理===》After

CGlib 动态代理

public class CGlibDynamicProxy implements MethodInterceptor {

    //单例模式
    private static CGlibDynamicProxy instance = new CGlibDynamicProxy();

    public static CGlibDynamicProxy getInstance(){
        return instance;
    }

    //限制外界去 new 本类
    private CGlibDynamicProxy() {
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> cls) {
        return (T) Enhancer.create(cls, this);
    }

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        before();
        Object result = methodProxy.invokeSuper(target, args);
        after();
        return result;
    }

    private void before() {
        System.out.println("CGlib动态代理===》Before");
    }

    private void after() {
        System.out.println("CGlib动态代理===》After");
    }
}

客户端调用

public class Client {
    public static void main(String[] args) {
        Greeting greeting = CGlibDynamicProxy.getInstance().getProxy(GreetingImpl.class);
        greeting.sayHello("Kim");
}

输出

CGlib动态代理===》Before
Hello! Kim
CGlib动态代理===》After

JDK动态代理与CGlib动态代理的区别

  1. JDK代理 实现的原理是java的反射机制;CGlib实现的原理是利用ASM(JAVA字节码处理框架)在内存中动态的生成被代理类的子类,因此不能对final修饰的类进行代理。
  2. JDK代理只能代理实现了接口的类,而CGlib则不用.
  3. CGLib 创建代理的速度比较慢,但创建代理后运行的速度却非常快,而JDK 动态代理正好相反。

© 著作权归作者所有

上一篇: 事务相关概念
下一篇: 内部类笔记
D_Kim
粉丝 0
博文 32
码字总数 12302
作品 0
深圳
私信 提问
spring基础知识---AOP动态代理原理

Spring Boot实践——Spring AOP实现之动态代理 Spring AOP 介绍   AOP的介绍可以查看 Spring Boot实践——AOP实现   与AspectJ的静态代理不同,Spring AOP使用的动态代理,所谓的动态代理...

spinachgit
02/21
149
0
Java设计模式综合运用(动态代理+Spring AOP)

AOP设计模式通常运用在日志,校验等业务场景,本文将简单介绍基于Spring的AOP代理模式的运用。 1. 代理模式 1.1 概念 代理(Proxy)是一种提供了对目标对象另外的访问方式,即通过代理对象访问...

landy8530
2018/10/05
0
0
JDK动态代理与Cglib动态代理(转载)

spring容器通过动态代理再结合java反射思想可以使得方法调用更加简洁 一、动态代理概述: 与静态代理对照(关于静态代理的介绍 可以阅读上一篇:JAVA设计模式之 代理模式【Proxy Pattern】(...

思悟修
2015/08/14
622
0
Spring中JDK动态代理和Cglib代理的区别

Spring的AOP基于代理模式,并且它即使用到了JDK动态代理也使用了Cglib代理。 如下代码是springAOP中默认的代理实现类DefaultAopProxyFactory,其中创建代理的方法createAopProxy,在这个方法...

王子城
2018/08/01
1K
0
JDK动态代理和Cglib的动态代理

最简单的是静态代理方法,即代理模式,这里就不多啰嗦了。。 重点说一下JDK的动态代理和Cglib的动态代理吧 先说JDK的,需要被代理的类需要有接口,否则无法实现 package proxy.dynamic; pub...

Eviltuzki
2015/10/29
112
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 我,小小编辑,食人族酋长

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享娃娃的单曲《飘洋过海来看你》: #今日歌曲推荐# 《飘洋过海来看你》- 娃娃 手机党少年们想听歌,请使劲儿戳(这里) @宇辰OSC...

小小编辑
今天
672
10
MongoDB系列-- SpringBoot 中对 MongoDB 的 基本操作

SpringBoot 中对 MongoDB 的 基本操作 Database 库的创建 首先 在MongoDB 操作客户端 Robo 3T 中 创建数据库: 增加用户User: 创建 Collections 集合(类似mysql 中的 表): 后面我们大部分都...

TcWong
今天
38
0
spring cloud

一、从面试题入手 1.1、什么事微服务 1.2、微服务之间如何独立通讯的 1.3、springCloud和Dubbo有哪些区别 1.通信机制:DUbbo基于RPC远程过程调用;微服务cloud基于http restFUL API 1.4、spr...

榴莲黑芝麻糊
今天
25
0
Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
71
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
昨天
69
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部