在 java 中,返回类型不是方法签名的一部分,因此您可以随心所欲地使用它。
有两种方法可以透明地实现这一目标:
- 如果您可以控制调用该方法的对象的注入,请使用 Java 动态代理。
- 使用带有环绕建议的 AspectJ 方面,您可以操作您无法控制的代码(第三方库)。通过编译时编织或加载时编织使用 AspectJ
编辑:
使用 java 动态代理(用于接口)或 CGlib(用于类),您可以将接口指向代理,您可以从该代理与调用相交,对其进行处理,并将其委托给真正的实现。要实现这一点,您必须控制依赖注入。这是一个很好的解释。
例子:
SomeInterface t = (SomeInterface) Proxy.newProxyInstance(SomeInterface.class.getClassLoader(),
new Class<?>[] {SomeInterface.class},
new TestInvocationHandler(new TestImpl()));
它的作用:TestInvocationHandler 扩展了 InvocationHandler 接口。TestImpl 是一个实现 SomeInterface 的类。当您从 SomeInterface 调用方法时,它将在 TestInvocationHandler 中结束。InvocationHandler 有一个方法调用,如下所示:
public Object invoke(Object proxy, Method method, Object[] args);
代理 - 对对象的引用
method - 被调用的方法
args - 方法的参数
例如,使用 AspectJ,您可以使用切入点指定应该包含在环绕通知中的内容。AspectJ 的优点是您可以操作已经编译的代码或您自己的代码,而无需任何显式编程。
例子:
@Aspect
public class MyAspect {
@Around("execution(* org.example.yourMethod(..))")
public Object doNothing(ProceedingJoinPoint pjp) {
// You can call the method or ignore the call and do your logic
return pjp.proceed();
}
}
这个http://www.hubberspot.com/2012/12/how-to-implement-around-advice-using_12.html是一个很好的例子,如何将 AspectJ 与 spring 一起使用。也许它可以帮助你作为一个起点。
用 CGlib 解释它要困难得多,所以我用 Java 动态代理来解释它。对于您的情况
// I suppose Bean implements IBean interface
IBean beanMock = (IBean) Proxy.newProxyInstance (
IBean.getClass().getClassLoader(),
new Class[] { IBean.class },
new InvocationHandler() {
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
if(method.getName().equals("convert")) {
if(args[0].toString().equals("world")) {
return "WORLD"
}
} else {
// Implement default case
}
}
});
System.out.println(beanMock.convert("world"));