0
votes

My project is using Spring web flow 2.4, and I need to use Spring AOP to advice flow scope bean to handle aspect requirement like logging. Here is the aspect class:

@Aspect
@Component
public class LogFlowEventExecutor {
    @Pointcut("execution(public * com.xyz.app.flow.*FlowBean.*(..))")
    private void flowFunction() {}

    @Before("flowOperation()")
    public void logFlowEvent(JoinPoint jp) throws Throwable {
        //logic ignored
        ...
    }
}

And defines autoproxy in the root WebApplicationContext:

<aop:aspectj-autoproxy />

And each individual -flow.xml file

<flow xmlns="http://www.springframework.org/schema/webflow"...>
    <var name="abcFlowBean" class="com.xyz.app.flow.AbcFlowBean" />
    ...
</flow>

I used the same pattern to easily advice Service beans and Controllers, but it didn't work on flow scoped beans, the aspect is never executed. I thought it might be something with the JDK dynamic interface proxy, however it failed with CGLIB as well (proxy-target-class="true" attribute was set). The pointcut never got intercepted. So I doubted the flow-scope bean was never properly proxied when it's instantiated.

I tried to switch to LTW, but it threw an NoSuchMethodError (the bean was woven from the weaveinfo log). Maybe it's better to open another thread for that alone.

My question is that will it be possible to use Spring AOP to advice a flow scope bean and how to do it?

1

1 Answers

0
votes

I worked around this issue by writing a Flow Execution Listener, basically the FlowExecutionListener defines a lot of callback methods that will be invoked when certain things happen in the course of a flow execution life cycle. So I created a custom listener class extends from FlowExecutionListenerAdapter that implements all methods by using empty method bodies and override what I am interested about, and this almost has the same kind of effect like AOP if you want global callbacks on all flow scope beans. But if you only need to intercept a few of them, then that's another story.

public class MyFlowExecutionListener extends FlowExecutionListenerAdapter{
    @Override
    public void eventSignaled(RequestContext context, Event event) {...}
    @Override
    public void transitionExecuting(RequestContext context, TransitionDefinition transition) {...}
    @Override
    public void viewRendered(RequestContext context, View view, StateDefinition viewState) {...}
    @Override
    public void exceptionThrown(RequestContext context, FlowExecutionException exception) {...}
    ...
}