6

由于我是 Spring 新手,因此在使用普通 Java 将状态模式转换为 Spring DI 时遇到了问题。

实际上,我使用状态模式制作了一个项目,但我采用的方法是每个状态都知道它是连续状态而不是上下文类。

上下文类有一个字段“currentState”,它的类型是 IState,它有方法 setState(IState state)。

IState 有一个方法 geNext(Context context)。

在上下文类中,我设置了一个 while(keepOn) keepOn 为真,它在 ExitState 中变为假以停止处理,在这个循环中我调用 currentState.goNext()。

每个状态都会进行一些数据库事务和 web 服务的调用,并根据结果使用 context.setState(new StateFour()) 设置下一个状态 - 例如 -。

第一个状态由客户端在创建上下文后设置。

代码示例:

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);}
}

现在我正在尝试使用基于 Spring DI 注释的问题,我面临的问题是上下文将使用 @Autowired 注释“currentState 字段”但是如果我处于状态一并且“如果声明”成功注入状态三“else if”注入状态二否则注入exitState。

如果我使用 @Qualifier(value ="stateOne") 它将仅指定实现接口的第一个状态,但我根据情况设置的其他状态我不知道如何在 spring 中指定它。

另外 org.springframework.core.Ordered 需要提前指定 bean 的顺序,但我不知道我会提前从数据库或 web 服务收到的值,它应该在运行时指定。

那么有没有可能用spring DI替换这个普通的java以及如何?

在此先感谢您的帮助,并抱歉延长。

4

2 回答 2

1

您应该使用ApplicationContext。下面的例子:

// Inject application context into your bean
@Autowired
ApplicationContext applicationContext;

// Get bean from the context (equivalent to @Autowired)
applicationContext.getBean(StateThree.class);
于 2014-07-23T12:32:48.323 回答
0

The most versatile way to auto wire the state is by registering a resolvable dependency with a ConfigurableListableBeanFactory. As a dependency you could drop in your implementation of org.springframework.beans.factory.ObjectFactory<T> which will get the current user and creates/fetches the state to be injected.

This is exactly what happens when you, for instance, auto wire a field of type HttpServletRequest. A RequestObjectFactory will get 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";
    }
}
于 2014-08-01T13:28:37.553 回答