《Java知识应用》Java CGLib动态代理使用和原理说明

一、CGLib jar包下载

百度网盘:

链接:https://pan.baidu.com/s/1O_5o_vtPWEZ3Hy0CHlZDug
提取码:5wf6

CGLib要使用还需要额外的asm.jar

链接:https://pan.baidu.com/s/1874lFlpOLsdzPUs7O9Ol-g
提取码:wf68

二、CGLib应用案例

package demo.knowledgepoints.cglib;

public class BaseDemo {

    private String Name;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    @Override
    public String toString() {
        return "BaseDemo{" +
                "Name=‘" + Name + ‘\‘‘ +
                ‘}‘;
    }
}
package demo.knowledgepoints.cglib;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("=============执行自己想要的内容start================");
        System.out.println("method.getName():" + method.getName());
        Object object = methodProxy.invokeSuper(o,objects);
        System.out.println("=============执行自己想要的内容end================");
        return object;
    }
}
package demo.knowledgepoints.cglib;

import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;

public class CGLibTest {

    public static void main(String[] args) {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "src\\demo\\knowledgepoints\\cglib");

        /**
         * 该类为CGLib设置动态代理的核心,你设置一个怎么样的动态代理
         */
        Enhancer enhancer = new Enhancer();
        /*******设置需要被代理的类**************/
        enhancer.setSuperclass(BaseDemo.class);
        /*******设置代理类**************/
        enhancer.setCallback(new MyMethodInterceptor());
        /*******创建代理类**************/
        BaseDemo proxyBaseDemo = (BaseDemo)enhancer.create();

        proxyBaseDemo.setName("李磊");

    }
}

运行结果:

这里会出现一个比较有意思的情况,如果是dubug运行会出现如下打印信息

简单解释一下:因为IDEA duebug下,你会需要查询信息,而这些信息其实就是IDEA默认在调用你对象的toString方法。IDEA执行的toString当然也被代理了。

三、CGLib动态代理原理

CGLib动态代理原理和JDK动态原理本质区别很大。

CGLib动态代理原理:是通过子类继承来实现动态代理的。上面的应用程序我们已经将CGLib的代理类生成到本地:

我们可以看看反编译后里面的代码。

public class BaseDemo$$EnhancerByCGLIB$$3c73e677 extends BaseDemo implements Factory{
    final String CGLIB$toString$0() {
        return super.toString();
    }

    public final String toString() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$0$Method, CGLIB$emptyArgs, CGLIB$toString$0$Proxy) : super.toString();
    }

    final String CGLIB$getName$1() {
        return super.getName();
    }

    public final String getName() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$getName$1$Method, CGLIB$emptyArgs, CGLIB$getName$1$Proxy) : super.getName();
    }

    final void CGLIB$setName$2(String var1) {
        super.setName(var1);
    }

    public final void setName(String var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$setName$2$Method, new Object[]{var1}, CGLIB$setName$2$Proxy);
        } else {
            super.setName(var1);
        }
    }
}

上述代码是我取了其中比较重要的信息,真实代理类,还会多一些代码。

从上面的文件内容可以看出:

1. 继承了BaseDemo

2. 实现Factory 接口,该接口可以创建对象等功能。

3. 重写了父类方法,并且还是会调用原父类方法。

更多使用方法见CGLib API :http://devdoc.net/javamisc/cglib-3.2.5/

原文地址:https://www.cnblogs.com/jssj/p/12635206.html

时间: 2024-10-09 22:54:49

《Java知识应用》Java CGLib动态代理使用和原理说明的相关文章

jdk动态代理和cglib动态代理底层实现原理详细解析(cglib动态代理篇)

代理模式是一种很常见的模式,关于底层原理网上看到很多的有关的讲解,但看了一些都觉得比较粗略,很多时候把底层代码copy下来也不大讲解,感觉不如自己详细的写上一篇.本文将以非常详细的说明来分析cglib动态代理底层的实现原理,篇幅较长,但是每个核心方法代码中每步都有说明.还请耐心阅读 1. 举例 使用cglib代理需要引入两个包,maven的话包引入如下 <!-- https://mvnrepository.com/artifact/cglib/cglib --> <dependency&

jdk动态代理和cglib动态代理底层实现原理超详细解析(jdk动态代理篇)

代理模式是一种很常见的模式,关于底层原理网上看到很多的有关的讲解,但看了一些都觉得比较粗略,很多时候把底层代码copy下来也不大讲解,感觉不如自己详细的写上一篇.本文将以非常详细的说明来分析jdk动态代理底层的实现原理,篇幅较长,但是每个核心方法代码中每步都有说明.还请耐心阅读 1.举例 public class ProxyFactory implements InvocationHandler { private Class target; public <T>T getProxy(Clas

spring aop原理 JDK动态代理和CGLIB动态代理

Spring的两大特性是IOC和AOPIOC负责将对象动态的注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果.理解spring的ioc也很重要.但是今天主要来和大家讲讲aop.AOP 广泛应用于处理一些具有横切性质的系统级服务,AOP 的出现是对 OOP 的良好补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理.日志.缓存等等. AOP实现的关键在于AOP框架自动创建的AOP代理.AOP代理主要分为静态代理和动态代理, 静态代理的代表为AspectJ:动态代理则

Java进阶之 JDK动态代理与Cglib动态代理

一.动态代理概述: 与静态代理对照(关于静态代理的介绍 可以阅读上一篇:JAVA设计模式之 代理模式[Proxy Pattern]), 动态代理类的字节码是在程序运行时由Java反射机制动态生成. 注意: 1.AspectJ是采用编译时生成AOP代理类,具有更好的性能,但是需要使用特定的编译器进行处理 2.Spring AOP采用运行时生成AOP代理类,无需使用特定编译器进行处理,但是性能相对于AspectJ较差 二.JDK动态代理 [对有实现接口的对象做代理] 1.JDK动态代理中 需要了解的

java动态代理和cglib动态代理

动态代理应用广泛,Spring,Struts等框架很多功能是通过动态代理,或者进一步封装来实现的. 常见的动态代理模式实现有Java API提供的动态代理和第三方开源类库CGLIB动态代理. Java API提供的动态代理是基于类反射实现的,用到的类有: java.lang.reflect.InvocationHandler; java.lang.reflect.Method; java.lang.reflect.Proxy; 其实现是通过Proxy类的newProxyInstance()方法产

Java学习之:JDK动态代理与CGLIB动态代理

代理的概念:简单的理解就是通过为某一个对象创建一个代理对象,我们不直接引用原本的对象,而是由创建的代理对象来控制对原对象的引用. 动态代理:是指在程序运行时由Java反射机制动态生成,无需手动编写代码.动态代理不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类. 代理原理:代理对象内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象.同时,代理对象可以在执行真实对象操作时,附加其他的操作

代理模式 &amp; Java原生动态代理技术 &amp; CGLib动态代理技术

第一部分.代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务.(其实就是在代理类中关联一个委托类的实例,然后在代理类中进行包装). UML图如下: 第二部分.在Java中实现代理模式  按照代理的创建时期,代理类可以分

java 静态代理 JDK动态代理 Cglib动态代理

下面以一个简单的银行账户为例讲述讲述动态代理. 设计一个银行账户类,包含用户的账户余额,实现查询和更新余额功能 这个系统用了一段时间,有客户要求对账说账户余额给弄错了?因为上面没有存取款记录,最后银行不认账,客户收到了损失.银行为了避免这种现象再次发生,决定对这个系统进行修改,但是因为bankAccount太过复杂,希望在不修改bankAccount的情况下,增加日志功能. 静态代理 使用静态代理解决上面的问题. 银行要求所有模块都需要添加日志功能,这对苦逼的程序员来说真的是一个不小的工作量啊,

[z]Java代理(jdk静态代理、动态代理和cglib动态代理)

一.代理是Java常用的设计模式,代理类通过调用被代理类的相关方法,并对相关方法进行增强.加入一些非业务性代码,比如事务.日志.报警发邮件等操作. 二.jdk静态代理 1.业务接口 1 2 3 4 5 6 7 8 9 10 11 12 13 /**  * 业务接口  * @author pc  *  */ public interface UserService {          // 增加一个用户     public void addUser();     // 编辑账户     pub