작성자 : 황지성
Redis(레디스) | Windows 10 설치 및 기본 명령어
implementation group: 'org.redisson', name: 'redisson-spring-boot-starter', version: '3.17.5'
의존성 주입 시, 문제가 생기지 않을 수도 있다고 하는데 나는 문제가 발생했다. Redis에 관련된 의존성을 주입했을 때는 오류가 나지 않지만, Redisson에 관련된 의존성을 주입할 시, 오류가 발생하고 Spring boot가 뜨지 않는다.
해결 방법은 아래와 같다.
main/java/springfox/documentation/spring/web/plugins directory를 생성한다. 해당 디렉토리에 WebMvcRequestHandlerProvider.java 파일을 생성한 후, 아래 코드를 복붙한다.
package springfox.documentation.spring.web.plugins;
import org.redisson.api.FunctionLibrary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Conditional;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.RequestHandler;
import springfox.documentation.spi.service.RequestHandlerProvider;
import springfox.documentation.spring.web.OnServletBasedWebApplication;
import springfox.documentation.spring.web.WebMvcRequestHandler;
import springfox.documentation.spring.web.readers.operation.HandlerMethodResolver;
import javax.servlet.ServletContext;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import static java.util.stream.Collectors.*;
import static springfox.documentation.builders.BuilderDefaults.*;
import static springfox.documentation.spi.service.contexts.Orderings.*;
import static springfox.documentation.spring.web.paths.Paths.*;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@Conditional(OnServletBasedWebApplication.class)
public class WebMvcRequestHandlerProvider implements RequestHandlerProvider {
private final List<RequestMappingInfoHandlerMapping> handlerMappings;
private final HandlerMethodResolver methodResolver;
private final String contextPath;
@Autowired
public WebMvcRequestHandlerProvider(
Optional<ServletContext> servletContext,
HandlerMethodResolver methodResolver,
List<RequestMappingInfoHandlerMapping> handlerMappings) {
this.handlerMappings = handlerMappings.stream().filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
this.methodResolver = methodResolver;
this.contextPath = servletContext
.map(ServletContext::getContextPath)
.orElse(ROOT);
}
@Override
public List<RequestHandler> requestHandlers() {
returnnullToEmptyList(handlerMappings).stream()
.filter(requestMappingInfoHandlerMapping ->
!("org.springframework.integration.http.inbound.IntegrationRequestMappingHandlerMapping"
.equals(requestMappingInfoHandlerMapping.getClass()
.getName())))
.map(toMappingEntries())
.flatMap((entries -> StreamSupport.stream(entries.spliterator(), false)))
.map(toRequestHandler())
.sorted(byPatternsCondition())
.collect(toList());
}
private Function<RequestMappingInfoHandlerMapping,
Iterable<Map.Entry<RequestMappingInfo, HandlerMethod>>> toMappingEntries() {
return input -> input.getHandlerMethods()
.entrySet();
}
private Function<Map.Entry<RequestMappingInfo, HandlerMethod>, RequestHandler> toRequestHandler() {
return input -> new WebMvcRequestHandler(
contextPath,
methodResolver,
input.getKey(),
input.getValue());
}
}
그러면 해결된다.
@Transactional
public MsgResponseDto enterStore(Long storeId) { // need to update
RLock lock = redissonClient.getLock("key 이름");
int availableCnt = 0; // 이용 가능 좌석
try{
boolean isLocked = lock.tryLock(1,3, TimeUnit.SECONDS);
if(isLocked) {
try {
// 1. find store
Store store = storeRepository.findById(storeId).orElseThrow(()->
new CustomException(ErrorCode.NOT_FOUND_STORE_ERROR)
);
// 2. storeStatus check
StoreStatus storeStatus = storeStatusRepository.findByStore(store);
// 3. counting availableCnt
if((storeStatus.getAvailableTableCnt() - 1) > 0){
availableCnt = storeStatus.getAvailableTableCnt() - 1;
}
else if(storeStatus.getAvailableTableCnt() == 0){
throw new CustomException(ErrorCode.NOT_ENOUGH_TABLE);
}
else if((storeStatus.getAvailableTableCnt() - 1) < 0){
String message = Integer.toString(Math.abs(storeStatus.getAvailableTableCnt() - 1));
availableCnt = 0;
storeStatus.update(availableCnt);
return new MsgResponseDto(HttpStatus.OK.value(),"빈 자석이 없습니다. " + message + "분은 예약 등록 부탁드립니다.");
}
// 4. update storeStatus
storeStatus.update(availableCnt);
return new MsgResponseDto(SuccessCode.CONFIRM_ENTER);
}catch(Exception e){
}finally{
lock.unlock();
}
}
}catch(Exception e){
Thread.currentThread().interrupt();
}
return null;
}