【编程进阶知识】静态代理、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();*/
    }
}
目录
相关文章
|
6天前
|
安全 Java 编译器
JDK 10中的局部变量类型推断:Java编程的简化与革新
JDK 10引入的局部变量类型推断通过`var`关键字简化了代码编写,提高了可读性。编译器根据初始化表达式自动推断变量类型,减少了冗长的类型声明。虽然带来了诸多优点,但也有一些限制,如只能用于局部变量声明,并需立即初始化。这一特性使Java更接近动态类型语言,增强了灵活性和易用性。
87 53
|
19天前
|
设计模式 Java API
[Java]静态代理与动态代理(基于JDK1.8)
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
15 0
[Java]静态代理与动态代理(基于JDK1.8)
|
29天前
|
Java 关系型数据库 MySQL
【编程基础知识】Eclipse连接MySQL 8.0时的JDK版本和驱动问题全解析
本文详细解析了在使用Eclipse连接MySQL 8.0时常见的JDK版本不兼容、驱动类错误和时区设置问题,并提供了清晰的解决方案。通过正确配置JDK版本、选择合适的驱动类和设置时区,确保Java应用能够顺利连接MySQL 8.0。
120 1
|
1月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
24 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程序能够顺利编译和运行。
34 1
|
2月前
|
Java
安装JDK18没有JRE环境的解决办法
安装JDK18没有JRE环境的解决办法
293 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
|
1天前
|
Ubuntu Java
Ubuntu之jdk安装
以下是Ubuntu之jdk安装的详细内容
|
1月前
|
Oracle Java 关系型数据库
jdk17安装全方位手把手安装教程 / 已有jdk8了,安装JDK17后如何配置环境变量 / 多个不同版本的JDK,如何配置环境变量?
本文提供了详细的JDK 17安装教程,包括下载、安装、配置环境变量的步骤,并解释了在已有其他版本JDK的情况下如何管理多个JDK环境。
578 0