JDK动态代理和Cglib的动态代理

Wesley13
• 阅读 908

最简单的是静态代理方法,即代理模式,这里就不多啰嗦了。。

重点说一下JDK的动态代理和Cglib的动态代理吧

先说JDK的,需要被代理的类需要有接口,否则无法实现

package proxy.dynamic;

public interface IBook {
    void add();
}

实现接口的类如下

package proxy.dynamic;

public class Book implements IBook {

    @Override
    public void add() {
        System.out.println("Add Method!");
    }

    

}

创建一个代理类,需要实现一个接口InvocationHandler接口,里面有一个invoke方法需要实现

同时创建一个生成实例的方法

package proxy.dynamic;

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

public class BookProxy implements InvocationHandler{
    private Object target;
    
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//这里需要接口
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result=null;
        System.out.println("Before");
        result=method.invoke(target, args);//执行方法
        System.out.println("After");
        return result;
    }
    

    

}

接下来创建测试类

package proxy.dynamic;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        BookProxy bp = new BookProxy();
        IBook book = (IBook) bp.bind(new Book());
        book.add();

    }

}

可以看到依次输出了Before,方法,After

下面说一下Cglib的代理,Cglib代理不需要原类实现接口,依赖Cglib和asm两个Jar包

需要代理的类如下

package cglib.proxy;

public class Book {

    public void add() {
        System.out.println("Add Method!");
    }
}

创建一个代理类,实现MethodInterceptor接口,同时写一个生成实例的getInstance方法

package cglib.proxy;

import java.lang.reflect.Method;

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

public class CglibProxy implements MethodInterceptor{
    private Object target;
    public Object getInstance(Object target){
        this.target=target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        
        System.out.println("Before");
        proxy.invokeSuper(obj, args);
        System.out.println("After");
        return null;
    }

    

}

接下来就是简单测试一下

package cglib.proxy;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy();
        Book book=(Book) proxy.getInstance(new Book());
        book.add();

    }

}

运行效果一样的

简单总结一下,JDK动态代理,需要实现一个接口InvocationHandler,要求被代理的对象必须有一个接口

Cglib代理需要实现MethodInterceptor接口,不需要被代理的类必须有接口

性能方法,参考其他文章,说JDK代理适合多例模式,而单例模式Cglib更好一些,因为Cglib是用底层的字节码技术生成实例,耗费时间较长,性能不如JDK动态代理。(有待验证。。)

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
CGLIB介绍与原理(通过继承的动态代理)
一、什么是CGLIB?CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。二、CGLIB原理CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的
Wesley13 Wesley13
2年前
CGLIB动态代理源码分析
CGLIB动态代理样例由于CGLIB是JDK之外的东西,因此在使用CGLIB的时候需要引入CGLIB的包(我这里是gradle项目):dependencies{implementation('cglib:cglib:3.3.0')}要被代理的类:packagecom.example.demo.p
Easter79 Easter79
2年前
Spring的两种代理JDK和CGLIB的区别浅谈
一、原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Easter79 Easter79
2年前
Spring的两种动态代理:Jdk和Cglib 的区别和实现
一、原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以
Wesley13 Wesley13
2年前
Java动态代理机制解析
动态代理是指在运行时动态生成代理类。不需要我们像静态代理那个去手动写一个个的代理类。生成动态代理类有很多方式:Java动态代理,CGLIB,Javassist,ASM库等。这里主要说一下Java动态代理的实现。Java动态代理InvocationHandler接口Java动态代理中,每一个
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这