java代理浅述

代理

代理主要可以分为:

  • 静态代理
  • JDK自带的动态代理
  • Cglib

静态代理

静态代理比较简单,简单来说就是不想直接调用被代理类,通过代理类来实现功能。如下就是使用了静态代理

定义接口

public interface BookFace {
    public void addBook();
    public void addapple();
}
public class BookFaceImp implements BookFace {
    @Override
    public void addBook()
    {
        System.out.println("增加图书方法");
    }
    @Override
    public void  addapple()
    {
        System.out.println("增加苹果");
    }

}
public class BookFaceStatic implements BookFace{
    private BookFace target;

    public  BookFaceStatic(BookFace target)
    {
        this.target=target;

    }
    @Override
    public void addBook() {
        System.out.println("美术图书");
        target.addBook();

    }

    @Override
    public void addapple() {
        System.out.println("红苹果");
        target.addapple();

    }
}

编写单测:

@Test
    public void test3()
    {
        BookFaceStatic faceStatic=new BookFaceStatic(new BookFaceImp());
        faceStatic.addBook();
        faceStatic.addapple();

 }

输出结果:

1166661-20190729213955757-1626123578.png

上述就是一个简单的静态代理,就是讲需要的被代理类作为参数传入待代理类中。

JDK自带的动态代理

java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

JDK动态代理只能对实现了接口的类生成代理,而不能针对类。

延续使用上述的接口和接口实现类,核心代码如下:

public class BookFaceProcyJDK  implements InvocationHandler {
    private Object target;

    public  Object getProcy(Object target)
    {
        //获取到是哪个类需要代理
        this.target=target;
        //getInterfaces()获取代理类的接口
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    //重写invoke方法,InvocationHandler中自动会执行
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("批量执行1");
        Object result=method.invoke(target,args);
        System.out.println("批量执行2");
        return result;
    }
}

编写单测:

   @Test
    public void test1()
    {
        BookFaceImp bookFaceImp=new BookFaceImp();
        BookFaceProcyJDK bookFaceProcy=new BookFaceProcyJDK();
        BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp);
        bookFace.addBook();
        bookFace.addapple();
    }

输出结果:

1166661-20190729214010793-2048833864.png

采坑:
为什么BookFace bookFace= (BookFaceImp)bookFaceProcy.getProcy(bookFaceImp);
不能这样写???

解释:因为代理时相当于新建了一个BookFaceImp1,要么写成(BookFaceImp1)bookFaceProcy.bind(bookFaceImp)或者使用它的父类BookFace,因为不知道到底生成了一个什么名字的BookFaceImp,所以得使用它的父类BookFace。

(代理生成的BookFaceImp1和BookFaceImp是统一层级的)

1166661-20190729214030315-1536074215.png

Cglib

cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。

延续使用上述的接口和接口实现类,核心代码如下:

  public class BookFaceProcyCglib implements MethodInterceptor {

    private Object target;
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

        System.out.println("监听开始");
        Object result=method.invoke(target,args);
        System.out.println("监听结束");
        return result;
    }
    public Object getProcy(Object target)
    {
        this.target=target;
        Enhancer enhancer=new Enhancer();
        //设置父类,因为cglib是设置子类
        enhancer.setSuperclass(target.getClass());
        //设置回调
        enhancer.setCallback(this);
        return  enhancer.create();
    }
}

单测:

   @Test
    public void test2()
    {
        BookFaceImp bookFaceImp=new BookFaceImp();
        BookFaceProcyCglib bookFaceProcy=new BookFaceProcyCglib();
        BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp);
        bookFace.addBook();
        bookFace.addapple();
    }

运行结果:
1166661-20190729214047389-438034062.png

Cglib与jdk自带的动态代理不同是生成的bookFaceImp1的父类是bookFaceImp

1166661-20190729214059129-747364043.png
所以 BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp)也可以改成 BookFace bookFace= (BookFaceImp)bookFaceProcy.getProcy(bookFaceImp),效果一致

转载于:https://www.cnblogs.com/lixuan1998/p/11266687.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值