me.kchabin 패키지 아래에 springbootdeveloper 패키지를 생성한 뒤 SpringBootDeveloperApplication 이란 이름의 자바 클래스를 생성함.
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.5'
}
apply plugin: 'io.spring.dependency-management'
//공식 설정 문서를 따라서 했음. 책은 왜 좀 구식이지..?
group = 'me.kchabin'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
🔼 build.gradle
내용
package me.kchabin.springbootdeveloper;
import org.springframework.boot.SpringApplication;
public class SpringBootDeveloperApplication {
public static void main(String[] args){
SpringApplication.run(SpringBootDeveloperApplication.class, args);
}
}
동일 패키지에 [TestController.java](http://TestController.java)
생성
package me.kchabin.springbootdeveloper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@GetMapping("/test")
public String test(){
return "Hello World!";
}
}
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'study'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
//Querydsl 추가
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}
tasks.named('test') {
useJUnitPlatform()
}
clean {
delete file('src/main/generated')
}
Execution failed for task ':SpringBootDeveloperApplication.main()'.
> Process 'command '/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
Spring Boot 애플리케이션 실행 중 문제가 발생했다. 처음엔 Gradle 버전 문제인 줄 알았는데, [gradle-wrapper.properties](http://gradle-wrapper.properties)
파일을 확인해봤을 때 별다른 문제는 없었다.
dependency나 jdk 버전, IDE 등에는 별 문제가 없어보였기 때문에 Stacktrace를 실행했다.
./gradlew build --stacktrace
Execution failed for task ':resolveMainClassName'.
Unable to find a single main class from the following candidates [me.kchabin.Main, me.kchabin.springbootdeveloper.SpringBootDeveloperApplication
문제 → 여러 후보 메인 클래스 발견
하나의 메인 클래스를 설정해야 함. → @SpringBootApplication
이라는 어노테이션이 있는 클래스.
보니까 책에 써있는 예제 코드에서 @SpringBootApplication을 빼먹은 거 였음..
이젠 실행 잘된다.
@GetMapping("/test")
localhost:8080/test
/test
: @GetMapping 애너테이션으로 메서드와 매핑할 때 스프링 부트에서 설정한 경로.
의존성이 모여 있는 그룹.
spring-boot-starter-{작업유형} → 명명규칙
자주 사용하는 스타터
스타터 | 설명 |
---|---|
spring-boot-starter-web | Spring MVC를 사용해서 RESTful 웹 서비스를 개발할 때 필요한 의존성 모음 |
spring-boot-starter-test | 스프링 애플리케이션 테스트용 |
spring-boot-starter-validation | 유효성 검사용 |
spring-boot-starter-actuator | 모니터링을 위해 애플리케이션에서 제공하는 다양한 정보를 제공하기 쉽게 하는 의존성 모음 |
spring-boot-starter-data-jpa | ORM을 사용하기 위한 인터페이스의 모음인 JPA를 더 쉽게 사용하기 위한 의존성 모음 |
**MVC(Model - View - Controller)**
web 스타터 확인
web mvc도 보이고 tomcat도 보임.
testCompileClasspath
를 펼치면 test 스타터도 확인할 수 있음.
META-INF
> spring.factories
: 위치
왼쪽 탭 > External Libraries
> spring-boot-autoconfigure
미리 구현되어 있는 자동 설정 파일을 확인할 수 있음.
스프링부트에서는 빈이 자동으로 구성 및 등록됨. 자동 구성이 없다면 개발자가 특정 기술을 사용할 때마다 설정해야하는 값을 모두 개발자가 직접 설정해줘야 함.
여러 줄의 텍스트 작성
String query17 =
""" SELECT * FROM "items"
WHERE "status" = "ON_SALE"
ORDER BY "price";
""";
값 파싱용
String testBlock17 = """
{
"id" : %d
"name" : %s,
}
""".formatted(2, "juice");
데이터 전달을 목적으로 하는 객체를 더 빠르고 간편하게 만들기 위한 기능
→ 스프링 강의에서 써먹었던 거
record Item(String name, int price){
//파라미터가 private final로 정의됨
}
Item juice = new Item("juice", 3000);
juice.price(); // 3000
형변환 사용 x
//11 버전
if (o instanceof Integer) {
Integer i = (Integer) o;
...
}
//17버전
if (o instanceof Interger i){
...
}
switch-case문으로 자료형에 맞게 case 처리를 할 수 있음.
static double getIntegerValue(Object o){
return switch(o) {
case Double d -> d.intValue();
case Float f -> f.intValue();
//double이나 float -> int
//string -> int로 변환 후 반환
case String s -> Integer.parseInt(s);
default -> 0d;
};
}
Servlet, JPA 네임스페이스 대체 : javax → jakarta
GraalVM 기반의 스프링 네이티브 공식 지원
이 클래스는 자바의 main()과 같은 역할. → 스프링 부트의 시작
SpringApplication.run()
애플리케이션 실행@SpringBootApplication
public class SpringBootDeveloperApplication {
public static void main(String[] args){
SpringApplication.run(SpringBootDeveloperApplication.class, args);
}
}
SpringBootDeveloperApplication.class
= 앱의 메인 클래스로 사용할 클래스.
args
: 커맨드 라인의 인수들 전달
cmd+클릭
SpringBootConfiguration
: 스프링 부트 관련 설정
ComponentScan
: 사용자가 등록한 빈을 읽고 등록함. @Component
라는 애너테이션을 가진 클래스들을 찾아 빈으로 등록하는 역할.
애너테이션명 | 설명 |
---|---|
@Configuration | 설정 파일 등록 |
@Repository | ORM 매핑 |
@Controller, @RestController | 라우터 |
@Service | 비즈니스 로직 |
→ 전부 @Component 포함
@EnableAutoConfiguration
: 자동 구성 활성화 애너테이션
@RestController
public class TestController {
@GetMapping("/test")
public String test(){
return "Hello Springboot!";
}
}
GET /test 요청이 오면 test() 메서드를 실행함.
위에서 말했듯이, @RestController
는 라우터 역할을 하는 애너테이션. → HTTP 요청과 메서드 연결.
@RestController 와 @Component를 같은 @Component 취급하는 이유
RestController.java
Controller.java
@Component 애너테이션을 발견할 수 있음.