如何在Spring中拦截静态方法?
主题行基本上说明了一切。我有一个静态方法要拦截,以便可以将周围的建议应用于该方法。我可以使它与任何非静态方法一起使用,但是我不确定如何允许静态方法被拦截。
回答:
使用Spring AOP不能做到这一点,因为它是基于代理的。你必须使用AspectJ
在看到我的一些同事开发的MockME之后,我开始思考如何以通用的方式来制作它。例如,我们将如何模拟以下课程?看一个简单的例子
public class StupidSingleton { public static String doStatic(int i) {
throw new UnsupportedOperationException("method not implemented yet...");
}
public static void sayHello() {
System.out.println("Hello");
}
public static native void nativeMethod();
}
我们想写这样的东西:
public void testMocking() { mock(StupidSingleton.class);
expect(StupidSingleton.doStatic(17)).andReturn("17");
StupidSingleton.sayHello();
StupidSingleton.nativeMethod();
replay(StupidSingleton.class);
assertEquals("17", StupidSingleton.doStatic(17));
StupidSingleton.sayHello();
StupidSingleton.nativeMethod();
verify(StupidSingleton.class);
}
在玩过AspectJ之后,我发现这实际上是可行的!需要两件事:
- 使我们能够捕获对静态方法的调用的方面!
- 模拟,重播,验证类的实现
事实证明,这真的很容易!以下方面捕获对所有静态方法的所有调用。可能会有些攻击性,但是可以!如果需要,可以使用更专业的切入点实现自己的方面。
@Aspectpublic class StaticMockAll extends StaticMockAspect {
@Pointcut("call(static * *(..))")
public void anyStaticOperation() {}
@Around("anyStaticOperation()")
public Object aroundStaticMethods(ProceedingJoinPoint jp) throws Throwable {
return super.aroundStaticMethods(jp);
}
}
模拟,重播,验证方法非常简单:
public class StaticMock { static Map mocks = new HashMap();
public static synchronized void mock(Class type) {
MockInvocationHandler h = new MockInvocationHandler((MocksControl) EasyMock.createControl());
mocks.put(type, h);
}
public static synchronized void replay(Class type) {
mocks.get(type).getControl().replay();
}
public static synchronized void verify(Class type) {
mocks.remove(type).getControl().verify();
}
}
最后,进行实际工作的方面的基类也非常简单:
public class StaticMockAspect { public Object aroundStaticMethods(ProceedingJoinPoint jp) throws Throwable {
Class type = jp.getSignature().getDeclaringType();
InvocationHandler h = getInvocationHandler(type);
if (h == null) {
return jp.proceed();
}
MethodSignature methodSignature = ((MethodSignature)jp.getSignature());
return h.invoke(type, methodSignature.getMethod(), jp.getArgs());
}
private MockInvocationHandler getInvocationHandler(Class type) {
synchronized (StaticMock.class) {
return StaticMock.mocks.get(type);
}
}
}
h3。笔记
需要注意和考虑的事情:
- 可以模拟静态方法和本机方法!通过使用“调用”切入点,我们可以更改所有试图调用本机方法而不是本机方法本身的代码。
- 要完成这项工作,必须使用AspectJ。我一直在使用Eclipse AJDT
- 应该可以用“普通”字节代码操作替换Aspect并“重新”加载类。
以上是 如何在Spring中拦截静态方法? 的全部内容, 来源链接: utcz.com/qa/435032.html