У меня проблемы с использованием прокси jdk Dynami c - PullRequest
0 голосов
/ 25 мая 2020

Перед использованием spring aop и cglib, теперь я заменил простой пример. Я обнаружил, что выполнение методов sayHello1 () и sayHello2 () выводит «до» и «после»: «Боже мой, это очень сложно, вы понимаете, что Я о чем говорю? Я схожу с ума. TT

public interface HelloWorld {
    void sayHello1(String say);
    void sayHello2(String say);
}
public static class HelloWorldImpl implements HelloWorld {
    @Override
    public void sayHello1(String say) { System.out.println(say); }
    @Override
    public void sayHello2(String say) { System.out.println(say); }
}
public static class Invocation implements InvocationHandler {
    private final Object target;

    public Invocation(Object target) { this.target = target; }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before..."); // TODO method before
        Object object = method.invoke(target, args);
        System.out.println("after..."); // TODO method after
        return object;
    }
}
public static void main(String[] args) {
    HelloWorld helloWorld = (HelloWorld) Proxy.newProxyInstance(
        ClassLoader.getSystemClassLoader(),
        new Class[] { HelloWorld.class },
        new Invocation(new HelloWorldImpl())
    );
    helloWorld.sayHello1("Hello World1 ...");
    helloWorld.sayHello2("Hello World2 ...");
}

1 Ответ

1 голос
/ 27 мая 2020

Вы имеете в виду, что хотите что-то вроде этого?

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  System.out.println("Instrumenting " + method);
  Object result;
  switch (method.getName()) {
    case "sayHello1":
      System.out.println("before A");
      result = method.invoke(target, args);
      System.out.println("after A");
      break;
    case "sayHello2":
      System.out.println("before B");
      // Let's change the argument just for fun
      args[0] = "changed argument";
      result = method.invoke(target, args);
      System.out.println("after B");
      break;
    default:
      result = method.invoke(target, args);
  }
  return result;
}

Это даст следующий журнал консоли:

Instrumenting public abstract void de.scrum_master.spring.q62001911.HelloWorld.sayHello1(java.lang.String)
before A
Hello World1 ...
after A
Instrumenting public abstract void de.scrum_master.spring.q62001911.HelloWorld.sayHello2(java.lang.String)
before B
changed argument
after B

Конечно, вы можете распечатать дополнительную информацию или различать перегруженные методы с помощью одинаковые имена по типам параметров. Попробуйте такие вещи, как

method.getParameterTypes();
method.getParameterCount();
method.getReturnType();

Это утомительно? Да, но все же прямолинейно. И это утомительно - причина того, почему AspectJ или Spring AOP с их элегантной моделью pointcut + advice намного проще использовать, потому что они уже выполнили свою работу и скрывают от вас внутреннюю сложность.

...