Java之jdk和CGLib实现动态代理

简介: Java之jdk和CGLib实现动态代理

1 jdk实现动态代理源码实现

这里需要用到InvocationHandler接口

public interface Hello {
    public void sayHello();
}
public class HelloImpl implements Hello {
    @Override
    public void sayHello() {
        System.out.println("hello word");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HelloInvocationHandler implements InvocationHandler{
    private Object object;
    PeopleInvocationHandler(Object object){
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("-------- start ---------");
        Object invoke = method.invoke(people, args);
        System.out.println("-------- end ---------");
        return invoke;
    }
}
import java.lang.reflect.Proxy;
public class Test {
    public static void main(String[] args) {
        HelloImpl hello = new HelloImpl();
        HelloInvocationHandler invocationHandler = new HelloInvocationHandler(hello);
        Hello proxy = (Hello) Proxy.newProxyInstance(HelloImpl.getClass().getClassLoader(), HelloImpl.getClass().getInterfaces(), invocationHandler);
        proxy.sayHello();
    }
}

2 CGLib实现动态代理源码实现

这里需要用到MethodInterceptor接口和Enhancer

public class Hello {
    public Hello() {
        System.out.println("Hello...");
    }
    public void print() {
        System.out.println("hello word");
    }
}


public class CglibProxyIntercepter implements MethodInterceptor {
    @Override
    public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //对目标方法进行拦截处理 
        System.out.println("before...");
        Object object = methodProxy.invokeSuper(sub, objects);
        System.out.println("after...");
        return object;
    }
}
public class CglibProxyIntercepter implements MethodInterceptor {
    @Override
    public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //对目标方法进行拦截处理 
        System.out.println("before...");
        Object object = methodProxy.invokeSuper(sub, objects);
        System.out.println("after...");
        return object;
    }
}
public class Test {
    public static void main(String[] args) {
        //创建加强器,用来创建动态代理类
        Enhancer enhancer = new Enhancer();
        //为加强器指定要代理的业务类
        enhancer.setSuperclass(Hello.class);
        //设置回调
        enhancer.setCallback(new CglibProxyIntercepter());
        //创建代理对象
        Hello proxy= (Hello) enhancer.create();
        proxy.print();
    } 
}

result

before...
hello word
after...


3 对比jdk实现动态代理CGLib实现动态代理

1)、JDK

内部主要是通过反射来实现。


2)、CGLib

CGLib是依靠asm字节码处理框架实现的高性能Code生成类库,可以在运行时扩展Java类或者实现接口?当然可以,CGLib对用户隐藏了asm复杂的内部实现,提供了Developer友好、面向特定功能的实现,比如方法拦截(Interpreter)、懒加载(Lazyloader & Dispatcher)等,AOP中的方法拦截,Hibernate中的延迟加载都利用了CGLib


特点:可以不通过接口实现动态代理的优点之外,还有处理速度快、效率高的优点!因为生成代码比Java反射的速度要快很多.


相关文章
|
2月前
|
Java Linux
java基础(3)安装好JDK后使用javac.exe编译java文件、java.exe运行编译好的类
本文介绍了如何在安装JDK后使用`javac.exe`编译Java文件,以及使用`java.exe`运行编译好的类文件。涵盖了JDK的安装、环境变量配置、编写Java程序、使用命令行编译和运行程序的步骤,并提供了解决中文乱码的方法。
60 2
|
9天前
|
安全 Java 编译器
JDK 10中的局部变量类型推断:Java编程的简化与革新
JDK 10引入的局部变量类型推断通过`var`关键字简化了代码编写,提高了可读性。编译器根据初始化表达式自动推断变量类型,减少了冗长的类型声明。虽然带来了诸多优点,但也有一些限制,如只能用于局部变量声明,并需立即初始化。这一特性使Java更接近动态类型语言,增强了灵活性和易用性。
91 53
|
22天前
|
设计模式 Java API
[Java]静态代理与动态代理(基于JDK1.8)
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
18 0
[Java]静态代理与动态代理(基于JDK1.8)
|
1月前
|
Java
【编程进阶知识】静态代理、JDK动态代理及Cglib动态代理各自存在的缺点及代码示例
本文介绍了三种Java代理模式:静态代理、JDK动态代理和Cglib动态代理。静态代理针对特定接口或对象,需手动编码实现;JDK动态代理通过反射机制实现,适用于所有接口;Cglib动态代理则基于字节码技术,无需接口支持,但需引入外部库。每种方法各有优缺点,选择时应根据具体需求考虑。
20 1
|
1月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
25 1
|
1月前
|
Java
深入理解Java动态代理
深入理解Java动态代理
19 1
|
26天前
|
Java
Java代码解释静态代理和动态代理的区别
### 静态代理与动态代理简介 **静态代理**:代理类在编译时已确定,目标对象和代理对象都实现同一接口。代理类包含对目标对象的引用,并在调用方法时添加额外操作。 **动态代理**:利用Java反射机制在运行时生成代理类,更加灵活。通过`Proxy`类和`InvocationHandler`接口实现,无需提前知道接口的具体实现细节。 示例代码展示了两种代理方式的实现,静态代理需要手动创建代理对象,而动态代理通过反射机制自动创建。
|
2月前
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
|
1月前
|
设计模式 缓存 Java
从源码学习Java动态代理|8月更文挑战
从源码学习Java动态代理|8月更文挑战
|
2月前
|
安全 Java API
【性能与安全的双重飞跃】JDK 22外部函数与内存API:JNI的继任者,引领Java新潮流!
【9月更文挑战第7天】JDK 22外部函数与内存API的发布,标志着Java在性能与安全性方面实现了双重飞跃。作为JNI的继任者,这一新特性不仅简化了Java与本地代码的交互过程,还提升了程序的性能和安全性。我们有理由相信,在外部函数与内存API的引领下,Java将开启一个全新的编程时代,为开发者们带来更加高效、更加安全的编程体验。让我们共同期待Java在未来的辉煌成就!
65 11