쪽지발송 성공
Click here
재능넷 이용방법
재능넷 이용방법 동영상편
가입인사 이벤트
판매 수수료 안내
안전거래 TIP
재능인 인증서 발급안내

🌲 지식인의 숲 🌲

🌳 디자인
🌳 음악/영상
🌳 문서작성
🌳 번역/외국어
🌳 프로그램개발
🌳 마케팅/비즈니스
🌳 생활서비스
🌳 철학
🌳 과학
🌳 수학
🌳 역사
해당 지식과 관련있는 인기재능

프로그래밍 15년이상 개발자입니다.(이학사, 공학 석사) ※ 판매자와 상담 후에 구매해주세요. 학습을 위한 코드, 게임, 엑셀 자동화, 업...

AS규정기본적으로 A/S 는 평생 가능합니다. *. 구매자의 요청으로 수정 및 보완이 필요한 경우 일정 금액의 수고비를 상호 협의하에 요청 할수 있...

안녕하세요!!!고객님이 상상하시는 작업물 그 이상을 작업해 드리려 노력합니다.저는 작업물을 완성하여 고객님에게 보내드리는 것으로 거래 완료...

30년간 직장 생활을 하고 정년 퇴직을 하였습니다.퇴직 후 재능넷 수행 내용은 쇼핑몰/학원/판매점 등 관리 프로그램 및 데이터 ...

Spring @Async와 CompletableFuture를 이용한 비동기 처리

2024-10-24 00:27:44

재능넷
조회수 771 댓글수 0

🚀 Spring @Async와 CompletableFuture를 이용한 비동기 처리의 세계로! 🌟

 

 

안녕하세요, 코딩 탐험가 여러분! 오늘은 정말 흥미진진한 주제로 여러분을 찾아왔습니다. 바로 Spring의 @Async 어노테이션과 CompletableFuture를 이용한 비동기 처리에 대해 알아볼 거예요. 이 주제는 마치 재능넷에서 다양한 재능이 동시에 거래되는 것처럼, 여러 작업을 효율적으로 처리하는 방법을 다룹니다. 자, 그럼 우리의 코딩 모험을 시작해볼까요? 🏄‍♂️

🎓 학습 목표:

  • Spring의 @Async 어노테이션 이해하기
  • CompletableFuture의 개념과 사용법 익히기
  • 비동기 처리의 장점과 주의점 파악하기
  • 실제 프로젝트에 비동기 처리 적용하기

🌈 비동기 처리란 무엇일까요?

비동기 처리라는 말, 들어보셨나요? 🤔 간단히 말해, 작업을 기다리지 않고 다른 일을 할 수 있게 해주는 마법이라고 할 수 있어요. 재능넷에서 여러분이 동시에 여러 재능을 탐색하고 거래할 수 있는 것처럼, 프로그램도 여러 작업을 동시에 처리할 수 있답니다!

🌟 비동기 처리의 장점:

  • 시간 절약: 여러 작업을 동시에 처리할 수 있어요.
  • 효율성 증가: 자원을 더 효율적으로 사용할 수 있어요.
  • 반응성 향상: 사용자 경험이 더 좋아집니다.

자, 이제 비동기 처리가 뭔지 대략 감이 오시나요? 그럼 이제 본격적으로 Spring의 @Async와 CompletableFuture에 대해 알아볼까요? 🚀

🍃 Spring의 @Async 어노테이션 살펴보기

Spring Framework는 정말 많은 기능을 제공하는데요, 그 중에서도 @Async 어노테이션은 비동기 처리의 핵심이라고 할 수 있어요. 이 어노테이션을 사용하면, 메소드를 비동기적으로 실행할 수 있게 됩니다. 마치 재능넷에서 여러 재능을 동시에 탐색하는 것처럼 말이죠! 😉

🔍 @Async 사용법:


@Service
public class MyService {
    @Async
    public void asyncMethod() {
        // 비동기로 실행될 코드
    }
}
    

이렇게 간단히 @Async 어노테이션을 메소드 위에 붙이면, 해당 메소드는 별도의 스레드에서 비동기적으로 실행됩니다. 놀랍지 않나요? 🎉

하지만 여기서 끝이 아닙니다! @Async를 사용할 때는 몇 가지 주의할 점이 있어요:

  • 반환 타입에 주의하세요: void나 Future 타입을 사용해야 합니다.
  • self-invocation에 주의하세요: 같은 클래스 내에서 @Async 메소드를 호출하면 동작하지 않습니다.
  • 예외 처리에 신경 쓰세요: 비동기 메소드에서 발생한 예외는 별도로 처리해야 합니다.

이제 @Async에 대해 어느 정도 이해가 되셨나요? 그렇다면 이제 CompletableFuture로 넘어가볼까요? 🚀

🔮 CompletableFuture의 마법

CompletableFuture는 Java 8에서 도입된 비동기 프로그래밍의 강력한 도구입니다. 이름에서 알 수 있듯이, 미래에 완료될 작업을 나타내는 객체예요. 재능넷에서 여러분이 원하는 재능을 찾는 과정을 상상해보세요. 여러분은 검색을 시작하고, 결과가 나올 때까지 다른 일을 할 수 있죠. CompletableFuture도 이와 비슷합니다! 🕵️‍♂️

🎭 CompletableFuture의 주요 특징:

  • 비동기 작업의 결과를 표현
  • 작업의 완료를 수동으로 설정 가능
  • 여러 비동기 작업을 조합하고 연결 가능
  • 예외 처리를 위한 다양한 메소드 제공

자, 이제 CompletableFuture를 어떻게 사용하는지 살펴볼까요? 🧐


CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    // 비동기로 실행될 코드
    return "Hello, Async World!";
});

future.thenAccept(result -> System.out.println(result));
  

이 코드에서 supplyAsync()는 비동기적으로 작업을 실행하고, thenAccept()는 작업이 완료되었을 때 결과를 처리합니다. 마치 재능넷에서 재능을 검색하고 결과를 받아보는 것과 비슷하죠? 😉

CompletableFuture는 정말 다양한 메소드를 제공합니다. 몇 가지 더 살펴볼까요?

  • thenApply(): 결과를 변환
  • thenCompose(): 두 개의 비동기 작업을 순차적으로 실행
  • thenCombine(): 두 개의 비동기 작업을 병렬로 실행하고 결과 결합
  • exceptionally(): 예외 처리

이렇게 다양한 메소드를 활용하면, 복잡한 비동기 로직도 우아하게 처리할 수 있답니다. 마치 재능넷에서 여러 재능을 조합해 새로운 가치를 만들어내는 것처럼 말이죠! 🌈

🤹 @Async와 CompletableFuture의 환상적인 콜라보

자, 이제 @Async와 CompletableFuture를 함께 사용하는 방법을 알아볼까요? 이 둘을 조합하면 정말 강력한 비동기 처리를 구현할 수 있어요. 마치 재능넷에서 여러 재능을 조합해 더 큰 가치를 만들어내는 것처럼 말이죠! 🎭

🌟 @Async와 CompletableFuture 사용 예시:


@Service
public class AsyncService {
    @Async
    public CompletableFuture<String> asyncMethod() {
        // 비동기 작업 수행
        return CompletableFuture.completedFuture("Async task completed!");
    }
}

// 사용 예
CompletableFuture<String> future = asyncService.asyncMethod();
future.thenAccept(result -> System.out.println(result));
    

이 예시에서 @Async 어노테이션은 메소드를 비동기적으로 실행하게 만들고, CompletableFuture는 그 비동기 작업의 결과를 표현합니다. 이렇게 하면 메소드 호출자는 즉시 CompletableFuture를 받아 다른 작업을 계속할 수 있죠. 👨‍💻

이 방식의 장점은 무엇일까요?

  • 유연성: CompletableFuture의 다양한 메소드를 활용할 수 있어요.
  • 확장성: 여러 비동기 작업을 쉽게 조합할 수 있어요.
  • 가독성: 비동기 로직을 명확하게 표현할 수 있어요.
  • 예외 처리: CompletableFuture의 예외 처리 메커니즘을 활용할 수 있어요.

이제 여러분도 @Async와 CompletableFuture를 자유자재로 다룰 수 있겠죠? 마치 재능넷에서 다양한 재능을 자유롭게 탐색하고 활용하는 것처럼 말이에요! 🚀

🏗️ 실제 프로젝트에 적용하기

자, 이제 우리가 배운 내용을 실제 프로젝트에 적용해볼 시간이에요! 재능넷과 같은 플랫폼을 개발한다고 상상해봅시다. 어떤 부분에 비동기 처리를 적용할 수 있을까요? 🤔

🌟 비동기 처리 적용 예시:

  1. 사용자 프로필 업데이트
  2. 대량 이메일 발송
  3. 복잡한 검색 쿼리 실행
  4. 외부 API 호출
  5. 대용량 파일 업로드/다운로드

이 중에서 "복잡한 검색 쿼리 실행"을 예로 들어 코드를 작성해볼까요? 🧑‍💻


@Service
public class SearchService {
    @Async
    public CompletableFuture<List<TalentDto>> searchTalents(String keyword) {
        return CompletableFuture.supplyAsync(() -> {
            // 복잡한 검색 로직 수행
            List<TalentDto> results = performComplexSearch(keyword);
            return results;
        });
    }

    private List<TalentDto> performComplexSearch(String keyword) {
        // 실제 검색 로직 구현
        // ...
    }
}

@RestController
public class SearchController {
    @Autowired
    private SearchService searchService;

    @GetMapping("/search")
    public CompletableFuture<ResponseEntity<List<TalentDto>>> search(@RequestParam String keyword) {
        return searchService.searchTalents(keyword)
            .thenApply(results -> ResponseEntity.ok(results))
            .exceptionally(ex -> ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
    }
}
  

이 예시에서 searchTalents 메소드는 @Async 어노테이션을 사용해 비동기적으로 실행됩니다. 복잡한 검색 로직은 별도의 스레드에서 수행되고, 결과는 CompletableFuture로 반환됩니다. 🔍

컨트롤러에서는 이 CompletableFuture를 그대로 반환하고 있는데, 이는 Spring MVC가 비동기 요청을 지원하기 때문입니다. 클라이언트의 요청은 즉시 반환되고, 결과가 준비되면 응답이 전송됩니다. 👨‍🏫

이렇게 비동기 처리를 적용하면 어떤 장점이 있을까요?

  • 응답성 향상: 사용자는 긴 대기 시간 없이 빠른 응답을 받을 수 있어요.
  • 서버 리소스 효율적 사용: 여러 요청을 동시에 처리할 수 있어요.
  • 확장성: 시스템의 부하를 더 잘 관리할 수 있어요.

이제 여러분도 재능넷과 같은 플랫폼을 개발할 때 비동기 처리를 적용할 수 있겠죠? 사용자들에게 더 나은 경험을 제공할 수 있을 거예요! 🌟

⚠️ 주의사항 및 베스트 프랙티스

비동기 프로그래밍은 강력하지만, 동시에 복잡성을 증가시킬 수 있어요. 재능넷에서 다양한 재능을 관리하는 것처럼, 비동기 코드도 신중하게 관리해야 합니다. 몇 가지 주의사항과 베스트 프랙티스를 알아볼까요? 🧐

🚨 주의사항:

  • 데드락 주의: 비동기 작업 간 순환 의존성을 만들지 않도록 주의하세요.
  • 리소스 관리: 너무 많은 비동기 작업을 동시에 실행하지 않도록 주의하세요.
  • 예외 처리: 비동기 작업의 예외를 적절히 처리하지 않으면 시스템이 불안정해질 수 있어요.
  • 테스트의 어려움: 비동기 코드는 테스트하기 어려울 수 있으므로 테스트 전략을 잘 세워야 해요.

이러한 주의사항을 염두에 두고, 다음과 같은 베스트 프랙티스를 따르는 것이 좋습니다:

  1. 적절한 스레드 풀 사용: @Async 작업을 위한 전용 스레드 풀을 구성하세요.
  2. 타임아웃 설정: 모든 비동기 작업에 적절한 타임아웃을 설정하세요.
  3. 에러 핸들링: CompletableFuture의 exceptionally() 또는 handle() 메소드를 활용하세요.
  4. 비동기 작업 모니터링: 로깅과 모니터링 도구를 활용해 비동기 작업을 추적하세요.
  5. 단위 테스트 작성: MockExecutor를 사용해 비동기 코드를 테스트하세요.

이러한 베스트 프랙티스를 따르면, 재능넷과 같은 복잡한 시스템에서도 안정적이고 효율적인 비동기 처리를 구현할 수 있을 거예요! 💪

🎓 심화 학습: 비동기 프로그래밍의 더 깊은 이해

자, 이제 우리는 @Async와 CompletableFuture의 기본을 마스터했어요. 하지만 비동기 프로그래밍의 세계는 더 깊고 넓답니다. 마치 재능넷에서 계속해서 새로운 재능을 발견하는 것처럼 말이죠! 좀 더 심화된 내용을 살펴볼까요? 🕵️‍♂️

🌟 심화 주제:

  1. Reactive Programming과의 연계
  2. 비동기 프로그래밍 패턴
  3. 성능 최적화 기법
  4. 분산 시스템에서의 비동기 처리

1. Reactive Programming과의 연계

Spring WebFlux와 Project Reactor를 사용하면 더욱 강력한 비동기 프로그래밍을 구현할 수 있어요. CompletableFuture를 Mono나 Flux로 변환하는 방법을 알아볼까요?


Mono<String> mono = Mono.fromFuture(completableFuture);
Flux<String> flux = Flux.from(mono);
  

이렇게 하면 CompletableFuture의 결과를 리액티브 스트림으로 처리할 수 있어요. 재능넷의 실시간 검색 기능을 구현한다고 생각해보세요. 사용자의 입력에 따라 실시간으로 결과를 제공할 수 있을 거예요! 🚀

2. 비동기 프로그래밍 패턴

비동기 프로그래밍에는 여러 가지 패턴이 있어요. 대표적인 몇 가지를 살펴볼까요?

  • Promise 패턴: CompletableFuture가 이 패턴을 구현하고 있어요.
  • Observer 패턴: 이벤트 기반 비동기 처리에 유용해요.
  • Actor 모델: 동시성 문제를 해결하는 또 다른 접근 방식이에요.

이러한 패턴들을 이해하고 적절히 활용하면, 재능넷과 같은 복잡한 시스템에서도 효율적인 비동기 처리를 구현할 수 있어요. 👨‍🔬

3. 성능 최적화 기법

비동기 프로그래밍을 통해 성능을 향상시킬 수 있지만, 잘못 사용하면 오히려 성능이 저하될 수 있어요. 다음과 같은 최적화 기법을 고려해보세요:

  • 적절한 병렬 처리: CompletableFuture.allOf()를 사용해 여러 작업을 병렬로 처리해보세요.
  • 캐싱: 자주 사용되는 비동기 작업의 결과를 캐싱하세요.
  • 백프레셔(Backpressure) 관리: 데이터 생성 속도와 소비 속도의 균형을 맞추세요.

이러한 기법들을 적용하면, 재능넷의 검색 기능이나 추천 시스템의 성능을 크게 향상시킬 수 있을 거예요! 💪

4. 분산 시스템에서의 비동기 처리

대규모 시스템에서는 여러 서버가 협력하여 작업을 처리해야 해요. 이때 비동기 처리는 더욱 중요해집니다.

  • 메시지 큐: RabbitMQ나 Apache Kafka를 사용해 비동기 메시지를 처리해보세요.
  • 이벤트 소싱: 시스템의 상태 변화를 이벤트로 관리하는 방식을 고려해보세요.
  • CQRS 패턴: 명령과 조회를 분리하여 시스템의 확장성을 높여보세요.

이러한 기술들을 활용하면, 재능넷과 같은 대규모 플랫폼에 서도 안정적이고 확장 가능한 비동기 시스템을 구축할 수 있을 거예요. 마치 전 세계의 다양한 재능을 하나의 플랫폼에서 원활하게 연결하는 것처럼 말이죠! 🌍

🎨 실전 예제: 재능넷 스타일의 비동기 시스템 구현

자, 이제 우리가 배운 모든 것을 종합해서 재능넷과 유사한 시스템의 일부를 구현해볼까요? 이 예제에서는 사용자가 새로운 재능을 등록할 때 발생하는 여러 비동기 작업을 처리하는 방법을 보여드릴게요. 🚀


@Service
public class TalentRegistrationService {

    @Autowired
    private TalentRepository talentRepository;

    @Autowired
    private UserNotificationService notificationService;

    @Autowired
    private SearchIndexService searchIndexService;

    @Autowired
    private RecommendationService recommendationService;

    @Async
    public CompletableFuture<TalentDTO> registerTalent(TalentDTO talentDTO) {
        return CompletableFuture.supplyAsync(() -> {
            // 1. 재능 정보 저장
            Talent savedTalent = talentRepository.save(new Talent(talentDTO));
            
            // 2. 비동기 작업들 시작
            CompletableFuture<Void> notificationFuture = notificationService.notifyAdmins(savedTalent);
            CompletableFuture<Void> indexingFuture = searchIndexService.indexTalent(savedTalent);
            CompletableFuture<Void> recommendationFuture = recommendationService.updateRecommendations(savedTalent);

            // 3. 모든 비동기 작업이 완료될 때까지 대기
            CompletableFuture.allOf(notificationFuture, indexingFuture, recommendationFuture).join();

            return new TalentDTO(savedTalent);
        }).exceptionally(ex -> {
            // 예외 처리
            log.error("Error during talent registration", ex);
            throw new TalentRegistrationException("Failed to register talent", ex);
        });
    }
}

@RestController
@RequestMapping("/api/talents")
public class TalentController {

    @Autowired
    private TalentRegistrationService registrationService;

    @PostMapping
    public CompletableFuture<ResponseEntity<TalentDTO>> registerTalent(@RequestBody TalentDTO talentDTO) {
        return registrationService.registerTalent(talentDTO)
            .thenApply(savedTalent -> ResponseEntity.ok(savedTalent))
            .exceptionally(ex -> ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
    }
}
  

이 예제에서는 다음과 같은 비동기 작업들을 수행하고 있어요:

  1. 재능 정보 저장: 데이터베이스에 새로운 재능 정보를 저장합니다.
  2. 관리자 알림: 새로운 재능이 등록되었음을 관리자에게 알립니다.
  3. 검색 인덱싱: 새로운 재능을 검색 엔진에 인덱싱합니다.
  4. 추천 시스템 업데이트: 새로운 재능을 바탕으로 추천 시스템을 업데이트합니다.

이 모든 작업들이 비동기적으로 처리되기 때문에, 사용자는 오래 기다리지 않고도 빠른 응답을 받을 수 있어요. 마치 재능넷에서 새로운 재능을 등록하고 즉시 피드백을 받는 것처럼 말이죠! 😉

💡 Pro Tip:

실제 프로덕션 환경에서는 이러한 비동기 작업들을 더욱 견고하게 만들어야 해요. 예를 들어:

  • 각 작업에 대한 재시도 메커니즘 구현
  • 분산 트랜잭션 관리를 위한 Saga 패턴 적용
  • 서킷 브레이커 패턴을 통한 장애 격리
  • 상세한 모니터링 및 로깅 구현

이렇게 하면 대규모 트래픽에서도 안정적으로 동작하는 시스템을 구축할 수 있어요!

🎉 마무리: 비동기의 미래

와우! 정말 긴 여정이었죠? 우리는 Spring의 @Async부터 CompletableFuture, 그리고 실제 프로젝트에 적용하는 방법까지 광범위하게 살펴봤어요. 이제 여러분은 재능넷과 같은 복잡한 시스템에서도 비동기 프로그래밍을 자유자재로 활용할 수 있을 거예요! 🚀

하지만 기억하세요, 기술의 세계는 계속해서 발전하고 있어요. 비동기 프로그래밍의 미래는 어떨까요?

  • Reactive Streams: 데이터 스트림을 비동기적으로 처리하는 방식이 더욱 중요해질 거예요.
  • 서버리스 아키텍처: AWS Lambda 같은 서비스를 통해 더욱 세분화된 비동기 처리가 가능해질 거예요.
  • AI와의 결합: 머신러닝 모델의 비동기적 실행과 결과 처리가 일상화될 거예요.
  • 엣지 컴퓨팅: 사용자와 가까운 곳에서 비동기 처리를 수행하여 더 빠른 응답을 제공할 수 있을 거예요.

여러분이 이 글을 통해 배운 내용들은 이러한 미래 기술의 기반이 될 거예요. 마치 재능넷이 다양한 재능을 연결하듯, 여러분의 비동기 프로그래밍 기술은 미래의 기술들을 연결하는 다리 역할을 할 거예요! 🌉

자, 이제 여러분의 차례예요. 이 지식을 가지고 어떤 멋진 프로젝트를 만들어볼 건가요? 재능넷보다 더 혁신적인 플랫폼을 만들 수 있을지도 모르겠네요! 화이팅! 💪😄

관련 키워드

  • Spring
  • @Async
  • CompletableFuture
  • 비동기 프로그래밍
  • 멀티스레딩
  • 성능 최적화
  • 리액티브 프로그래밍
  • 동시성
  • 분산 시스템
  • 확장성

지적 재산권 보호

지적 재산권 보호 고지

  1. 저작권 및 소유권: 본 컨텐츠는 재능넷의 독점 AI 기술로 생성되었으며, 대한민국 저작권법 및 국제 저작권 협약에 의해 보호됩니다.
  2. AI 생성 컨텐츠의 법적 지위: 본 AI 생성 컨텐츠는 재능넷의 지적 창작물로 인정되며, 관련 법규에 따라 저작권 보호를 받습니다.
  3. 사용 제한: 재능넷의 명시적 서면 동의 없이 본 컨텐츠를 복제, 수정, 배포, 또는 상업적으로 활용하는 행위는 엄격히 금지됩니다.
  4. 데이터 수집 금지: 본 컨텐츠에 대한 무단 스크래핑, 크롤링, 및 자동화된 데이터 수집은 법적 제재의 대상이 됩니다.
  5. AI 학습 제한: 재능넷의 AI 생성 컨텐츠를 타 AI 모델 학습에 무단 사용하는 행위는 금지되며, 이는 지적 재산권 침해로 간주됩니다.

재능넷은 최신 AI 기술과 법률에 기반하여 자사의 지적 재산권을 적극적으로 보호하며,
무단 사용 및 침해 행위에 대해 법적 대응을 할 권리를 보유합니다.

© 2024 재능넷 | All rights reserved.

댓글 작성
0/2000

댓글 0개

해당 지식과 관련있는 인기재능

프로그램 개발자입니다. ERP, WMS, MES 등과 같은 산업용 프로그램, 설비 인터페이스 프로그램 등을 주로 개발하였습니다.현재는 모 대기업의...

일반 웹사이트 크롤링부터 거래소 홈페이지 정보 가져오기, 공식 api를 통한 정보 가져오기 등 가능합니다  거래소 뿐만 아니라 일반 웹...

개인용도의 프로그램이나 소규모 프로그램을 합리적인 가격으로 제작해드립니다.개발 아이디어가 있으시다면 부담 갖지 마시고 문의해주세요. ...

📚 생성된 총 지식 10,748 개

  • (주)재능넷 | 대표 : 강정수 | 경기도 수원시 영통구 봉영로 1612, 7층 710-09 호 (영통동) | 사업자등록번호 : 131-86-65451
    통신판매업신고 : 2018-수원영통-0307 | 직업정보제공사업 신고번호 : 중부청 2013-4호 | jaenung@jaenung.net

    (주)재능넷의 사전 서면 동의 없이 재능넷사이트의 일체의 정보, 콘텐츠 및 UI등을 상업적 목적으로 전재, 전송, 스크래핑 등 무단 사용할 수 없습니다.
    (주)재능넷은 통신판매중개자로서 재능넷의 거래당사자가 아니며, 판매자가 등록한 상품정보 및 거래에 대해 재능넷은 일체 책임을 지지 않습니다.

    Copyright © 2024 재능넷 Inc. All rights reserved.
ICT Innovation 대상
미래창조과학부장관 표창
서울특별시
공유기업 지정
한국데이터베이스진흥원
콘텐츠 제공서비스 품질인증
대한민국 중소 중견기업
혁신대상 중소기업청장상
인터넷에코어워드
일자리창출 분야 대상
웹어워드코리아
인터넷 서비스분야 우수상
정보통신산업진흥원장
정부유공 표창장
미래창조과학부
ICT지원사업 선정
기술혁신
벤처기업 확인
기술개발
기업부설 연구소 인정
마이크로소프트
BizsPark 스타트업
대한민국 미래경영대상
재능마켓 부문 수상
대한민국 중소기업인 대회
중소기업중앙회장 표창
국회 중소벤처기업위원회
위원장 표창