Itération 122442
Itération 122442

Reputation: 2962

Execute a function "before each" method of the same class in java

I have several methods in a class that require a boolean to be set to true in order to execute correctly.

I could write the if statement in each method, but it is not convenient if I or someone else wants to ad another method. I or he could forget about the check.

Is there a way in java to execute a method before each other methods (exactly like JUnit does with @BeforeEach ) in a class ?

Edit: Lots of very interesting techniques/answers/concepts proposed. I'll be in touch when I've understood them. Thanks.

Upvotes: 9

Views: 8388

Answers (4)

Saif Asif
Saif Asif

Reputation: 5658

Lets make a method turnBooleanTrue() where effectively the boolean is set to true in order for the method to be execute correctly.

Then, you can write up your very own InvocationHandler that would intercept calls to your objects, and then reflectively (using reflection API) invoke first the turnBooleanTrue() method followed by the method to which the call was made.

Will look something like this

public class MyClassInvocationHandler implements InvocationHandler {

    // initiate an instance of the class
    MyClass myClass = new MyClassImpl();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        // look up turnBooleanTrue() method
        Method turnBooleanTrue = myClass.getClass().getMethod("turnBooleanTrue");

        // invoke the method
        turnBooleanTrue.invoke(...); // toggle the boolean

        // invoke the method to which the call was made
        // pass in instance of class
        Object returnObj = method.invoke(myClass, args);

        return returnObj;
}

EDIT

Added some lines to have an object of MyClass initialized. You need something to invoke the method on and maintain the state. Changed util to myClass in the code example above.

Upvotes: 6

Itération 122442
Itération 122442

Reputation: 2962

Considering my use case, it was a bit overkill to use AOP or other concepts. So I basically did a check in each functions.

Upvotes: 1

Tschallacka
Tschallacka

Reputation: 28722

I suggest a simple solution by dividing your workflow in four components.

You have an interface you use to execute commands.
You have an interface that defines which commands you can use.
You have one wrapper that analyzes your boolean value.
You have an implementation of the work performing class, that implements the second interface.

Your wrapper initialize the worker.
Your wrapper exposes an action performing command that accepts the executing interface.
if the boolean is true, pass the worker to the executing interface work method.
the executing interfaces work method calls the work function on the command instance interface, the worker.

See it online: https://ideone.com/H6lQO8

class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        WorkDistributer wd = new WorkDistributer();
        wd.enable();
        wd.performAction((w) -> {w.printHello();});
        wd.disable();
        wd.performAction((w) -> {w.printHello();});
        wd.enable();
        wd.performAction((w) -> {w.printAnswer();});
        wd.disable();
        wd.performAction((w) -> {w.printAnswer();});
    }
}
class WorkDistributer 
{
    private boolean enabled = false;
    private ActionPerformer worker;
    public WorkDistributer() {
        this.worker = new Worker();
    }
    public void enable() {
       enabled = true;
    }
    public void disable() {
        enabled = false;
    }
    public void performAction(ActionCommand command) {
        if(this.enabled) {
           command.run(this.worker);
        }
    }
}
class Worker implements ActionPerformer {
    public void printHello() {
        System.out.println("hello");
    }
    public void printAnswer() {
        System.out.println(21 * 2);
    }
}

interface ActionPerformer {
    public void printHello();
    public void printAnswer();
}

interface ActionCommand {
    public void run(ActionPerformer worker);
}

Upvotes: 0

daniu
daniu

Reputation: 14999

With AOP, this is how what you need would look:

// wraps around all methods in your class that have a boolean parameter
@Around(value = "@target(*..YourClass) && args(yourBool)", argNames = "jp,yourBool")
Object scheduleRequest(ProceedingJoinPoint jp, boolean yourBool) {
    if (yourBool) {
        jp.proceed(yourBool);
    } else {
        throw new RuntimeException("cannot execute this method!");
    }
}

This would handle the case that the method take the boolean you say needs evaluation as its (only) parameter. If it comes from a different source, you may need to wire it into the aspect somehow, that depends on your overall design.

Upvotes: 0

Related Questions