两种动态代理比较(补充),进程通信方式总结

jdk和CGLib动态代理:

jdk动态代理:

  • java提供的动态代理技术;

  • spring aop默认采用的方式;

  • 只能对实现了至少一个接口的类生成代理对象;

CGLib动态代理:

  • 采用底层字节码技术;

  • 目标对象没有实现接口时采用;

在性能方面,CGLib创建的代理对象比JDK动态代理创建的代理对象高很多。

但是,CGLib在创建代理对象时所花费的时间比JDK动态代理多很多。

所以,对于单例的对象因为无需频繁创建代理对象,采用CGLib动态代理比较合适。

反之,对于多例的对象因为需要频繁的创建代理对象,则JDK动态代理更合适。

CGLib动态代理是在运行时通过创建目标类的子类来生成代理对象的。

CGLib(Code Generation Library)是一个基于类继承的代理库,它通过生成目标类的子类来实现代理。具体步骤如下:

  1. 首先,需要引入CGLib的相关依赖。

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>xxx</version>
</dependency>
  1. 创建一个MethodInterceptor对象,用于拦截目标方法的调用。

public class MyInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // 在目标方法执行前后进行拦截操作
        // ...
        Object result = proxy.invokeSuper(obj, args);
        // ...
        return result;
    }
}
  1. 使用Enhancer类创建代理对象。

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(YourClass.class);
enhancer.setCallback(new MyInterceptor());
YourClass proxy = (YourClass) enhancer.create();

在上述代码中,YourClass是目标类,MyInterceptor是自定义的拦截器。通过Enhancer类的setSuperclass()方法设置目标类,setCallback()方法设置拦截器,最后通过create()方法创建代理对象。

  1. 使用代理对象进行方法调用。

proxy.yourMethod();

在运行时,CGLib会动态生成目标类的子类,并重写目标类中的方法。当调用代理对象的方法时,实际上是调用了子类中重写的方法,然后在拦截器中进行拦截操作。

总结来说,CGLib动态代理是在运行时创建子类代理的实例,通过继承目标类来生成代理对象,并在拦截器中进行方法拦截和增强。相比于JDK动态代理,CGLib能够代理非接口类,但代理过程中需要创建子类,可能会对性能产生一定影响。

JDK动态代理是在运行时通过创建接口的代理类来生成代理对象的。

JDK动态代理是通过Proxy类和InvocationHandler接口来实现的。具体步骤如下:

  1. 创建一个实现InvocationHandler接口的类,用于拦截目标方法的调用。

public class MyInvocationHandler implements InvocationHandler {
    private Object target;
​
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
​
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 在目标方法执行前后进行拦截操作
        // ...
        Object result = method.invoke(target, args);
        // ...
        return result;
    }
}
  1. 使用Proxy类创建代理对象。

YourInterface proxy = (YourInterface) Proxy.newProxyInstance(
        YourInterface.class.getClassLoader(),
        new Class[]{YourInterface.class},
        new MyInvocationHandler(target)
);

在上述代码中,YourInterface是目标接口,MyInvocationHandler是自定义的拦截器。通过Proxy类的newProxyInstance()方法创建代理对象,需要传入目标接口的类加载器、目标接口数组和拦截器对象。

  1. 使用代理对象进行方法调用。

proxy.yourMethod();

在运行时,JDK动态代理会动态生成一个实现了目标接口的代理类,并在代理类中重写了目标接口中的方法。当调用代理对象的方法时,实际上是调用了代理类中重写的方法,然后在拦截器中进行拦截操作。

总结来说,JDK动态代理是在运行时创建接口的代理实例,通过实现目标接口的代理类来生成代理对象,并在拦截器中进行方法拦截和增强。相比于CGLib动态代理,JDK动态代理只能代理接口,但代理过程中无需创建子类,相对更轻量级。

invoke()`方法

invoke()方法是在InvocationHandler接口中定义的方法,用于拦截目标方法的调用并进行自定义的操作。

Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
  • proxy:代理对象,即生成的代理类的实例。

  • method:被调用的目标方法。

  • args:方法的参数。

invoke()方法中,可以在目标方法执行前后进行拦截操作,例如记录日志、权限验证、性能监控等。在方法执行前可以进行一些预处理,如参数校验、权限检查等;在方法执行后可以进行一些后处理,如结果处理、日志记录等。

invoke()方法中,需要通过反射调用目标方法,并将结果返回。可以使用method.invoke(target, args)来调用目标方法,其中target是目标对象,args是方法的参数。

在拦截操作完成后,invoke()方法返回目标方法的执行结果。可以对结果进行一些处理,或者直接返回原始结果。

总结来说,invoke()方法是在拦截器中实现的,用于拦截目标方法的调用,并在拦截器中进行自定义的操作。通过反射调用目标方法,并返回执行结果。

进程通信是指不同进程之间进行数据交换和共享的方式。常见的进程通信方式包括:

  1. 管道(Pipe):管道是一种半双工的通信方式,它可以在父进程和子进程之间传递数据。管道可以是匿名的,也可以是有名字的。

  2. 命名管道(Named Pipe):命名管道是一种有名字的管道,可以用于不相关的进程之间进行通信。

  3. 信号(Signal):信号是一种异步通信方式,用于通知进程发生了某个事件。进程可以捕捉信号并执行相应的处理程序。

  4. 消息队列(Message Queue):消息队列是一种存储在内核中的消息缓冲区,进程可以通过消息队列进行数据交换。

  5. 共享内存(Shared Memory):共享内存是一种高效的进程通信方式,多个进程可以访问同一块物理内存,从而实现数据共享。

  6. 信号量(Semaphore):信号量是一种同步机制,用于控制多个进程对共享资源的访问。

  7. 套接字(Socket):套接字是一种网络通信方式,可以在不同主机上的进程之间进行通信。

  8. 文件(File):进程可以通过读写文件来进行通信,其中一个进程将数据写入文件,另一个进程读取文件中的数据。

选择适当的进程通信方式取决于具体的需求和场景。不同的通信方式具有不同的特点和适用范围。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值