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

🌲 지식인의 숲 🌲

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

PCB ARTWORK (아트웍) / 회로설계 (LED조명 및 자동차 및 SMPS/ POWER)  안녕하세요. 개발자 입니다.PCB ARTWORK 을 기반으로 PCB ...

c언어c++,   erwin을 이용한 데이터베이스 설계java,    jsp,     javascript,      c#  ...

   안녕하세요^^ 엑셀을 사랑하는 개발자입니다. 간단한 함수작업부터 크롤링,자동화 프로그램, DB연동까지  모두 ...

안녕하세요.안드로이드 앱/라즈베리파이/ESP8266/32/ 아두이노 시제품 제작 외주 및 메이커 취미 활동을 하시는 분들과 아두이노 졸업작품을 진행...

Groovy와 스프링 프레임워크: 동적 언어의 강점 활용

2024-12-25 11:00:38

재능넷
조회수 28 댓글수 0

Groovy와 스프링 프레임워크: 동적 언어의 강점 활용 🚀

 

 

안녕, 친구들! 오늘은 정말 흥미진진한 주제로 여러분과 함께 이야기를 나눠볼 거야. 바로 Groovy와 스프링 프레임워크에 대해서 말이지. 😎 이 두 가지를 함께 사용하면 어떤 마법 같은 일이 벌어질까? 자, 이제부터 우리의 코딩 여행을 시작해볼까?

먼저, Groovy가 뭔지 알아보자. Groovy는 Java 플랫폼을 위한 동적 프로그래밍 언어야. Java와 비슷하면서도 더 간결하고 유연한 문법을 가지고 있어. 그래서 Java 개발자들이 쉽게 배울 수 있지. 🤓

그리고 스프링 프레임워크는 뭐냐고? 이건 Java 기반의 애플리케이션 개발을 위한 오픈 소스 프레임워크야. 엔터프라이즈급 애플리케이션을 만들 때 정말 유용하지.

이 두 가지를 합치면 어떻게 될까? 바로 개발의 효율성과 생산성이 폭발적으로 높아진다는 거야! 😮 재능넷 같은 플랫폼을 개발할 때도 이런 조합을 활용하면 정말 좋을 거야.

💡 알고 계셨나요? 재능넷(https://www.jaenung.net)은 다양한 재능을 거래할 수 있는 플랫폼이에요. Groovy와 스프링 프레임워크를 활용하면 이런 복잡한 시스템도 더 쉽고 효율적으로 개발할 수 있답니다!

자, 이제 본격적으로 Groovy와 스프링 프레임워크의 세계로 들어가볼까? 준비됐어? 그럼 고고! 🚀

Groovy: Java의 멋진 사촌 🎭

Groovy에 대해 더 자세히 알아보자. Groovy는 2003년에 처음 등장했어. Java의 문법을 기반으로 하지만, 더 간결하고 표현력이 풍부한 언어야. Java 개발자들이 쉽게 배울 수 있도록 설계되었지.

Groovy의 주요 특징을 살펴볼까?

  • 동적 타이핑: 변수의 타입을 명시적으로 선언하지 않아도 돼.
  • 클로저 지원: 함수형 프로그래밍을 쉽게 할 수 있어.
  • 메타프로그래밍: 런타임에 프로그램의 동작을 변경할 수 있어.
  • DSL(Domain-Specific Language) 생성 용이: 특정 도메인에 특화된 언어를 만들기 쉬워.
  • Java와의 완벽한 호환성: 기존 Java 코드와 함께 사용할 수 있어.

이런 특징들 때문에 Groovy는 스크립팅, 테스트 자동화, 빌드 도구 등 다양한 분야에서 사용되고 있어. 특히 Gradle이라는 빌드 도구는 Groovy를 기반으로 만들어졌지.

자, 이제 간단한 Groovy 코드를 한번 볼까? 😊


def greet = { name ->
    println "안녕, $name! Groovy의 세계에 오신 걸 환영해요!"
}

greet("친구")

어때? Java보다 훨씬 간결하고 읽기 쉽지? 이게 바로 Groovy의 매력이야!

🌟 Groovy 꿀팁! Groovy에서는 세미콜론(;)을 생략할 수 있어요. 코드가 더 깔끔해 보이죠?

Groovy를 사용하면 코드의 양을 줄이면서도 더 많은 일을 할 수 있어. 예를 들어, 파일을 읽는 코드를 비교해볼까?

Java로 작성한 코드:


BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
String line;
while ((line = reader.readLine()) != null) {
    System.out.println(line);
}
reader.close();

같은 기능을 하는 Groovy 코드:


new File("file.txt").eachLine { line ->
    println line
}

어떤가요? Groovy가 얼마나 간결한지 느껴지나요? 😲

이런 Groovy의 특징들은 개발 속도를 높이고, 코드의 가독성을 향상시키는 데 큰 도움을 줘. 특히 재능넷 같은 복잡한 웹 애플리케이션을 개발할 때 정말 유용할 거야.

Groovy vs Java 코드 비교 Groovy Java 5줄 20줄 같은 기능 구현에 필요한 코드 라인 수

이 그래프를 보면 Groovy가 얼마나 효율적인지 한눈에 알 수 있지? 같은 기능을 구현하는 데 Java보다 훨씬 적은 코드로 가능해. 이게 바로 Groovy의 강력한 장점이야! 🚀

하지만 Groovy가 장점만 있는 건 아니야. 모든 기술이 그렇듯 Groovy도 단점이 있어:

  • 실행 속도: Java보다 조금 느릴 수 있어.
  • 정적 타입 체크: 컴파일 시점에 오류를 잡기 어려울 수 있어.
  • 학습 곡선: Java와 비슷하지만, 새로운 개념들을 익혀야 해.

그래도 이런 단점들은 Groovy의 장점들에 비하면 크게 문제가 되지 않아. 특히 스프링 프레임워크와 함께 사용하면 이런 단점들을 대부분 극복할 수 있지.

🔍 깊이 들어가기: Groovy는 메타프로그래밍을 지원해요. 이게 뭐냐고요? 간단히 말해, 프로그램이 자기 자신을 수정하거나 다른 프로그램을 만들 수 있다는 거예요. 이 기능을 잘 활용하면 정말 강력한 프로그램을 만들 수 있답니다!

자, 이제 Groovy에 대해 어느 정도 감이 왔지? 다음으로 스프링 프레임워크에 대해 알아보고, 이 둘을 어떻게 함께 사용하는지 살펴볼 거야. 준비됐어? 그럼 다음 섹션으로 고고! 🚀

스프링 프레임워크: 자바 개발의 강력한 동반자 🌱

이제 스프링 프레임워크에 대해 알아볼 차례야. 스프링은 엔터프라이즈급 애플리케이션 개발을 위한 종합 솔루션이라고 할 수 있어. 2003년에 처음 등장한 이후로 자바 개발 생태계에서 정말 중요한 위치를 차지하고 있지.

스프링의 핵심 철학은 뭘까? 바로 '가벼움'과 '유연성'이야. 복잡한 엔터프라이즈 시스템을 개발할 때도 간단하고 효율적인 방법을 제공하거든.

스프링의 주요 특징을 살펴볼까?

  • IoC(Inversion of Control): 객체의 생성과 생명주기를 컨테이너가 관리해.
  • DI(Dependency Injection): 객체 간의 의존성을 외부에서 주입해줘.
  • AOP(Aspect-Oriented Programming): 공통 관심사를 분리해서 모듈화할 수 있어.
  • PSA(Portable Service Abstraction): 환경과 세부기술의 변경과 관계없이 일관된 방식으로 기술에 접근할 수 있어.

이런 특징들 덕분에 스프링을 사용하면 코드의 재사용성이 높아지고, 테스트가 쉬워지며, 유지보수가 편리해져. 특히 재능넷 같은 복잡한 웹 서비스를 개발할 때 이런 장점들이 빛을 발하지.

🌟 스프링 꿀팁! 스프링 부트를 사용하면 스프링 프레임워크의 설정을 더욱 간편하게 할 수 있어요. 초기 설정 시간을 대폭 줄일 수 있죠!

자, 이제 간단한 스프링 애플리케이션 예제를 볼까? 😊


@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
        return String.format("Hello, %s!", name);
    }
}

이 코드는 웹 요청을 처리하는 간단한 컨트롤러야. @RestController와 @GetMapping 같은 애노테이션을 사용해서 HTTP GET 요청을 쉽게 처리할 수 있지.

스프링의 또 다른 강점은 다양한 모듈을 제공한다는 거야. 예를 들면:

  • Spring MVC: 웹 애플리케이션 개발을 위한 모듈
  • Spring Security: 보안 기능을 제공하는 모듈
  • Spring Data: 데이터 접근을 쉽게 해주는 모듈
  • Spring Batch: 대용량 데이터 처리를 위한 모듈

이런 모듈들을 조합해서 사용하면 정말 강력한 애플리케이션을 만들 수 있어. 재능넷 같은 서비스도 이런 모듈들을 활용하면 더 효율적으로 개발할 수 있겠지?

스프링 프레임워크의 주요 모듈 Spring Core Spring MVC Spring Security Spring Data Spring Batch

이 그림을 보면 스프링의 구조를 한눈에 이해할 수 있지? 중앙의 Spring Core를 중심으로 다양한 모듈들이 유기적으로 연결되어 있어. 이런 구조 덕분에 필요한 기능만 골라서 사용할 수 있고, 확장성도 뛰어나.

하지만 스프링도 완벽한 건 아니야. 몇 가지 단점도 있지:

  • 학습 곡선: 처음 배울 때 개념이 많아서 어려울 수 있어.
  • 설정의 복잡성: XML 설정이 복잡할 수 있어 (하지만 최근에는 많이 개선되었어!).
  • 오버헤드: 작은 프로젝트에는 과도할 수 있어.

그래도 이런 단점들은 스프링의 장점에 비하면 크게 문제가 되지 않아. 특히 Groovy와 함께 사용하면 이런 단점들을 많이 보완할 수 있지.

🔍 깊이 들어가기: 스프링의 IoC 컨테이너는 정말 강력해요. 객체의 생성과 생명주기를 관리해주기 때문에, 개발자는 비즈니스 로직에만 집중할 수 있죠. 이게 바로 스프링의 핵심 철학인 '제어의 역전'이에요!

자, 이제 스프링 프레임워크에 대해서도 어느 정도 알게 됐지? 다음으로는 Groovy와 스프링을 어떻게 함께 사용하는지, 그리고 그 시너지 효과가 어떤지 알아볼 거야. 준비됐어? 그럼 다음 섹션으로 고고! 🚀

Groovy와 스프링의 환상적인 만남 💑

자, 이제 정말 재미있는 부분이 왔어! Groovy와 스프링을 함께 사용하면 어떤 마법이 일어날까? 🎩✨

Groovy와 스프링의 조합은 Java의 안정성과 Groovy의 유연성을 동시에 얻을 수 있는 최고의 방법이야. 이 둘을 함께 사용하면 개발 생산성이 크게 향상되고, 코드의 가독성도 좋아져.

어떤 점에서 이 조합이 좋은지 구체적으로 알아볼까?

  1. 간결한 문법: Groovy의 간결한 문법을 사용해 스프링 설정을 더 쉽게 할 수 있어.
  2. 동적 타이핑: Groovy의 동적 타이핑을 활용해 더 유연한 코드를 작성할 수 있어.
  3. 메타프로그래밍: Groovy의 메타프로그래밍 기능을 사용해 스프링의 기능을 확장할 수 있어.
  4. DSL 생성: Groovy로 도메인 특화 언어(DSL)를 만들어 스프링 설정을 더 직관적으로 할 수 있어.
  5. 테스트 용이성: Groovy의 테스팅 프레임워크와 스프링의 테스트 지원을 결합해 더 쉽게 테스트를 작성할 수 있어.

이런 장점들 덕분에 개발 속도가 빨라지고, 코드의 품질도 향상돼. 특히 재능넷 같은 복잡한 웹 서비스를 개발할 때 이런 장점들이 빛을 발하지.

🌟 꿀팁! 스프링 부트와 Groovy를 함께 사용하면 설정이 거의 필요 없는 스프링 애플리케이션을 만들 수 있어요. 정말 빠르게 프로토타입을 만들 수 있죠!

자, 이제 Groovy로 작성한 간단한 스프링 컨트롤러를 볼까?


@RestController
class GreetingController {
    @GetMapping("/greet")
    def greet(@RequestParam(value = "name", defaultValue = "World") String name) {
        [message: "Hello, $name!"]
    }
}

어때? Java로 작성한 것보다 훨씬 간결하지? Groovy의 문자열 보간법($name)과 맵 리터럴([message: "Hello, $name!"])을 사용해서 코드를 더 읽기 쉽게 만들었어.

이번엔 Groovy로 스프링 빈을 정의하는 예제를 볼까?


beans {
    dataSource(BasicDataSource) {
        driverClassName = "org.h2.Driver"
        url = "jdbc:h2:mem:testdb"
        username = "sa"
        password = ""
    }
}

이렇게 Groovy DSL을 사용하면 XML보다 훨씬 간결하고 읽기 쉽게 스프링 설정을 할 수 있어. 특히 복잡한 설정이 필요한 대규모 프로젝트에서 이런 장점이 더 두드러지지.

Groovy와 스프링의 시너지 효과 Groovy Spring 시너지 효과 생산성 향상 코드 가독성 개선

이 그림을 보면 Groovy와 스프링이 만나 어떤 시너지를 내는지 한눈에 알 수 있지? 두 기술의 장점이 합쳐져서 더 큰 효과를 만들어내는 거야.

Groovy와 스프링을 함께 사용하면 다음과 같은 이점이 있어:

  • 설정 간소화: Groovy DSL을 사용해 스프링 설정을 더 간단하게 할 수 있어.
  • 테스트 코드 작성 용이: Groovy의 테스팅 프레임워크와 스프링의 테스트 지원을 결합해 더 쉽게 테스트를 작성할 수 있어.
  • 스크립팅 능력 향상: Groovy의 스크립팅 능력을 활용해 동적인 기능을 쉽게 구현할 수 있어.
  • 생산성 향상: Groovy의 간결한 문법과 스프링의 강력한 기능이 만나 개발 속도가 빨라져.

이런 장점들 덕분에 복잡한 엔터프라이즈 애플리케이션도 더 쉽고 빠르게 개발할 수 있어. 재능넷 같은 서비스를 개발할 때도 이런 조합이 큰 도움이 될 거야.

🔍 깊이 들어가기: Groovy의 메타프로그래밍 기능을 활용하면 스프링의 AOP(관점 지향 프로그래밍)를 더욱 강력하게 사용할 수 있어요. 예를 들어, 메서드 호출을 동적으로 가로채서 로깅이나 보안 체크 같은 기능을 쉽게 추가할 수 있죠!

하지만 모든 기술 조합이 그 렇듯이 Groovy와 스프링의 조합도 주의해야 할 점이 있어:

  • 성능: Groovy는 Java보다 약간 느릴 수 있어. 성능이 중요한 부분에서는 Java를 사용하는 것이 좋을 수 있지.
  • 학습 곡선: 두 기술을 모두 익혀야 하므로 초기 학습 시간이 더 필요할 수 있어.
  • 팀 구성: 모든 팀원이 Groovy와 스프링을 모두 잘 다룰 수 있어야 해.

그래도 이런 단점들은 장점에 비하면 크게 문제가 되지 않아. 특히 장기적인 관점에서 보면 생산성 향상과 코드 품질 개선 효과가 훨씬 크지.

자, 이제 Groovy와 스프링을 함께 사용하는 실제 예제를 좀 더 자세히 볼까? 재능넷 같은 서비스의 일부 기능을 구현한다고 가정해보자.


@RestController
@RequestMapping("/api/talents")
class TalentController {
    @Autowired
    TalentService talentService

    @GetMapping
    def listTalents(@RequestParam(required = false) String category) {
        def talents = category ? talentService.findByCategory(category) : talentService.findAll()
        [status: "success", data: talents]
    }

    @PostMapping
    def createTalent(@RequestBody Talent talent) {
        def savedTalent = talentService.save(talent)
        [status: "success", data: savedTalent]
    }
}

@Service
class TalentService {
    @Autowired
    TalentRepository talentRepository

    def findAll() {
        talentRepository.findAll()
    }

    def findByCategory(String category) {
        talentRepository.findByCategory(category)
    }

    def save(Talent talent) {
        talentRepository.save(talent)
    }
}

interface TalentRepository extends JpaRepository<talent long> {
    List<talent> findByCategory(String category)
}
</talent></talent>

이 예제에서 볼 수 있듯이, Groovy를 사용하면 코드가 더 간결해지고 읽기 쉬워져. 특히 컨트롤러에서 맵을 반환할 때 Groovy의 맵 리터럴을 사용하면 코드가 훨씬 깔끔해지지.

또한 Groovy의 동적 타이핑 덕분에 메서드 반환 타입을 명시적으로 선언하지 않아도 돼. 이런 특징들이 코드를 더 유연하고 표현력 있게 만들어주는 거야.

🌟 실무 팁! Groovy와 스프링을 함께 사용할 때는 Spock 프레임워크를 사용해 테스트를 작성하는 것이 좋아요. Spock은 Groovy로 작성된 테스팅 프레임워크로, 매우 표현력이 풍부하고 읽기 쉬운 테스트 코드를 작성할 수 있죠!

이제 Groovy와 스프링을 사용해 테스트 코드를 작성하는 예제를 볼까?


import spock.lang.Specification
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
class TalentServiceSpec extends Specification {
    @Autowired
    TalentService talentService

    def "should find talents by category"() {
        given:
        def category = "Programming"

        when:
        def talents = talentService.findByCategory(category)

        then:
        talents.size() > 0
        talents.every { it.category == category }
    }

    def "should save new talent"() {
        given:
        def talent = new Talent(name: "Java Programming", category: "Programming")

        when:
        def savedTalent = talentService.save(talent)

        then:
        savedTalent.id != null
        savedTalent.name == talent.name
        savedTalent.category == talent.category
    }
}

이 테스트 코드를 보면 Spock 프레임워크의 given-when-then 구조를 사용해 테스트를 매우 명확하게 작성할 수 있어. 또한 Groovy의 간결한 문법 덕분에 테스트 코드도 매우 읽기 쉽게 작성할 수 있지.

이렇게 Groovy와 스프링을 함께 사용하면 개발부터 테스트까지 전체 개발 프로세스를 더욱 효율적으로 만들 수 있어. 특히 재능넷 같은 복잡한 웹 서비스를 개발할 때 이런 효율성이 큰 도움이 될 거야.

Groovy와 스프링의 개발 프로세스 개선 개발 테스트 배포

이 그림은 Groovy와 스프링을 사용한 개발 프로세스를 보여줘. 각 단계가 유기적으로 연결되어 있고, 전체적으로 매우 효율적인 흐름을 만들어내는 걸 볼 수 있지.

자, 이제 Groovy와 스프링의 조합이 얼마나 강력한지 알겠지? 이 두 기술을 잘 활용하면 정말 놀라운 일을 할 수 있어. 특히 재능넷 같은 복잡한 웹 서비스를 개발할 때 이런 기술 조합이 큰 도움이 될 거야.

하지만 기억해야 할 점은, 어떤 기술을 사용하든 가장 중요한 건 사용자의 니즈를 정확히 파악하고 그에 맞는 서비스를 제공하는 거야. 기술은 그저 도구일 뿐이니까.

자, 이제 우리의 Groovy와 스프링 여행이 끝나가고 있어. 마지막으로 정리해볼까?

  • Groovy는 Java 플랫폼 위에서 동작하는 동적 언어로, 간결하고 표현력이 풍부해.
  • 스프링은 Java/Groovy 기반의 애플리케이션 개발을 위한 강력한 프레임워크야.
  • 이 둘을 함께 사용하면 개발 생산성이 크게 향상되고, 코드의 품질도 개선돼.
  • 특히 복잡한 웹 서비스 개발에 이 조합이 매우 유용해.

어때? Groovy와 스프링의 세계는 정말 흥미진진하지? 이제 이 지식을 가지고 멋진 프로젝트를 시작해보는 건 어떨까? 화이팅! 🚀

관련 키워드

  • Groovy
  • 스프링 프레임워크
  • Java
  • 웹 개발
  • 생산성
  • 테스트 주도 개발
  • 메타프로그래밍
  • DSL
  • 스크립팅
  • 엔터프라이즈 애플리케이션

지적 재산권 보호

지적 재산권 보호 고지

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

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

© 2024 재능넷 | All rights reserved.

댓글 작성
0/2000

댓글 0개

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

반복적인 업무/계산은 프로그램에 맞기고 좀 더 중요한 일/휴식에 집중하세요- :)칼퇴를 위한 업무 효율 개선을 도와드립니다 !!! "아 이건 ...

현재 한국디지털미디어고등학교에 재학중인 학생입니다. 아드이노는 중 1 처음 접하였으며  횟수로 5년동안 아두이노를 해오...

  Matlab 이나 C 형태의 알고리즘을 분석하여 회로로 설계하여 드립니다. verilog, VHDL 모두 가능합니다. 회로설계후 simula...

안녕하세요, 6년차 머신러닝, 딥러닝 엔지니어 / 리서처 / 데이터 사이언티스트 입니다. 딥러닝 코딩을 통한 기술 개발부터, 오픈소스 ...

📚 생성된 총 지식 10,570 개

  • (주)재능넷 | 대표 : 강정수 | 경기도 수원시 영통구 봉영로 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 스타트업
대한민국 미래경영대상
재능마켓 부문 수상
대한민국 중소기업인 대회
중소기업중앙회장 표창
국회 중소벤처기업위원회
위원장 표창