繁体   English   中英

如何使 Java Spring 组件 class 线程安全?

[英]How can I make a Java Spring Component class thread safe?

我有一个 spring class,当你调用httpDatastoreFacade.getDatastore()它应该给你 REST 请求线程安全数据存储:

@Component
public class HttpDatastoreFacade {
  private Boolean useAttribute = Boolean.FALSE;

  public String getDatastore() {
    HttpServletRequest request = ((ServletRequestAttributes)RequestContextholder.currentRequestAttributes()).getRequest();
    String datastore = request.getParameter("datastore");

    if(useAttribute) {
      datastore = String.valueOf(request.getAttribute("datastore"));
    }

    return datastore;
  }

  public void setDatastore(String datastore, Boolean useAttribute) {
    HttpServletRequest request = ((ServletRequestAttributes)RequestContextholder.currentRequestAttributes()).getRequest();
    request.setAttribute("datastore", datastore);
    this.useAttribute = useAttribute;
  }

  public Boolean getUseAttribute() {
    return useAttribute;
  }
}

有时在我的代码中,我需要更改该datastore ,但随后我想在调用任何需要不同datastore的代码后立即将其改回:

 @Component
  public class someClass() {
    @Autowired
    private HttpDatastoreFacade datastoreFacade;

   @Autowired
   private OtherClass otherClass;

   public void someMethod() {
     String savedDatastore = datastoreFacade.getDatastore();
     String savedUseAttribute = datastoreFacade.getUseAttribute;

     //setDatastore to new settings 
     datastoreFacade.setDatastore("newStore", true);

     //this is where I call my method's or methods that need this new datastore
     otherClass.callSomeMethod();

     //set the datastore back to old value
     datastoreFacade.setDatastore(savedDatastore , savedUseAttribute );
   }
 }

我的问题是我遇到了线程问题,其中useAttribute为 true 但未在请求属性中设置datastore区。

我正在寻找更好的 java 模式,在其中我可以在执行otherClass.callSomeMethod()或我需要进行的任何其他调用时锁定HttpDatastoreFacade ,直到将HttpDatastoreFacade设置回正常状态。 otherCalss.callSomeMethod可能正在调用其他使用HttpDatastoreFacade的方法,他们可能希望根据需要设置它。 所以也许我需要一些线程安全的datastore堆栈?

@RequestScope中的一个 bean 似乎可以解决您的问题。

@Component
@RequestScope
public class X {
    //
}

您不必像清除 ThreadLocal 那样考虑清除请求作用域的 bean。 它会在相应的 ServletRequest 清理时被收集。

我最终将useAttribute ThreadLocal变量,这解决了我的问题。

private ThreadLocal<Boolean> useAttribute = new ThreadLocal<>();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM