본문 바로가기

카테고리 없음

@Autowired 를 통해 명시적 주입을 받는 이유

@Autowired를 사용해서 Repository를 명시적으로 주입받는 이유는 주로 객체의 의존성 관리와 관련이 있습니다.

  1. 객체 의존성 관리: Spring의 DI(Dependency Injection) 원칙
    Spring에서는 의존성 주입(DI)을 통해 객체 간의 결합도를 낮추고 유연성을 높이는 것을 목표로 합니다. Repository는 Service 계층에서 데이터 접근을 담당하는 핵심 구성 요소이기 때문에, 직접 객체를 생성하거나 import해서 사용하지 않고, Spring 컨테이너에 의해 생성된 Bean을 주입받아 사용하는 방식을 권장합니다.

주요 이유:
결합도 낮추기:
직접 객체를 생성하거나 import하면 Service 계층과 Repository 계층 사이의 결합도가 높아집니다.
반면, Spring의 DI를 통해 객체를 주입받으면 Service 계층은 Repository 구현체의 생성 방식에 대해 알 필요가 없어집니다. 이는 확장성과 테스트 용이성을 크게 향상시킵니다.
2. @Autowired의 역할
@Autowired는 Spring 컨테이너에 등록된 Bean 중에서 해당 타입(또는 이름)에 맞는 객체를 찾아 주입하는 역할을 합니다. 즉, Service 클래스에서 Repository 인터페이스에 대해 의존성을 선언하면, Spring이 자동으로 해당 Repository의 구현체를 찾아 주입합니다.

장점:
구현체에 대한 의존성 제거:
Repository는 일반적으로 인터페이스로 선언되고, 실제 데이터베이스 접근은 Spring Data JPA가 제공하는 구현체(SimpleJpaRepository 등)가 처리합니다.
Service 계층은 Repository 인터페이스만 알고, 구현체에 대해 몰라도 됩니다.
테스트 가능성 향상:
테스트 시 Repository를 Mock으로 대체할 수 있습니다. DI를 사용하면 구현체 대신 가짜 객체(Mock)를 주입하기 쉬워집니다.
예제:


@Service
public class UserService {
    @Autowired
    private UserRepository userRepository; // 주입받기만 하면 됨
}
  1. 직접 객체 생성과 @Autowired 방식 비교
    1) 직접 객체 생성 방식:

public class UserService {
    private UserRepository userRepository = new UserRepository(); // 직접 생성
}

문제점:
결합도가 높음: UserService가 UserRepository의 생성 방식에 대해 알고 있어야 함.
테스트 어려움: UserRepository의 Mock 객체를 사용하려면 UserService를 수정해야 함.
스프링 컨테이너와의 단절: Spring의 Bean 관리 기능을 사용할 수 없음.
2) @Autowired 방식:


@Service
public class UserService {
    @Autowired
    private UserRepository userRepository; // DI로 주입받음
}

장점:
결합도 낮음: UserService는 UserRepository 구현체를 몰라도 됨.
테스트 용이: Spring Boot의 테스트 환경에서 쉽게 Mock을 주입 가능.
Spring의 AOP 지원 가능: Spring 컨테이너에서 관리하므로, 트랜잭션 등 부가적인 기능을 쉽게 추가할 수 있음.
4. Spring Data JPA와의 연계
Spring Data JPA를 사용하면 Repository 인터페이스를 선언만 하면 Spring이 자동으로 구현체를 만들어 Bean으로 등록합니다. @Autowired를 사용해 이를 주입받을 수 있습니다.


@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository; // Spring이 구현체를 자동으로 주입
}
  1. 결론
    @Autowired를 사용해 명시적으로 주입받는 이유는 Service 계층이 Repository 계층의 구현 세부사항에 의존하지 않도록 하기 위함입니다.**
    이로 인해 코드의 결합도를 낮추고, 유지보수성과 테스트 용이성을 높이는 장점이 있습니다.
    또한, Spring 컨테이너에서 객체를 관리하므로 트랜잭션, AOP 등 추가 기능을 쉽게 사용할 수 있습니다.