목차
콜백이란
콜백, 콜에프터 함수란 다른 코드의 인수로서 넘겨주는 실행 가능한 코드
콜백을 넘겨받는 코드는 이 콜백을 필요에 따라 즉시 실행할 수 있고, 아니면 나중에 실행할 수 있다.
public interface Callback { void call(); }
|
@Slf4j public class TimeLogTemplate {
public void execute(Callback callback){ long startTime = System.currentTimeMillis();
callback.call();
long endTime = System.currentTimeMillis(); long resultTime = endTime - startTime; log.info("resultTime = {}", resultTime); } }
|
Template Callback Pattern 실행
직접적으로 Callback 객체내 call 메소드를 실행하는 것이 아닌 TimeLogTemplate 객체에서 execute 메소드를 실행하게 되면 Callback 객체를 넘겨주고 execute 내에서 Callback 객체의 call 메소드가 실행된다.
@Slf4j public class TemplateCallbackTest {
@Test void callbackV1(){ TimeLogTemplate template = new TimeLogTemplate(); template.execute(new Callback() { @Override public void call() { log.info("비즈니스 로직 1 실행"); } });
template.execute(() -> log.info("비즈니스 로직 2 실행")); } }
|
Template Callback Pattern 적용
public class TraceTemplate {
private final LogTrace trace;
public TraceTemplate(LogTrace trace){ this.trace = trace; }
public <T> T execute(String message, TraceCallback<T> callback){ TraceStatus status = null; try{ status = trace.begin(message);
T result = callback.call(); trace.end(status); return result; }catch (Exception e){ trace.exception(status, e); throw e; } } }
|
@RestController public class OrderControllerV5 {
private final OrderServiceV5 orderService; private final TraceTemplate template;
public OrderControllerV5(OrderServiceV5 orderService, LogTrace logTrace) { this.orderService = orderService; this.template = new TraceTemplate(logTrace); }
@GetMapping("/v5/request") public String request(String itemId){
return template.execute("OrderController.request()", new TraceCallback<String>() { @Override public String call() { orderService.orderItem(itemId); return "ok"; } }); } }
|
@Service public class OrderServiceV5 {
private final OrderRepositoryV5 orderRepository; private final TraceTemplate template;
public OrderServiceV5(OrderRepositoryV5 orderRepository, LogTrace trace) { this.orderRepository = orderRepository; this.template = new TraceTemplate(trace); }
public void orderItem (String itemId){ template.execute("OrderService.orderItem()", () -> { orderRepository.save(itemId); return null; }); } }
|
@Repository public class OrderRepositoryV5 {
private final TraceTemplate template;
public OrderRepositoryV5(LogTrace logTrace) { this.template = new TraceTemplate(logTrace); }
public void save(String itemId){ template.execute("OrderRepository.save()", () -> { if(itemId.equals("ex")){ throw new IllegalStateException("예외 발생!"); } sleep(1000); return null; }); }
private void sleep(int millis) { try{ Thread.sleep(millis); }catch (InterruptedException e){ e.printStackTrace(); } } }
|