Java之代理

  代理通常有两种代理方式,一种是动态代理,一种是静态代理,动态代理一般有两种实现方式,一种是通过JDK自身实现代理,还有一种就是通过开源库cglib实现代理。

  1.静态代理

    静态代理需要三个类,一个接口类,一个接口实现类,还有一个是接口的代理类,下面与一个例子
    接口类如下,就写一个需要代理的接口方法。
    
public interface A {
    
    void something();
    
}
   接口的实现类
public class ImplementA implements A {

    @Override
    public void something() {
        System.out.println("do something");
    }
}
   接口的代理类
public class ProxyA implements A {

    private A a;

    public ProxyA(A a){
        this.a = a;
    }

    @Override
    public void something() {
        before();
        a.something();
        after();
    }

    private void before(){
        System.out.println("before do something");
    }

    private void after(){
        System.out.println("after do something");
    }
}
  接口的代理类添加了一些在代理之前和之后的方法,来模仿代理的一个作用(验证等)
  最后是一个测试类
public class Test {

    public static void main(String[] args){
        A a = new ImplementA();
        ProxyA proxyA = new ProxyA(a);
        proxyA.something();
    }
}
   测试结果

   静态代理的优缺点:
   优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。 
   缺点: 
      1)代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。 
      2)如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。 

2.动态代理(JDK)

  静态代理的优缺点非常明显,为了解决静态代理的缺点,所有我们使用动态代理,动态代理有两种,第一种就是JDK代理,第二种是cglib代理,我们先来看JDK代理,下面来举一个例子。
   和静态代理一样需要一个接口类
public interface A {
    
    void something();
    
}
  一个接口的实现类
public class ImplementA implements A {

    @Override
    public void something() {
        System.out.println("do something");
    }
}
   代理类
package proxy;

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

/**
 * Created by Jackie on 2017/7/23.
 * JDK 动态代理
 */
public class JDKProxy implements InvocationHandler {

    private Object target;

    public JDKProxy(Object target){
        this.target = target;
    }


    public Object bind(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces() , this);
    }
    /**
     *
     * @param proxy  需要代理的实现类
     * @param method 调用的方法
     * @param args   调用的方法需要的参数
     * @return result
     * @throws Throwable 异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        if (method.getName().equals("something")){
            before();
            result = method.invoke(target , args);
            after();
            return result;
        }
        return null;
    }

    private void before(){
        System.out.println("before do something");
    }

    private void after(){
        System.out.println("after do something");
    }
}
  通过bind获取接口实现的代理类,注意是接口的实现代理类,这也是JDK代理的一个缺点,只能代理接口的实现类,这时候就需要cglib的代理。

3.cglib代理

   JDK动态代理只能代理接口的实现类,但是cglib能代理不是接口的实现类,下面举一个例子
   我们还是需要一个接口
public interface A {
    
    void something();
    
}
  一个被代理对象
/**
 * Created by Jackie on 2017/7/23.
 * 并没有实现接口
 */
public class CglibAImpl  {

    public void something(){
        System.out.println("do something");
    }
}
   使用cglib代理
package proxy;

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

import java.lang.reflect.Method;

/**
 * Created by Jackie on 2017/7/23.
 *
 */
public class CglibProxy implements MethodInterceptor {

    private Object target;

    public CglibProxy(Object target){
        this.target = target;
    }

    public Object bind(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = null;
        if (method.getName().equals("something")){
            before();
            result = methodProxy.invokeSuper(o , objects);
            after();
        }
        return result;
    }

    private void before(){
        System.out.println("before do something");
    }

    private void after(){
        System.out.println("after do something");
    }
}
  测试类
package proxy;

/**
 * Created by Jackie on 2017/7/23.
 *
 */
public class CglibProxyTest {

    public static void main(String[] args){
        CglibProxy cglibProxy = new CglibProxy(new CglibAImpl());
        CglibAImpl cglibA = (CglibAImpl) cglibProxy.bind();
        cglibA.something();
    }
}
   测试结果

   JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。 

【源码免费下载链接】:https://renmaiwang.cn/s/rpwet 在进行科学计算和数据分析时,使用Python中的Numpy库是必不可少的。Numpy库提供了高性能的多维数组对象和用于处理这些数组的工具,而数组和矩阵是Numpy中两个非常重要的概念。数组(array)是一个通用于各种数值运算的同质数据结构,而矩阵(matrix)则是一种特定的二维数组,用于更专业的数学运算。在使用过程中,我们可能需要在数组和矩阵之间进行转换。本文将详细介绍如何在Numpy中进行这两种类型之间的转换,并通过实例代码进行说明。我们来了解一下什么是Numpy中的数组和矩阵。Numpy中的数组(ndarray)是一种多维的数组对象,它可以处理数值计算中的各种数据类型,包括整数、浮点数、复数等。数组的维度可以是任意的,但数组中的所有元素必须是相同的数据类型。数组通常用于一般的数值计算和数据处理任务。而Numpy中的矩阵(matrix)则是一种特殊的二维数组,它在某些方面与传统的数学上的矩阵概念相仿,例如支持矩阵乘法,具有逆矩阵等属性。Numpy的矩阵类名为matrix,它继承自ndarray类,但增加了一些特定于矩阵的操作方法。当我们需要进行特定的矩阵运算,比如矩阵乘法时,使用matrix对象可能会更加直观和方便。但是,在需要进行一些通用的数组操作时,使用ndarray对象更为合适。下面将介绍如何将ndarray对象转换为matrix对象,以及如何将matrix对象转换回ndarray对象。1. ndarray转换成matrix在Numpy中,要将一个ndarray对象转换为matrix对象,可以使用numpy库中的mat函数,或者直接将ndarray对象传递给numpy.matrix的构造器。下面给出一个示例:```pythonimport numpy as np# 创建一个4x4的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值