依赖
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
接口
public interface Person {
boolean getBoolean();
char getChar();
byte getByte();
short getShort();
int getInt();
float getFloat();
double getDouble();
long getLong();
String getName();
void setId();
int add(int a, int b);
Student getStudent(char[] vv);
Student[] getStudents(char[] vv);
Long getL();
Double getD();
MyEnum getMyEnum();
}
代码
import javassist.*;
import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
public class AssistUtil {
private static Set<String> set = new HashSet<>();
static {
set.add("byte");
set.add("char");
set.add("short");
set.add("int");
set.add("float");
set.add("double");
set.add("long");
set.add("boolean");
}
/**
* @param clazz
* @return
* @throws Exception
*/
private static byte[] generateByteCode(Class clazz) throws Exception {
ClassPool pool = ClassPool.getDefault();
//此句要打开要不然SpringBoot中打成jar包可能不生效
pool.insertClassPath(new ClassClassPath(AssistUtil.class));
//创建代理类对象
CtClass ctClass = pool.makeClass(getNewClassName(clazz));
//获取代理对象的接口类
CtClass interfaceClass = pool.getCtClass(clazz.getName());
CtClass[] interfaces = new CtClass[]{interfaceClass};
//设置代理类的接口
ctClass.setInterfaces(interfaces);
//代理类的所有方法
CtMethod[] methods = interfaceClass.getDeclaredMethods();
for (CtMethod method : methods) {
String methodName = method.getName();
/**
* 新生成方法,保证和原方法一样,如果返回值不是基础类型 返回null
*/
CtMethod cm = new CtMethod(method.getReturnType(), methodName, method.getParameterTypes(), ctClass);
//根据返回值类型处理基础类型,float,double,long要特殊处理,没有返回值时直接return
String returnType = cm.getReturnType().getName();
if (set.contains(returnType)) {
if ("float".equals(returnType)) {
cm.setBody("return 0F;");
} else if ("double".equals(returnType)) {
cm.setBody("return 0D;");
} else if ("long".equals(returnType)) {
cm.setBody("return 0L;");
} else {
cm.setBody("return 0;");
}
} else if (!"void".equals(returnType)) {
cm.setBody("return null;");
} else {
cm.setBody("return;");
}
ctClass.addMethod(cm);
}
byte[] code = ctClass.toBytecode();
return code;
/**
* 此3句打开会在当前生成一个class文件
* FileOutputStream fos = new FileOutputStream(getNewClassName(clazz) + ".class");
* fos.write(code);
* fos.close();
*/
/**
* 生成一个Class对象 这里直接返回此class也是可以的
* Class aClass = ctClass.toClass();
*/
}
/**
* 通过当前类加载器加载此类
*
* @param clazz
* @return
* @throws Exception
*/
public static Class getInterfaceImpl(Class<?> clazz) throws Exception {
byte[] code = generateByteCode(clazz);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class cls = Class.forName("java.lang.ClassLoader");
Method method = cls.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class});
method.setAccessible(true);
try {
Object[] args = new Object[]{getNewClassName(clazz), code, 0, code.length};
Class newClazz = (Class) method.invoke(loader, args);
return newClazz;
} finally {
method.setAccessible(false);
}
}
private static String getNewClassName(Class<?> clazz) {
return clazz.getSimpleName() + "Impl";
}
}