8. 스프링 어노테이션을 이해해보자

3일만에 스프링을 배워야한다아악

어노테이션을 달면, 알아서 생성자 함수를 주입해준단다. 이게 먼 소리일까. 대체 어디에서 주입해준다는걸까. 앱이 시작되면 스프링이 어노테이션 붙은거를 다 조립한다. 그 단계를 알아보자

어노테이션이 뭘까?

1. 어노테이션 붙은 클래스들을 찾는다.

2. 의존관계 파악한다.

3. 밑바닥부터 순서대로 생성 & 조립한다.

  1. JpaRepository 를 생성한다 (Spring Data 가 자동으로 구현)
  2. DailyStepAdapter를 생성한다 (JpaReository 주입)
    .. 계속 컨트롤러 레벨까지

4. 그 다음은? 유저가 API 호출할때까지 기다린다.

어노테이션 목록들 - 클래스에 붙는 어노테이션

메서드에 붙는 어노테이션

필드에 붙는 어노테이션

@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이 뭐지