一、接口定义
定义接口
public interface IUserApi {
String queryUserInfo();
}
实现接口
public class UserApi implements IUserApi {
public String queryUserInfo() {
return "查询用户信息!";
}
}
二、JDK代理方式
public class JDKProxy {
public static <T> T getProxy(Class clazz) throws Exception {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return (T) Proxy.newProxyInstance(classLoader, new Class[]{clazz}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName() + " 你被代理了,By JDKProxy!");
return "查询用户信息!";
}
});
}
}
@Test
public void test_JDKProxy() throws Exception {
IUserApi userApi = JDKProxy.getProxy(IUserApi.class);
String invoke = userApi.queryUserInfo();
logger.info("测试结果:{}", invoke);
}
三、 CGLIB代理方式
public class CglibProxy implements MethodInterceptor {
public Object newInstall(Object object) {
return Enhancer.create(object.getClass(), this);
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("我被CglibProxy代理了");
return methodProxy.invokeSuper(o, objects);
}
}
@Test
public void test_CglibProxy() throws Exception {
CglibProxy cglibProxy = new CglibProxy();
UserApi userApi = (UserApi) cglibProxy.newInstall(new UserApi());
String invoke = userApi.queryUserInfo();
logger.info("测试结果:{}", invoke);
}
四、ASM代理方式
public class ASMProxy extends ClassLoader {
public static <T> T getProxy(Class clazz) throws Exception {
ClassReader classReader = new ClassReader(clazz.getName());
ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
classReader.accept(new ClassVisitor(ASM5, classWriter) {
@Override
public MethodVisitor visitMethod(int access, final String name, String descriptor, String signature, String[] exceptions) {
// 方法过滤
if (!"queryUserInfo".equals(name))
return super.visitMethod(access, name, descriptor, signature, exceptions);
final MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);
return new AdviceAdapter(ASM5, methodVisitor, access, name, descriptor) {
@Override
protected void onMethodEnter() {
// 执行指令;获取静态属性
methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
// 加载常量 load constant
methodVisitor.visitLdcInsn(name + " 你被代理了,By ASM!");
// 调用方法
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
super.onMethodEnter();
}
};
}
}, ClassReader.EXPAND_FRAMES);
byte[] bytes = classWriter.toByteArray();
return (T) new ASMProxy().defineClass(clazz.getName(), bytes, 0, bytes.length).newInstance();
}
}
@Test
public void test_ASMProxy() throws Exception {
IUserApi userApi = ASMProxy.getProxy(UserApi.class);
String invoke = userApi.queryUserInfo();
logger.info("测试结果:{}", invoke);
}
五、Byte-Buddy代理方式
public class ByteBuddyProxy {
public static <T> T getProxy(Class clazz) throws Exception {
DynamicType.Unloaded<?> dynamicType = new ByteBuddy()
.subclass(clazz)
.method(ElementMatchers.<MethodDescription>named("queryUserInfo"))
.intercept(MethodDelegation.to(InvocationHandler.class))
.make();
return (T) dynamicType.load(Thread.currentThread().getContextClassLoader()).getLoaded().newInstance();
}
}
@RuntimeType
public static Object intercept(@Origin Method method, @AllArguments Object[] args, @SuperCall Callable<?> callable) throws Exception {
System.out.println(method.getName() + " 你被代理了,By Byte-Buddy!");
return callable.call();
}
@Test
public void test_ByteBuddyProxy() throws Exception {
IUserApi userApi = ByteBuddyProxy.getProxy(UserApi.class);
String invoke = userApi.queryUserInfo();
logger.info("测试结果:{}", invoke);
}
六、Javassist代理方式
public class JavassistProxy extends ClassLoader {
public static <T> T getProxy(Class clazz) throws Exception {
ClassPool pool = ClassPool.getDefault();
// 获取类
CtClass ctClass = pool.get(clazz.getName());
// 获取方法
CtMethod ctMethod = ctClass.getDeclaredMethod("queryUserInfo");
// 方法前加强
ctMethod.insertBefore("{System.out.println(\"" + ctMethod.getName() + " 你被代理了,By Javassist\");}");
byte[] bytes = ctClass.toBytecode();
return (T) new JavassistProxy().defineClass(clazz.getName(), bytes, 0, bytes.length).newInstance();
}
}
@Test
public void test_JavassistProxy() throws Exception {
IUserApi userApi = JavassistProxy.getProxy(UserApi.class)
String invoke = userApi.queryUserInfo();
logger.info("测试结果:{}", invoke);
}