【编程进阶知识】静态代理、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();*/
    }
}
目录
相关文章
|
20天前
|
设计模式 Java API
[Java]静态代理与动态代理(基于JDK1.8)
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
15 0
[Java]静态代理与动态代理(基于JDK1.8)
|
1月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
24 1
|
2月前
|
存储 Java 开发者
【Java新纪元启航】JDK 22:解锁未命名变量与模式,让代码更简洁,思维更自由!
【9月更文挑战第7天】JDK 22带来的未命名变量与模式匹配的结合,是Java编程语言发展历程中的一个重要里程碑。它不仅简化了代码,提高了开发效率,更重要的是,它激发了我们对Java编程的新思考,让我们有机会以更加自由、更加创造性的方式解决问题。随着Java生态系统的不断演进,我们有理由相信,未来的Java将更加灵活、更加强大,为开发者们提供更加广阔的舞台。让我们携手并进,共同迎接Java新纪元的到来!
62 11
|
2月前
|
监控 Java 开发者
【并发编程的终极简化】JDK 22结构化并发:让并发编程变得像写代码一样简单!
【9月更文挑战第8天】随着JDK 22的发布,结构化并发为Java编程带来了全新的并发编程体验。它不仅简化了并发编程的复杂性,提高了程序的可靠性和可观察性,还为开发者们提供了更加高效、简单的并发编程方式。我们相信,在未来的发展中,结构化并发将成为Java并发编程的主流方式之一,推动Java编程语言的进一步发展。让我们共同期待Java在并发编程领域的更多创新和突破!
|
2月前
|
IDE Java 数据处理
【字符串构建的全新时代】JDK 22字符串模板:让字符串操作如行云流水,代码更流畅!
【9月更文挑战第8天】虽然目前JDK 22的确切内容尚未公布,但我们可以根据Java语言的演进趋势和社区的需求,构想出一种可能在未来版本中引入的字符串模板机制。这种机制有望为Java的字符串操作带来革命性的变化,让代码编写如行云流水般流畅。我们期待Java语言能够不断进化,为开发者们提供更加高效、便捷和强大的编程工具。
|
3月前
|
开发者 C# 容器
【独家揭秘】当WPF邂逅DirectX:看这两个技术如何联手打造令人惊艳的高性能图形渲染体验,从环境搭建到代码实践,一步步教你成为图形编程高手
【8月更文挑战第31天】本文通过代码示例详细介绍了如何在WPF应用中集成DirectX以实现高性能图形渲染。首先创建WPF项目并使用SharpDX作为桥梁,然后在XAML中定义承载DirectX内容的容器。接着,通过C#代码初始化DirectX环境,设置渲染逻辑,并在WPF窗口中绘制图形。此方法适用于从简单2D到复杂3D场景的各种图形处理需求,为WPF开发者提供了高性能图形渲染的技术支持和实践指导。
208 0
|
2月前
|
Java
安装JDK18没有JRE环境的解决办法
安装JDK18没有JRE环境的解决办法
297 3
|
3月前
|
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应用打下基础。
57 1
|
3月前
|
Oracle Java 关系型数据库
Mac安装JDK1.8
Mac安装JDK1.8
685 4
|
2天前
|
Ubuntu Java
Ubuntu之jdk安装
以下是Ubuntu之jdk安装的详细内容
10 0