一、接口定义

定义接口

  1. public interface IUserApi {
  2. String queryUserInfo();
  3. }

实现接口

  1. public class UserApi implements IUserApi {
  2. public String queryUserInfo() {
  3. return "查询用户信息!";
  4. }
  5. }

二、JDK代理方式

  1. public class JDKProxy {
  2. public static <T> T getProxy(Class clazz) throws Exception {
  3. ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  4. return (T) Proxy.newProxyInstance(classLoader, new Class[]{clazz}, new InvocationHandler() {
  5. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  6. System.out.println(method.getName() + " 你被代理了,By JDKProxy!");
  7. return "查询用户信息!";
  8. }
  9. });
  10. }
  11. }
  12. @Test
  13. public void test_JDKProxy() throws Exception {
  14. IUserApi userApi = JDKProxy.getProxy(IUserApi.class);
  15. String invoke = userApi.queryUserInfo();
  16. logger.info("测试结果:{}", invoke);
  17. }

三、 CGLIB代理方式

  1. public class CglibProxy implements MethodInterceptor {
  2. public Object newInstall(Object object) {
  3. return Enhancer.create(object.getClass(), this);
  4. }
  5. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  6. System.out.println("我被CglibProxy代理了");
  7. return methodProxy.invokeSuper(o, objects);
  8. }
  9. }
  10. @Test
  11. public void test_CglibProxy() throws Exception {
  12. CglibProxy cglibProxy = new CglibProxy();
  13. UserApi userApi = (UserApi) cglibProxy.newInstall(new UserApi());
  14. String invoke = userApi.queryUserInfo();
  15. logger.info("测试结果:{}", invoke);
  16. }

四、ASM代理方式

  1. public class ASMProxy extends ClassLoader {
  2. public static <T> T getProxy(Class clazz) throws Exception {
  3. ClassReader classReader = new ClassReader(clazz.getName());
  4. ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
  5. classReader.accept(new ClassVisitor(ASM5, classWriter) {
  6. @Override
  7. public MethodVisitor visitMethod(int access, final String name, String descriptor, String signature, String[] exceptions) {
  8. // 方法过滤
  9. if (!"queryUserInfo".equals(name))
  10. return super.visitMethod(access, name, descriptor, signature, exceptions);
  11. final MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);
  12. return new AdviceAdapter(ASM5, methodVisitor, access, name, descriptor) {
  13. @Override
  14. protected void onMethodEnter() {
  15. // 执行指令;获取静态属性
  16. methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
  17. // 加载常量 load constant
  18. methodVisitor.visitLdcInsn(name + " 你被代理了,By ASM!");
  19. // 调用方法
  20. methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
  21. super.onMethodEnter();
  22. }
  23. };
  24. }
  25. }, ClassReader.EXPAND_FRAMES);
  26. byte[] bytes = classWriter.toByteArray();
  27. return (T) new ASMProxy().defineClass(clazz.getName(), bytes, 0, bytes.length).newInstance();
  28. }
  29. }
  30. @Test
  31. public void test_ASMProxy() throws Exception {
  32. IUserApi userApi = ASMProxy.getProxy(UserApi.class);
  33. String invoke = userApi.queryUserInfo();
  34. logger.info("测试结果:{}", invoke);
  35. }

五、Byte-Buddy代理方式

  1. public class ByteBuddyProxy {
  2. public static <T> T getProxy(Class clazz) throws Exception {
  3. DynamicType.Unloaded<?> dynamicType = new ByteBuddy()
  4. .subclass(clazz)
  5. .method(ElementMatchers.<MethodDescription>named("queryUserInfo"))
  6. .intercept(MethodDelegation.to(InvocationHandler.class))
  7. .make();
  8. return (T) dynamicType.load(Thread.currentThread().getContextClassLoader()).getLoaded().newInstance();
  9. }
  10. }
  11. @RuntimeType
  12. public static Object intercept(@Origin Method method, @AllArguments Object[] args, @SuperCall Callable<?> callable) throws Exception {
  13. System.out.println(method.getName() + " 你被代理了,By Byte-Buddy!");
  14. return callable.call();
  15. }
  16. @Test
  17. public void test_ByteBuddyProxy() throws Exception {
  18. IUserApi userApi = ByteBuddyProxy.getProxy(UserApi.class);
  19. String invoke = userApi.queryUserInfo();
  20. logger.info("测试结果:{}", invoke);
  21. }

六、Javassist代理方式

  1. public class JavassistProxy extends ClassLoader {
  2. public static <T> T getProxy(Class clazz) throws Exception {
  3. ClassPool pool = ClassPool.getDefault();
  4. // 获取类
  5. CtClass ctClass = pool.get(clazz.getName());
  6. // 获取方法
  7. CtMethod ctMethod = ctClass.getDeclaredMethod("queryUserInfo");
  8. // 方法前加强
  9. ctMethod.insertBefore("{System.out.println(\"" + ctMethod.getName() + " 你被代理了,By Javassist\");}");
  10. byte[] bytes = ctClass.toBytecode();
  11. return (T) new JavassistProxy().defineClass(clazz.getName(), bytes, 0, bytes.length).newInstance();
  12. }
  13. }
  14. @Test
  15. public void test_JavassistProxy() throws Exception {
  16. IUserApi userApi = JavassistProxy.getProxy(UserApi.class)
  17. String invoke = userApi.queryUserInfo();
  18. logger.info("测试结果:{}", invoke);
  19. }