一起学SF框架系列补-模块core-cglib之Enhancer

本文详细介绍了CGLIB中的Enhancer类,它能代理普通类和接口,拦截方法调用,但不能处理final方法和final类。讲解了setSuperclass和create方法的用法,以及createClass和generateClass的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Enhancer是CGLIB中最常用的一个类,和Java1.3动态代理中引入的Proxy类差不多。但和Proxy不同的是,Enhancer既能够代理普通的class,也能够代理接口。

类作用

Enhancer创建一个被代理对象的子类并且拦截所有的方法调用(包括从Object中继承的toString和hashCode方法)。Enhancer不能拦截final方法,例如Object.getClass()方法,这是由于Java final方法语义决定的。基于同样的道理,Enhancer也不能对fianl类进行代理操作。

Enhancer.setSuperclass用来设置父类型,Enhancer.create(Object…)方法是用来创建增强对象的,其提供了很多不同参数的方法用来匹配被增强类的不同构造方法。(虽然类的构造方法只是Java字节码层面的函数,但是Enhancer却不能对其进行操作。Enhancer同样不能操作static或者final类)。我们也可以先使用Enhancer.createClass()来创建字节码(.class),然后用字节码动态的生成增强后的对象。

类实现

createClass / createHelper

创建一个增强类

	public Class createClass() {
		classOnly = true;
		return (Class) createHelper();
	}
	
	private Object createHelper() {
		//进行有效性验证:callBack不能为空,且有多个callBack时必须有callBackFilter
		preValidate();
		// SPRING PATCH BEGIN
		//根据KEY_FACTORY 以当前代理类的配置信息 生成一个组合Key,再利用这个组合Key,进行create
		Object key = new EnhancerKey((superclass != null ? superclass.getName() : null),
				(interfaces != null ? Arrays.asList(ReflectUtils.getNames(interfaces)) : null),
				(filter == ALL_ZERO ? null : new WeakCacheKey<>(filter)),
				Arrays.asList(callbackTypes),
				useFactory,
				interceptDuringConstruction,
				serialVersionUID);
		// SPRING PATCH END
		this.currentKey = key;
		//根据生成的key创建代理对象 注1
		Object result = super.create(key);
		return result;
	}

注1:见父类实现:https://blog.youkuaiyun.com/zhang6622056/article/details/87783480

generateClass

生成class字节码。

public void generateClass(ClassVisitor v) throws Exception {
		Class sc = (superclass == null) ? Object.class : superclass;

		if (TypeUtils.isFinal(sc.getModifiers()))
			throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
		List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
		filterConstructors(sc, constructors);

		// Order is very important: must add superclass, then
		// its superclass chain, then each interface and
		// its superinterfaces.
		List actualMethods = new ArrayList();
		List interfaceMethods = new ArrayList();
		final Set forcePublic = new HashSet();
		// 得到所有的方法,包括基类、接口
		getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);

		List methods = CollectionUtils.transform(actualMethods, new Transformer() {
			public Object transform(Object value) {
				Method method = (Method) value;
				int modifiers = Constants.ACC_FINAL
						| (method.getModifiers()
						& ~Constants.ACC_ABSTRACT
						& ~Constants.ACC_NATIVE
						& ~Constants.ACC_SYNCHRONIZED);
				if (forcePublic.contains(MethodWrapper.create(method))) {
					modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
				}
				return ReflectUtils.getMethodInfo(method, modifiers);
			}
		});

		// 生成字节码,参数还是之前的classWriter
		ClassEmitter e = new ClassEmitter(v);
		if (currentData == null) {
			e.begin_class(Constants.V1_2,
					Constants.ACC_PUBLIC,
					getClassName(),
					Type.getType(sc),
					(useFactory ?
							TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) :
							TypeUtils.getTypes(interfaces)),
					Constants.SOURCE_FILE);
		}
		else {
			e.begin_class(Constants.V1_2,
					Constants.ACC_PUBLIC,
					getClassName(),
					null,
					new Type[]{FACTORY},
					Constants.SOURCE_FILE);
		}
		List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());

		// 这些都是属性
		e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
		e.declare_field(Constants.ACC_PUBLIC | Constants.ACC_STATIC, FACTORY_DATA_FIELD, OBJECT_TYPE, null);
		if (!interceptDuringConstruction) {
			e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE, null);
		}
		e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null);
		e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null);
		if (serialVersionUID != null) {
			e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID);
		}

		// 生成的callback,命名就是CGLIB&CALLBACK_在数组中的序号
		for (int i = 0; i < callbackTypes.length; i++) {
			e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null);
		}
		// This is declared private to avoid "public field" pollution
		e.declare_field(Constants.ACC_PRIVATE | Constants.ACC_STATIC, CALLBACK_FILTER_FIELD, OBJECT_TYPE, null);

		if (currentData == null) {
			// filter在这里发生作用
			emitMethods(e, methods, actualMethods);
			emitConstructors(e, constructorInfo);
		}
		else {
			emitDefaultConstructor(e);
		}
		emitSetThreadCallbacks(e);
		emitSetStaticCallbacks(e);
		emitBindCallbacks(e);

		if (useFactory || currentData != null) {
			int[] keys = getCallbackKeys();
			emitNewInstanceCallbacks(e);
			emitNewInstanceCallback(e);
			emitNewInstanceMultiarg(e, constructorInfo);
			emitGetCallback(e, keys);
			emitSetCallback(e, keys);
			emitGetCallbacks(e);
			emitSetCallbacks(e);
		}

		e.end_class();
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐享技术

每一个打赏,都是对我最大的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值