使用Spring DI的状态模式

时间:2013-06-20 15:46:59

标签: java spring

我在使用普通java将状态模式转换为弹簧DI时遇到了问题,因为我刚接触到春天。

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

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

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

在上下文类中我做了一段时间(keepOn)keepOn为true,在ExitState中它变为false以停止处理,在这个循环中我调用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 field”但是如果我处于状态1,我需要spring容器来执行相同的逻辑并且“if statement”成功注入状态三“else if”注入状态二否则注入exitState。

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

同样org.springframework.core.Ordered需要提前指定bean的顺序,但我不知道我将提前从数据库或webservice接收的值,它应该在运行时指定。

那么可以用spring DI替换这个普通的java吗?

提前感谢您提供任何帮助,并且抱歉延长。

2 个答案:

答案 0 :(得分:1)

您应该使用 ApplicationContext 。示例如下:

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

// Get bean from the context (equivalent to @Autowired)
applicationContext.getBean(StateThree.class);

答案 1 :(得分:0)

自动连接状态的最通用方法是使用ConfigurableListableBeanFactory注册可解析的依赖关系。作为依赖项,您可以放入org.springframework.beans.factory.ObjectFactory<T>的实现,这将获得当前用户并创建/获取要注入的状态。

这正是您例如自动连接类型为HttpServletRequest的字段时所发生的情况。 RequestObjectFactory将获取当前请求并使用此实现注入它。

// 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";
    }
}