在使用spring aop和cglib之前,现在我替换了一个简单的示例。我发现执行方法sayHello1()和sayHello2()都输出“ before”和“ after”哦,天哪,这很困难,您理解吗?我在说什么?我现在疯了。 T.T
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 ...");
}
答案 0 :(得分:1)
您的意思是您想要这样的东西吗?
@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或带有优雅的pointcut +咨询模型的Spring AOP如此易于使用的原因,因为它们已经完成了工作并向您隐藏了内在的复杂性。