๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐Ÿƒโ€โ™‚๏ธ Quick Start

๋น ๋ฅด๊ฒŒ Sprout๋ฅผ ์‹คํ–‰ํ•ด๋ณด์„ธ์š”.

์‚ฌ์ „ ์š”๊ตฌ์‚ฌํ•ญโ€‹

  • Java 21+ (๊ฐ€์ƒ ์Šค๋ ˆ๋“œ ๋ฐ ์ตœ์‹  ์–ธ์–ด ๊ธฐ๋Šฅ ํ•„์ˆ˜)
  • Gradle (ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ์šฉ)

1. ํด๋ก  ๋ฐ ๋นŒ๋“œโ€‹

$ git clone https://github.com/yyubin/sprout.git
$ cd sprout && ./gradlew build

2. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰โ€‹

Java 21 ๋ชจ๋“ˆ ์š”๊ตฌ์‚ฌํ•ญ

CGLIB ํ”„๋ก์‹œ๋Š” ๊นŠ์€ ๋ฆฌํ”Œ๋ ‰์…˜์„ ์œ„ํ•ด ์ถ”๊ฐ€ ๋ชจ๋“ˆ ์ ‘๊ทผ ํ”Œ๋ž˜๊ทธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

$ java \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-opens=java.base/java.util=ALL-UNNAMED \
-jar build/libs/sprout.jar
ํŒ

์„œ๋ฒ„ ๋ชจ๋“œ์™€ ์Šค๋ ˆ๋“œ ๋ชจ๋ธ์€ ๋ช…๋ น์ค„ ์ธ์ˆ˜๊ฐ€ ์•„๋‹Œ application.yml์„ ํ†ตํ•ด ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

3. ์ฒซ ๋ฒˆ์งธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜โ€‹

๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํด๋ž˜์Šคโ€‹

@ComponentScan("com.example.app")
public class DemoApplication {
public static void main(String[] args) throws Exception {
SproutApplication.run(DemoApplication.class);
}
}

๊ฐ„๋‹จํ•œ ์ปจํŠธ๋กค๋Ÿฌโ€‹

@Controller
@RequestMapping("/api")
public class HelloController {
private final GreetingService service;

public HelloController(GreetingService service) {
this.service = service;
}

@GetMapping("/hello/{id}")
public MessageDto hello(@PathVariable Long id) {
return new MessageDto(service.greet(id));
}

@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody CreateUserRequest request) {
User user = service.createUser(request);
return ResponseEntity.ok(user);
}
}

AOP๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋น„์Šคโ€‹

@Service
public class GreetingService {
public String greet(Long id) {
return "์•ˆ๋…•ํ•˜์„ธ์š”, ์‚ฌ์šฉ์ž " + id + "๋‹˜!";
}

public User createUser(CreateUserRequest request) {
// ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ตฌํ˜„
return new User(request.getName(), request.getEmail());
}
}

AOP Aspectโ€‹

@Aspect
public class LoggingAspect {
@Around(pointcut = "com.example.app..*Service.*")
public Object logExecutionTime(ProceedingJoinPoint pjp) throws Throwable {
long startTime = System.nanoTime();
try {
return pjp.proceed();
} finally {
long duration = (System.nanoTime() - startTime) / 1_000;
System.out.printf("%s ์‹คํ–‰ ์‹œ๊ฐ„: %d ยตs%n",
pjp.getSignature().toLongName(), duration);
}
}
}

4. ๊ตฌ์„ฑ ์„ค์ •โ€‹

src/main/resources/application.yml ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์„ธ์š”.

author: ๋‹น์‹ ์˜-์ด๋ฆ„
server:
execution-mode: hybrid # nio | hybrid | blocking
thread-type: virtual # virtual | platform
thread-pool-size: 150 # thread-type = platform์ผ ๋•Œ๋งŒ ์‚ฌ์šฉ

sprout:
database:
url: jdbc:mysql://localhost:3306/myapp
username: root
password: your-password

5. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ…Œ์ŠคํŠธโ€‹

์‹คํ–‰ ํ›„ ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ•ด๋ณด์„ธ์š”.

# GET ์š”์ฒญ
curl http://localhost:8080/api/hello/123

# POST ์š”์ฒญ
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name": "ํ™๊ธธ๋™", "email": "hong@example.com"}'

๋‹ค์Œ ๋‹จ๊ณ„๋Š”?โ€‹

๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‚˜์š”?โ€‹