State Pattern Using Spring DI

I ran into the problem of converting my state template using simple java to spring DI since I am new to spring.

In fact, I created a project using a state template, but I took the approach that each state knows that these are consecutive states, not a context class.

The context class has a currentState field, its type is IState, and it has a setState method (ISTate state).

IState has one geNext method (context context).

And in the context class that I did for a while (keepOn), keepOn is true, and in ExitState it stops processing, in this loop I call currentState.goNext ().

Each state performs some database transactions and webservice calls, and depending on the result, it sets the next state using context.setState (new StateFour ()) - for example.

The first state is set by the client after creating the context.

Code example:

public interface IState{public void goNext(Context context);} public class StateOne implements IState{ public void goNext(Context context){ //do some logic if(user.getTitle.equals("manager"){context.setState(new StateThree());} else if(user.getTitle.equals("teamLead"){context.setState(new StateTwo());} else{context.setState(new ExitState());} } } public class Context{ private boolean keepOn = true; private IState currentState; public void setState(IState state){ currentState = state; } while(keepOn){currentState.goNext(this);} } 

Now I'm trying to use the spring DI annotation, the problem I am facing is that the context will annotate the "currentState field" with @Autowired, but I need a spring container to execute the same logic if I am in state one and " if the statement "successfully enters state three" else if "inject state, otherwise enter exitState.

If I use @Qualifier (value = "stateOne"), it will indicate only the first state that implements the interface, but the other states that I set depending on the situation, I do not know how to specify it in spring.

Also, org.springframework.core.Ordered needs to specify beans orders in advance, but I do not know what values ​​I will get from the database or web service in advance, it must be specified at runtime.

So, is it possible to replace this regular java spring DI and how?

Thank you in advance for your help and sorry for the lengthening.

+4
source share
2 answers

You should use ApplicationContext . Example below:

 // Inject application context into your bean @Autowired ApplicationContext applicationContext; // Get bean from the context (equivalent to @Autowired) applicationContext.getBean(StateThree.class); 
+1
source

The most universal way to automatically connect state is to register a resolved dependency using ConfigurableListableBeanFactory . As a dependency, you can refuse the implementation of org.springframework.beans.factory.ObjectFactory<T> , which will receive the current user and create / select the state to be entered.

This is exactly what happens when you, for example, automatically create a field of type HttpServletRequest . A RequestObjectFactory will receive the current request and inject it using this implementation.

 // org.springframework.web.context.support.WebApplicationContextUtils private static class RequestObjectFactory implements ObjectFactory<ServletRequest>, Serializable { @Override public ServletRequest getObject() { return currentRequestAttributes().getRequest(); } @Override public String toString() { return "Current HttpServletRequest"; } } 
0
source

Source: https://habr.com/ru/post/1487329/


All Articles