2014-09-28 3 views
1

가정하자 나는 다음과 같은 스프링 MVC 컨트롤러봄 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); 
    } 
} 

내 문제는 다음과 같다 다음 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() { 
    ... 
    } 
} 

다음과 같은 저장소

@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 클래스는 스레드로부터 안전하지 않으므로이 방법을 사용하면 경쟁 조건이 발생할 수 있습니다. 이것을 처리하는 좋은 방법은 무엇입니까? 빈 범위를 예를 들어로 변경하는 것만으로 충분합니다. 의뢰?

+1

예, 경쟁 조건이 있습니다. 왜 손으로 쓰지 않고 생성 된 Spring 저장소를 사용하지 않는가? – chrylis

+0

스프링 데이터 JPA를 의미합니까? 감사합니다. –

+3

왜 빌더를 관리 Bean ('@ Component')으로 정의합니까? 왜 당신이 무언가를 만들 필요가있을 때마다'new'로 만들지 않는 것이 좋을까요? –

답변

1

나는 Spring 빈으로 SearchQueryBuilderFactory를 사용하고, 즉시 SearchQueryBuilder 인스턴스를 생성 할 것이다.
나는 실행 중에 상태가 바뀌는 스프링 빈을 만드는 것을 피할 것이다.
웹 컨텍스트 외부에서 스프링 빈으로 사용하려고하면 문제가 다시 나타나기 때문에 요청 범위를 갖는 데 의존하게되면 솔루션이 더 취약 해지고 오류가 발생하기 쉽습니다.

+0

분명히 당신은 "요청 범위"가 의미하는 것, 즉 단순히 instatiation에 대한 지시자가 무엇인지 모릅니다. 빈 인스턴스는 HTTP 시작 부분에 생성됩니다 - 완료되면 요청 및 완료; 어떤 종류의 유용성 - 제한도 없으므로 "웹 컨텍스트 외부에서 사용하기가 쉽지 않습니다"는 것은별로 의미가 없습니다. – specializt

+1

@specializt 명백히 요청 범위가 아닌 요청 범위를 사용하려고 시도하지 않았습니다. –

+0

음 ... 그건 말도 안돼. 추측을 멈추고 일을 그만 두십시오. 요청 범위가있는 스프링 빈도 수동으로 인스턴스화 할 수 있습니다. 스프링 빈은 표준 자바 객체이므로 여기에는 전혀 마법이 없습니다. – specializt