【编程进阶知识】静态代理、JDK动态代理及Cglib动态代理各自存在的缺点及代码示例

简介: 本文介绍了三种Java代理模式:静态代理、JDK动态代理和Cglib动态代理。静态代理针对特定接口或对象,需手动编码实现;JDK动态代理通过反射机制实现,适用于所有接口;Cglib动态代理则基于字节码技术,无需接口支持,但需引入外部库。每种方法各有优缺点,选择时应根据具体需求考虑。

本文介绍了三种Java代理模式:静态代理、JDK动态代理和Cglib动态代理。静态代理针对特定接口或对象,需手动编码实现;JDK动态代理通过反射机制实现,适用于所有接口;Cglib动态代理则基于字节码技术,无需接口支持,但需引入外部库。每种方法各有优缺点,选择时应根据具体需求考虑。

1.⭐⭐⭐静态代理🌙🌙🌙

  • 基本描述:静态代理代理的是某一个接口的实例对象,以接口的形式对外展示。当然如果不需要以接口的形式对外展示,直接代理对象即可。
  • 缺点:只能代理某一种类型,要想代理其他类型,需要修改代码。
package unittest.proxy;
interface StaticInterface{
   
    void method();
}
class Target implements StaticInterface{
   
    @Override
    public void method() {
   
        System.out.println("StaticInterface");
    }
}
/**
 * @author Dylaniou
 * 基本描述:静态代理代理的是某一个接口的实例对象,以接口的形式对外展示。当然如果不需要以接口的形式对外展示,直接代理对象即可。
 * 缺点:只能代理某一种类型,要想代理其他类型,需要修改代码。
 */
public class JdkStaticProxy implements StaticInterface{
   
    Target target;
    JdkStaticProxy(Target target){
   
        this.target = target;
    }
    @Override
    public void method() {
   
        System.out.println("before");
        target.method();
        System.out.println("after");
    }
    public static void main(String[] args) {
   
        StaticInterface staticInterface = (StaticInterface)(new JdkStaticProxy(new Target()));
        staticInterface.method();
    }
}

2.⭐⭐⭐JDK动态代理🌙🌙🌙

  • 基本描述:jdk动态代理可以代理的接口的实例对象,以接口的形式对外展示。不局限于某个类型。
    • 缺点:必须要有接口。
package unittest.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface DynamicInterface{
   
    void method();
}
class DynamicProxyInterfaceImp implements DynamicInterface{
   
    @Override
    public void method() {
   
        System.out.println("DynamicProxyInterfaceImp");
    }
}
/**
 * @author Dylaniou
 * 基本描述:jdk动态代理可以代理的接口的实例对象,以接口的形式对外展示。不局限于某个类型。
 * 缺点:必须要有接口。
 */
public class JdkDynamicProxy implements InvocationHandler{
   
    Object target;
    JdkDynamicProxy(Object target){
   
        this.target = target;
    }

    public Object getProxyOfTarget(){
   
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
        System.out.println("before");
        method.invoke(target, args);
        System.out.println("after");
        return null;
    }
    public static void main(String[] args) {
   
        DynamicProxyInterfaceImp target = new DynamicProxyInterfaceImp();
        DynamicInterface dynamicInterface = (DynamicInterface)(new JdkDynamicProxy(target)).getProxyOfTarget();
        dynamicInterface.method();
    }
}

3.⭐⭐⭐Cglib动态代理🌙🌙🌙

  • 基本描述:Cglib动态代理可以直接代理实例对象,不是必须要接口。当然想以接口的形式对外展示也是完全OK的。
  • 缺点:Cglib动态代理需要依赖第三方jar包,比如我本地用的就是mybatis-3.5.4里的cglib-3.3.0.jar和asm-7.1.jar。
package unittest.proxy;

import java.lang.reflect.Method;

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

class CglibInstance{
   
    void method(){
   
        System.out.println("CglibInstance");
    };
}
/**
 * @author Dylaniou
 * 基本描述:Cglib动态代理可以直接代理实例对象,不是必须要接口。当然想以接口的形式对外展示也是完全OK的。
 */
//public class CglibProxy{
   
public class CglibProxy implements MethodInterceptor{
   
    public Object getProxyOfTarget(Class cls){
   
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
   
        System.out.println("before");
         methodProxy.invokeSuper(proxy, args);
        System.out.println("after");
        return null;
    }
    public static void main(String[] args) {
   
        CglibInstance cglibInterface  = (CglibInstance)(new CglibProxy().getProxyOfTarget(CglibInstance.class));
        cglibInterface.method();
        /*Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(CglibInstance.class);
        enhancer.setCallback(new MethodInterceptor(){
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println("before");
                Object result = methodProxy.invokeSuper(proxy, args);
                System.out.println("after");
                return result;
            }
        });
        ((CglibInstance) enhancer.create()).method();*/
    }
}
目录
相关文章
|
1天前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
7 1
|
1天前
|
开发框架 Oracle Java
【编程基础知识】《Java 世界探秘:JRE、JDK 与 JDK 版本全解析》
JRE(Java Runtime Environment)是运行Java程序所需的环境,包含JVM和Java核心类库,适合普通用户使用。JDK(Java Development Kit)则是Java开发工具包,不仅包含JRE,还提供了编译器、调试器等开发工具,适用于开发者。两者的主要区别在于JDK用于开发,而JRE仅用于运行Java程序。JDK各版本不断引入新特性,如Java 8中的Lambda表达式和默认方法等。环境配置方面,Windows和Linux系统都有详细的步骤,确保Java程序能够顺利编译和运行。
7 1
|
1月前
|
存储 Java 开发者
【Java新纪元启航】JDK 22:解锁未命名变量与模式,让代码更简洁,思维更自由!
【9月更文挑战第7天】JDK 22带来的未命名变量与模式匹配的结合,是Java编程语言发展历程中的一个重要里程碑。它不仅简化了代码,提高了开发效率,更重要的是,它激发了我们对Java编程的新思考,让我们有机会以更加自由、更加创造性的方式解决问题。随着Java生态系统的不断演进,我们有理由相信,未来的Java将更加灵活、更加强大,为开发者们提供更加广阔的舞台。让我们携手并进,共同迎接Java新纪元的到来!
51 11
|
1月前
|
监控 Java 开发者
【并发编程的终极简化】JDK 22结构化并发:让并发编程变得像写代码一样简单!
【9月更文挑战第8天】随着JDK 22的发布,结构化并发为Java编程带来了全新的并发编程体验。它不仅简化了并发编程的复杂性,提高了程序的可靠性和可观察性,还为开发者们提供了更加高效、简单的并发编程方式。我们相信,在未来的发展中,结构化并发将成为Java并发编程的主流方式之一,推动Java编程语言的进一步发展。让我们共同期待Java在并发编程领域的更多创新和突破!
|
1月前
|
Java 开发者
【Java编程新纪元】JDK 22:超级构造函数来袭,super(...) 前导语句改写编程规则!
【9月更文挑战第6天】JDK 22的超级构造函数特性是Java编程语言发展史上的一个重要里程碑。它不仅简化了代码编写,还提升了代码的可读性和维护性。我们有理由相信,在未来的Java版本中,还将有更多令人兴奋的新特性等待我们去发现和应用。让我们共同期待Java编程新纪元的到来!
|
1月前
|
Oracle Java 关系型数据库
【颠覆性升级】JDK 22:超级构造器与区域锁,重塑Java编程的两大基石!
【9月更文挑战第6天】JDK 22的发布标志着Java编程语言在性能和灵活性方面迈出了重要的一步。超级构造器和区域锁这两大基石的引入,不仅简化了代码设计,提高了开发效率,还优化了垃圾收集器的性能,降低了应用延迟。这些改进不仅展示了Oracle在Java生态系统中的持续改进和创新精神,也为广大Java开发者提供了更多的可能性和便利。我们有理由相信,在未来的Java编程中,这些新特性将发挥越来越重要的作用,推动Java技术不断向前发展。
|
1月前
|
IDE Java 数据处理
【字符串构建的全新时代】JDK 22字符串模板:让字符串操作如行云流水,代码更流畅!
【9月更文挑战第8天】虽然目前JDK 22的确切内容尚未公布,但我们可以根据Java语言的演进趋势和社区的需求,构想出一种可能在未来版本中引入的字符串模板机制。这种机制有望为Java的字符串操作带来革命性的变化,让代码编写如行云流水般流畅。我们期待Java语言能够不断进化,为开发者们提供更加高效、便捷和强大的编程工具。
|
2月前
|
开发者 C# 容器
【独家揭秘】当WPF邂逅DirectX:看这两个技术如何联手打造令人惊艳的高性能图形渲染体验,从环境搭建到代码实践,一步步教你成为图形编程高手
【8月更文挑战第31天】本文通过代码示例详细介绍了如何在WPF应用中集成DirectX以实现高性能图形渲染。首先创建WPF项目并使用SharpDX作为桥梁,然后在XAML中定义承载DirectX内容的容器。接着,通过C#代码初始化DirectX环境,设置渲染逻辑,并在WPF窗口中绘制图形。此方法适用于从简单2D到复杂3D场景的各种图形处理需求,为WPF开发者提供了高性能图形渲染的技术支持和实践指导。
124 0
|
1月前
|
Java
安装JDK18没有JRE环境的解决办法
安装JDK18没有JRE环境的解决办法
165 3
|
2月前
|
Java 关系型数据库 MySQL
"解锁Java Web传奇之旅:从JDK1.8到Tomcat,再到MariaDB,一场跨越数据库的冒险安装盛宴,挑战你的技术极限!"
【8月更文挑战第19天】在Linux上搭建Java Web应用环境,需安装JDK 1.8、Tomcat及MariaDB。本指南详述了使用apt-get安装OpenJDK 1.8的方法,并验证其版本。接着下载与解压Tomcat至`/usr/local/`目录,并启动服务。最后,通过apt-get安装MariaDB,设置基本安全配置。完成这些步骤后,即可验证各组件的状态,为部署Java Web应用打下基础。
48 1