Spring MVC - 比赛条件?

时间:2014-09-28 09:50:23

标签: java spring spring-mvc

假设我有以下Spring MVC控制器

@RestController
@RequestMapping("/books")
public class BooksController {

  @Autowired    
  private final BooksRepository booksRepository;

  @RequestMapping(value="/search", method=RequestMethod.POST, consumes="application/json")
  public Collection<Book> doSearch(@RequestBody final SearchCriteria criteria) {
    return booksRepository.find(criteria);
  }
}

以及以下存储库

@Service
public class BooksRepository {

  @Autowired
  private final JdbcTemplate jdbcTemplate;

  @Autowired
  private final SearchQueryBuilder searchQueryBuilder;

  public Collection<BookLite> find(final SearchCriteria criteria) {

    // TODO: will this cause race conditions?
    searchQueryBuilder.clear().addKeywords(criteria.getKeywords());

    final String query = searchQueryBuilder.buildQuery();
    final Object[] params = searchQueryBuilder.buildParams();

    return jdbcTemplate.query(query, params, new BookExtractor());
  }
}

使用以下SearchQueryBuilder实现

@Component
public class SearchQueryBuilder {

  private final List<String> keywords = new LinkedList<String>();

  public SearchQueryBuilder clear() {
    keywords.clear();
    return this;
  }

  public SearchQueryBuilder addKeywords(final List<String> keywords) {
    for (String keyword : keywords) {
        add(keyword);
    }
    return this;
  }

  private SearchQueryBuilder add(final String keyword) {
    keywords.add(keyword);
    return this;
  }

  public String buildQuery() {
    ...
  }

  public Object[] buildParams() {
    ...
  }
}

我的担忧如下。由于SearchQueryBuilder类不是线程安全的,因此以这种方式注入可能会导致竞争条件。处理这个问题的好方法是什么?是否足够(并且是一种良好的做法)将bean范围更改为例如请求?

1 个答案:

答案 0 :(得分:1)

我会使用SearchQueryBuilderFactory作为Spring bean,并动态创建SearchQueryBuilder实例。
我会避免创建在执行期间改变状态的Spring bean。
您依赖于使用请求范围会使您的解决方案更加脆弱且容易出错,因为如果您尝试将其用作Web上下文之外的Spring bean,则问题会再次出现。