/*
|
* Copyright (c) 2011-2020, baomidou (jobob@qq.com).
|
* <p>
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* use this file except in compliance with the License. You may obtain a copy of
|
* the License at
|
* <p>
|
* https://www.apache.org/licenses/LICENSE-2.0
|
* <p>
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* License for the specific language governing permissions and limitations under
|
* the License.
|
*/
|
package com.yuanchu.mom.numgen;
|
|
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
|
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.SerializationUtils;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
|
import java.io.*;
|
|
/**
|
* 这个类是从 {@link java.lang.invoke.SerializedLambda} 里面 copy 过来的,
|
* 字段信息完全一样
|
* <p>负责将一个支持序列的 Function 序列化为 SerializedLambda</p>
|
*
|
* @author HCL
|
* @since 2018/05/10
|
*/
|
public class SerializedLambda implements Serializable {
|
|
private static final long serialVersionUID = 8025925345765570181L;
|
|
private Class<?> capturingClass;
|
private String functionalInterfaceClass;
|
private String functionalInterfaceMethodName;
|
private String functionalInterfaceMethodSignature;
|
private String implClass;
|
private String implMethodName;
|
private String implMethodSignature;
|
private int implMethodKind;
|
private String instantiatedMethodType;
|
private Object[] capturedArgs;
|
|
/**
|
* 通过反序列化转换 lambda 表达式,该方法只能序列化 lambda 表达式,不能序列化接口实现或者正常非 lambda 写法的对象
|
*
|
* @param lambda lambda对象
|
* @return 返回解析后的 SerializedLambda
|
*/
|
public static SerializedLambda resolve(SFunction<?, ?> lambda) {
|
if (!lambda.getClass().isSynthetic()) {
|
throw ExceptionUtils.mpe("该方法仅能传入 lambda 表达式产生的合成类");
|
}
|
try (ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(SerializationUtils.serialize(lambda))) {
|
@Override
|
protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
|
Class<?> clazz;
|
try {
|
clazz = ClassUtils.toClassConfident(objectStreamClass.getName());
|
} catch (Exception ex) {
|
clazz = super.resolveClass(objectStreamClass);
|
}
|
return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
|
}
|
}) {
|
return (SerializedLambda) objIn.readObject();
|
} catch (ClassNotFoundException | IOException e) {
|
throw ExceptionUtils.mpe("This is impossible to happen", e);
|
}
|
}
|
|
/**
|
* 获取接口 class
|
*
|
* @return 返回 class 名称
|
*/
|
public String getFunctionalInterfaceClassName() {
|
return normalizedName(functionalInterfaceClass);
|
}
|
|
/**
|
* 获取实现的 class
|
*
|
* @return 实现类
|
*/
|
public Class<?> getImplClass() {
|
return ClassUtils.toClassConfident(getImplClassName());
|
}
|
|
/**
|
* 获取 class 的名称
|
*
|
* @return 类名
|
*/
|
public String getImplClassName() {
|
return normalizedName(implClass);
|
}
|
|
/**
|
* 获取实现者的方法名称
|
*
|
* @return 方法名称
|
*/
|
public String getImplMethodName() {
|
return implMethodName;
|
}
|
|
/**
|
* 正常化类名称,将类名称中的 / 替换为 .
|
*
|
* @param name 名称
|
* @return 正常的类名
|
*/
|
private String normalizedName(String name) {
|
return name.replace('/', '.');
|
}
|
|
/**
|
* @return 获取实例化方法的类型
|
*/
|
public Class<?> getInstantiatedType() {
|
String instantiatedTypeName = normalizedName(instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(';')));
|
return ClassUtils.toClassConfident(instantiatedTypeName);
|
}
|
|
/**
|
* @return 字符串形式
|
*/
|
@Override
|
public String toString() {
|
String interfaceName = getFunctionalInterfaceClassName();
|
String implName = getImplClassName();
|
return String.format("%s -> %s::%s",
|
interfaceName.substring(interfaceName.lastIndexOf('.') + 1),
|
implName.substring(implName.lastIndexOf('.') + 1),
|
implMethodName);
|
}
|
|
}
|