博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
代理学习
阅读量:6123 次
发布时间:2019-06-21

本文共 4432 字,大约阅读时间需要 14 分钟。

1、静态代理

测试类:

package com.example.demo.proxy;public class StaticProxy implements UserDao {    private UserDao userdao;    public UserDao getUserdao() {        return userdao;    }    public void setUserdao(UserDao userdao) {        this.userdao = userdao;    }    @Override    public void getUser() {        System.out.println("代理类进入");        userdao.getUser();        System.out.println("代理类退出");    }    public static void main(String[] args) {        StaticProxy sp = new StaticProxy();        UserDao userDao = new UserDaoImpl();        sp.setUserdao(userDao);        sp.getUser();    }}

userdao:

package com.example.demo.proxy;public interface UserDao {    void getUser();}

userdaoimpl:

package com.example.demo.proxy;public class UserDaoImpl implements UserDao {    @Override    public void getUser() {        System.out.println("userdao impl");    }}

运行测试类:

代理类进入userdao impl代理类退出

 

2、jdk动态代理

测试类:

package com.example.demo.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class DynamicProxy1 {    //维护一个被代理的类    private Object obj;    public Object getObj() {        return obj;    }    public void setObj(Object obj) {        this.obj = obj;    }    public Object getInstance() {        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),                obj.getClass().getInterfaces(),                new InvocationHandler() {                    @Override                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                        System.out.println("进入proxy");                        //invoke两个参数,obj原对象,args参数                        method.invoke(obj, args);                        System.out.println("退出proxy");                        return null;                    }                });    }    public static void main(String[] args) {        DynamicProxy1 dp1 = new DynamicProxy1();        dp1.setObj(new UserDaoImpl());        UserDao instance = (UserDao) dp1.getInstance();        instance.getUser();    }}

userdao和userdaoimpl同上

运行测试类:

进入proxyuserdao impl退出proxy
JDK动态代理局限性

通过反射类Proxy和InvocationHandler回调接口实现的jdk动态代理,要求委托类必须实现一个接口,但事实上并不是所有类都有接口,对于没有实现接口的类,便无法使用该方方式实现动态代理。

3、cglib动态代理

静态代理和jdk动态代理模式都是要求目标对象实现一个接口,
Cglib代理,也叫作子类代理,是基于asm框架,实现了无反射机制进行代理,利用空间来换取了时间,代理效率高于jdk ,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.
它有如下特点:
JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现.
Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)
Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.
注意
需要引入cglib的jar文件,但是Spring的核心包中已经包括了Cglib功能,所以直接引入pring-core-3.2.5.jar即可.
引入功能包后,就可以在内存中动态构建子类
代理的类不能为final,否则报错
目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法.
 
测试类:
package com.example.demo.proxy;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/** * 实现methodInterceptor方法,并重写interceptor方法 */public class CglibDynamicProxy implements MethodInterceptor {    //维护一个被代理的对象    private Object target;    public Object getinstance() {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(target.getClass());        //回调方法指定当前类即可(实现了methodInterceptor接口的类)        enhancer.setCallback(this);        return enhancer.create();    }    @Override    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {        System.out.println("cglib代理开始");        Object invoke = method.invoke(target, objects);        System.out.println("cglib代理结束");        return invoke;    }    public static void main(String[] args) {        CglibDynamicProxy cg = new CglibDynamicProxy();        UserWithoutInterface u = new UserWithoutInterface();        cg.setTarget(u);        UserWithoutInterface instance = (UserWithoutInterface) cg.getinstance();        instance.getuser();    }    public Object getTarget() {        return target;    }    public void setTarget(Object target) {        this.target = target;    }}

被代理对象UserwithoutInterface:

package com.example.demo.proxy;public class UserWithoutInterface {    public void getuser(){        System.out.println("执行userwithoutInterface中的getuser方法");    }}

执行测试类结果:

cglib代理开始执行userwithoutInterface中的getuser方法cglib代理结束

 

 

参考:

 

转载于:https://www.cnblogs.com/nxzblogs/p/11014986.html

你可能感兴趣的文章
TypeScript--函数
查看>>
原生JS大揭秘—原型链
查看>>
利用tornado实现表格文件预览
查看>>
微信自定义分享
查看>>
Spring 中获取 request 的几种方法,及其线程安全性分析
查看>>
SpiderData 2019年2月14日 DApp数据排行榜
查看>>
PAT A1104
查看>>
软件测试的艺术第六章总结
查看>>
leetcode394. Decode String
查看>>
iOS开发之有间距的UITableViewCell
查看>>
区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令一
查看>>
SSH框架之SpringMVC文件上传功能代码
查看>>
08.自定义方法以及直接访问java类方法---《Beetl视频课程》
查看>>
FFmpeg在Intel GPU上的硬件加速与优化
查看>>
PDCA + GTD + 番茄工作法
查看>>
阿里云超算揭秘:虚拟机的心脏,物理机的肌肉
查看>>
Edge 浏览器有秘密白名单,允许 Facebook 运行 Flash 代码
查看>>
css 居中几种方法
查看>>
vue双向绑定的实现原理
查看>>
03.HTML5(音频)
查看>>