Java:是否可以始终在调用其他函数之前执行某个函数? (就像JUnit中的@Before一样) [英] Java: Is it possible to always execute a certain function before other functions are called? (Like @Before in JUnit)

查看:616
本文介绍了Java:是否可以始终在调用其他函数之前执行某个函数? (就像JUnit中的@Before一样)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以在调用某个类的任何其他函数之前始终执行一个函数?

Is there a way to always execute a function before any other function of a class is called?

我有一个类,需要在此之前刷新所有字段任何函数都将被调用:

I have a class where I need to refresh some fields always before any function is called:

public class Example {

private int data;

public void function1(){

}

public void function2(){

}

//@BeforeOtherFunction
private void refresh(){
    // refresh data
}
}

由于似乎编程不好,我不想在其他开始时调用刷新功能。由于其他人也将从事此项目,因此存在危险,即有人会扩展呼叫而不会呼叫刷新

Because it seems to be bad programming, I don't want to call refresh at the beginning of every other function. Since other persons are going to work on this project as well, there would be the danger, that somebody extends the calls and doesn't call refresh.

JUnit通过 @Before -Annotation解决了这个问题。

JUnit has a solution for this with the @Before-Annotation. Is there a way to do this in other classes as well?

并且顺便说一句:如果您知道编程模式可以通过执行函数以外的其他方式解决此问题每次调用任何函数时,这也将非常有帮助!

And by the way: If you know a programming pattern wich solves this problem in another way than executing a function everytime any function is called, that would be very helpful, too!

推荐答案

使用动态代理,您可以在其中过滤这些内容方法,在此之前应调用您的特定 before方法。在这种情况下,请在分派呼叫之前进行呼叫。请从如何拦截具有标准Java功能(无AspectJ等)的方法调用?

Use a dynamic proxy in which you can filter to those methods before which your specific "before" method should be called. And call it in those cases before dispatching the call. Please see the answer from How do I intercept a method invocation with standard java features (no AspectJ etc)?

更新:

需要为代理分隔接口。 refresh()方法不能保持私有。它必须是公共的,并且是接口的一部分(此处不是很好),以便可以从代理中调用。

An interface is needed to be separated for the proxy. The refresh() method cannot remain private. It must be public and part of the interface (which is not nice here) to be able to be called from the proxy.

package CallBefore;

public interface ExampleInterface {
    void function1();

    void function2();

    void otherFunction();

    void refresh();
}

您的课程实现了该接口:

Your class implements that interface:

package CallBefore;

public class Example implements ExampleInterface {

    @Override
    public void function1() {
    System.out.println("function1() has been called");
    }

    @Override
    public void function2() {
    System.out.println("function2() has been called");
    }

    @Override
    public void otherFunction() {
    System.out.println("otherFunction() has been called");
    }

    @Override
    public void refresh() {
    System.out.println("refresh() has been called");
    }
}

实现此目的的代理。

package CallBefore;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ExampleProxy implements InvocationHandler {

    private ExampleInterface obj;

    public static ExampleInterface newInstance(ExampleInterface obj) {
    return (ExampleInterface) java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
        obj.getClass().getInterfaces(), new ExampleProxy(obj));
    }

    private ExampleProxy(ExampleInterface obj) {
    this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
    Object result;
    try {
        if (m.getName().startsWith("function")) {
        obj.refresh();
        }
        result = m.invoke(obj, args);
    } catch (InvocationTargetException e) {
        throw e.getTargetException();
    } catch (Exception e) {
        throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
    }
    return result;
    }
}

用法:

package CallBefore;

public class Main {

    public static void main(String[] args) {

    ExampleInterface proxy = ExampleProxy.newInstance(new Example());
    proxy.function1();
    proxy.function2();
    proxy.otherFunction();
    proxy.refresh();
    }
}

输出:

refresh() has been called
function1() has been called
refresh() has been called
function2() has been called
otherFunction() has been called
refresh() has been called

这篇关于Java:是否可以始终在调用其他函数之前执行某个函数? (就像JUnit中的@Before一样)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆