java 如何在不重复其他方法的情况下调用方法
How to call a method without repeat from other methods in java
例如,我有数千种方法:
AA() {
...
}
BB() {
...
}
CC() {
...
}
etc ...
现在我想在每个方法的开头调用一个方法 printCurrentMethodName()。也就是说,
AA() {
printCurrentMethodName();
...
}
BB() {
printCurrentMethodName();
...
}
CC() {
printCurrentMethodName();
...
}
etc ...
在数千个方法的开头包含 printCurrentMethodName() 非常耗时。
有什么方法可以在每个方法的开头调用 printCurrentMethodName() 而无需在数千个方法中重复它?
(我不能使用@Before 或@BeforeMethod 之类的注释,因为它会在进入 AA() 之前调用 printCurrentMethodName(),因此它不会按预期打印方法名称)
您可以使用正则表达式在每个函数上插入此调用。
将(\w+\(\w*\)\s*\{)
替换为\nprintCurrentMethodName();
您可以使用 java.lang.reflect.InvocationHandler
来达到这个目的。
在你的 class 中的任何方法被调用之前(AA
、BB
、CC
等)你的 invoke
方法=16=] 被调用。在 invoke
方法中,您可以访问被调用的实际方法,并且可以添加其他逻辑,例如打印被调用方法的名称,以便在调用实际方法之前或之后执行。
代码示例:
public class PrintClassName {
public static void main(String[] a) {
Service srv = (Service) Proxy.newProxyInstance(
PrintClassName.class.getClassLoader(),
new Class<?>[]{Service.class},
new PrintingMethodNameHandler(new ServiceImpl())
);
srv.doNothing();
}
}
interface Service {
void doNothing();
}
class ServiceImpl implements Service {
public void doNothing() { }
}
class PrintingMethodNameHandler implements InvocationHandler {
private Service service;
public PrintingMethodNameHandler(final Service service) {
this.service = service;
}
@Override
public Object invoke(final Object proxy, final Method method,
final Object[] args) throws Throwable {
System.out.println(method.getName());
return method.invoke(service, args);
}
}
很简单,将这一行放在你的方法中。
System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
使用 AspectJ 注释怎么样。
对于前任
常见的 AspectJ 注释:
1.@Before – 运行方法执行前
2.@After – 运行方法返回结果后
3.@AfterReturning – 运行方法返回结果后,也截取返回结果
4.@AfterThrowing – 运行方法抛出异常后
5.@Around – 运行围绕方法执行,结合以上所有三个建议。
这可能会解决您的问题。
返回的时候可以用这个调用方法,
您可以按照 this 教程进行操作。
如果您只想打印测试方法的名称,那么您可以创建一个 JUnit rule that is similar to the TestName rule
public class PrintTestName extends TestWatcher {
@Override
protected void starting(Description d) {
System.out.println(d.getMethodName());
}
}
并在你的测试中使用它
public class YourTest {
@Rule
public final PrintTestName printTestName = new PrintTestName();
@Test
public AA() {
...
}
...
例如,我有数千种方法:
AA() {
...
}
BB() {
...
}
CC() {
...
}
etc ...
现在我想在每个方法的开头调用一个方法 printCurrentMethodName()。也就是说,
AA() {
printCurrentMethodName();
...
}
BB() {
printCurrentMethodName();
...
}
CC() {
printCurrentMethodName();
...
}
etc ...
在数千个方法的开头包含 printCurrentMethodName() 非常耗时。
有什么方法可以在每个方法的开头调用 printCurrentMethodName() 而无需在数千个方法中重复它?
(我不能使用@Before 或@BeforeMethod 之类的注释,因为它会在进入 AA() 之前调用 printCurrentMethodName(),因此它不会按预期打印方法名称)
您可以使用正则表达式在每个函数上插入此调用。
将(\w+\(\w*\)\s*\{)
替换为\nprintCurrentMethodName();
您可以使用 java.lang.reflect.InvocationHandler
来达到这个目的。
在你的 class 中的任何方法被调用之前(AA
、BB
、CC
等)你的 invoke
方法=16=] 被调用。在 invoke
方法中,您可以访问被调用的实际方法,并且可以添加其他逻辑,例如打印被调用方法的名称,以便在调用实际方法之前或之后执行。
代码示例:
public class PrintClassName {
public static void main(String[] a) {
Service srv = (Service) Proxy.newProxyInstance(
PrintClassName.class.getClassLoader(),
new Class<?>[]{Service.class},
new PrintingMethodNameHandler(new ServiceImpl())
);
srv.doNothing();
}
}
interface Service {
void doNothing();
}
class ServiceImpl implements Service {
public void doNothing() { }
}
class PrintingMethodNameHandler implements InvocationHandler {
private Service service;
public PrintingMethodNameHandler(final Service service) {
this.service = service;
}
@Override
public Object invoke(final Object proxy, final Method method,
final Object[] args) throws Throwable {
System.out.println(method.getName());
return method.invoke(service, args);
}
}
很简单,将这一行放在你的方法中。
System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
使用 AspectJ 注释怎么样。
对于前任
常见的 AspectJ 注释: 1.@Before – 运行方法执行前
2.@After – 运行方法返回结果后
3.@AfterReturning – 运行方法返回结果后,也截取返回结果
4.@AfterThrowing – 运行方法抛出异常后
5.@Around – 运行围绕方法执行,结合以上所有三个建议。
这可能会解决您的问题。 返回的时候可以用这个调用方法,
您可以按照 this 教程进行操作。
如果您只想打印测试方法的名称,那么您可以创建一个 JUnit rule that is similar to the TestName rule
public class PrintTestName extends TestWatcher {
@Override
protected void starting(Description d) {
System.out.println(d.getMethodName());
}
}
并在你的测试中使用它
public class YourTest {
@Rule
public final PrintTestName printTestName = new PrintTestName();
@Test
public AA() {
...
}
...