8. 스프링 어노테이션을 이해해보자
3일만에 스프링을 배워야한다아악
어노테이션을 달면, 알아서 생성자 함수를 주입해준단다. 이게 먼 소리일까. 대체 어디에서 주입해준다는걸까. 앱이 시작되면 스프링이 어노테이션 붙은거를 다 조립한다. 그 단계를 알아보자
어노테이션이 뭘까?
- 이 클래스/메서드가 뭔지 Spring에게 알려주는 태그
1. 어노테이션 붙은 클래스들을 찾는다.
- @Repository, @Service, @RestController 등
2. 의존관계 파악한다.
- DailyStepAdapter는 JpaRepository가 필요하구나~~
3. 밑바닥부터 순서대로 생성 & 조립한다.
- JpaRepository 를 생성한다 (Spring Data 가 자동으로 구현)
- DailyStepAdapter를 생성한다 (JpaReository 주입)
.. 계속 컨트롤러 레벨까지
4. 그 다음은? 유저가 API 호출할때까지 기다린다.
- 이미 조립된 상태에서 실행만됨.
- 그래서 개발할 때, new 로 객체 만들어서 실행할 필요 없음. 스프링이 알아서 어노테이션 붙은거 조립해줌.
어노테이션 목록들 - 클래스에 붙는 어노테이션
@Service: 비즈니스로직 (UseCase 구현체)@Repository: DB 접근 (Adapter)@RestController: HTTP API (Controller)@Entity: 이 클래스 = DB 테이블임@Table(name = "hope"): 테이블이름은 hope
메서드에 붙는 어노테이션
@Trasctional: 이 메서드 안의 DB 작업을 하나로 묶어줘
필드에 붙는 어노테이션
@Entity
@Table(name = "daily_step")
class DailyStepEntity(
@Id // "이게 PK야"
@GeneratedValue(strategy = GenerationType.IDENTITY) // "DB가 자동 증가"
val id: Long? = null,
@Column(nullable = false) // "NOT NULL"
val fleamarketUserId: Long,
@Column(nullable = false, updatable = false) // "NOT NULL + 수정 불가"
val createdAt: ZonedDateTime,
@Column(name = "updated_at") // "DB 컬럼명 직접 지정"
var updatedAt: ZonedDateTime,
@UpdateTimestamp // "수정될 때 자동으로 시간 갱신"
@Column(name = "updated_at", nullable = false)
var updatedAt: ZonedDateTime,
@Typeclass // "이 컬럼은 JSON 타입"
@Column(columnDefinition = "json")
val recentReward: String? = null,
)
JPA 레포지토리관련 어노테이션
// 커스텀 쿼리 직접 작성
@Query("SELECT e FROM SomeEntity e WHERE e.userId = :userId")
fun findByUser(@Param("userId") userId: Long): List<SomeEntity>
// 네이티브 SQL (MySQL 직접)
@Query(value = "SELECT * FROM some_thing WHERE ...", nativeQuery = true)
fun customQuery(): List<SomeEntity>
// 비관적 락 (동시성 제어)
@Lock(LockModeType.PESSIMISTIC_WRITE)
fun findByUserIdWithLock(userId: Long): UserEntity?
Bean이 뭐지
- 스프링이 만들어서 들고있는 객체
- 즉..어노테이션을 붙이면 실행시 빈이 된다.