请选择 进入手机版 | 继续访问电脑版

代理-动态代理另外一种方式:cglib

发表于 2017-07-13 10:43 显示全部楼层 16 198

        接着上篇:代理-JDK动态字节码获取($Proxy) 本篇介绍java动态代理的另外一种方式,内容仅仅涉及到cglib的基本的用法,想了解更深入内容,可以自个百度,或google。

        开始前,先了解cglib概念,它跟jdk自带的有什么区别。

CGLIB:(百度百科)

    CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。

    注意概念中的关键字, 运行期,拓展java类,实现java接口。这里包含一个潜台词,可以动态生成某个类的子类或者生成java接口实现类。这些跟jdk的动态代理有异曲同工之处。

   先回顾jdk动态代理原理:

    1:先创建一个接口(要代理的操作)

    2:真实对象(被代理对象),实现了1中的接口

    3:实现InvocationHandler接口中的invoke方法, 目的很简单:将额外的逻辑跟代理逻辑编织在一起

    4:jdk动态创建一个代理对象,继承制Proxy类(目的获取3中的handler对象),同时实现1中的接口

    5:代理对象执行代理操作,底层便是执行handler中的invoke方法。

    从上面的原理中,可以看出接口是jdk动态代理的核心,功能完成依赖接口存在,也即jdk动态代理实现模式是接口的实现。那么问题来了,如果就单纯一个普通java类需要代理,怎办?这时候,就到cglib出场了。

    CGLIB 也可以用来做java的动态代理,而它的实现原理上跟jdk差不多,区别是使用了继承的模式。在这方面的运用,cglib可以说是jdk动态代理的有效补充。

选用

    但凡涉及到对比,都出现选用问题,关键看代理类还是代理接口, 代理类使用cglib,代理接口使用jdk原生的,这里要注意,如果使用代理类,必须确保类是非final类。

运用

    spring的 AOP, 代理接口时,使用jdk原生, 代理类时使用cglib

    hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联

扯那么多,还没提到重点,怎么用?直接上代码:

image.png

注意:cglib要依赖jar, 这里的jar包是spring框架中的自带的jar,直接拿来用了

App:测试类

USBImpl2:业务接口实现类(真实对象, 将要被代理的对象)

USBCglibHandler:动态代理接口处理类

代码:

真实对象:注意, 没有实现接口

package com.langfei;

//业务接口实现类
public class USBImpl2 {
	public void swapData() {
		System.out.println("你傻逼....");
	}
}


  USBCglibHandler:

package com.langfei;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;

public class USBCglibHandler implements InvocationHandler {
	
	private Object target;
	public USBCglibHandler(Object target){
		this.target = target;
	}
	
	@SuppressWarnings("unchecked")
	public <T> T getProxyObject(){
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.target.getClass());
		enhancer.setCallback(this);
		return (T) enhancer.create();
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		System.out.println("被代理....");
		return method.invoke(this.target, args);
	}

}

App:

package com.langfei;


public class App {
	public static void main(String[] args) throws Exception {
		USBCglibHandler cglibHandler = new USBCglibHandler(new USBImpl2());
		USBImpl2 proxyObject = cglibHandler.getProxyObject();  
		proxyObject.swapData();
		
	}
}

运行,代理成功:

image.png

到这,搞掂。

评分

参与人数 1学币 +3 收起 理由
seemygo + 3 很给力!

查看全部评分

回复 使用道具
举报
青埂峰峰主

发表于 2017-12-30 23:51 显示全部楼层

棒棒哒!!!!!!!!!!!!!
回复 支持 反对 使用道具
举报
无戒

发表于 2017-11-01 13:01 显示全部楼层

回复 支持 反对 使用道具
举报
GHOST

发表于 2017-10-24 17:25 显示全部楼层

回复 支持 反对 使用道具
举报
仰光的阳光

发表于 2017-10-18 21:06 显示全部楼层

以诚感人者,人亦诚而应。一点回复,敬请笑纳!

回复 支持 反对 使用道具
举报
寻找皮卡丘

发表于 2017-10-09 15:13 显示全部楼层

回复 支持 反对 使用道具
举报
山秀

发表于 2017-09-29 01:01 显示全部楼层

支持!支持!!

回复 支持 反对 使用道具
举报
凌大胖纸

发表于 2017-09-17 16:23 显示全部楼层

回复 支持 反对 使用道具
举报
哥哥在哪儿

发表于 2017-09-08 17:14 显示全部楼层

回复 支持 反对 使用道具
举报
我爱大菠萝

发表于 2017-08-21 11:14 显示全部楼层

回复 支持 反对 使用道具
举报
12下一页

发表新文章
叶星飞

小码哥骨干成员

0

学分

958

学币

1049

积分

小码哥骨干成员

Rank: 6Rank: 6

积分
1049
Ta的主页 发消息
精华帖排行榜

精彩推荐

  • 关注小码哥教育