반응형

DI(Dependency Injection) 란?

  • 의존성 주입
  • 개발자가 만든 객체들 간에는 서로 의존 관계가 존재
  • 전에는 객체간의 의존 관계를 개발자가 일일이 주입해 줬어야 했음
  • 이제는 Spring의 어노테이션들을 사용하면 Spring이 알아서 주입해줌

DI 관련 예제

  • Test 코드 작성 예제를 활용해 의존성 주입과 주입 방법에 대해 정리해 보려 함
  • 위 예제를 요약해보면
    1. ContentServiceTest에서 ContentService의 메소드들에 대한 테스트 진행
    2. ContentService의 메소드들은 ContentRepository의 메소드들을 활용해 데이터에 접근
    3. ContentRepository는 Map에 저장된 데이터들을 직접 CRUD 진행
  • 이 때 ContentServiceTest에서는 ContentService를 불러와야 하고, ContentService에서는 ContentRepository를 불러와야 함

각각의 클래스에서 필요한 클래스를 직접 호출

class ContentServiceTest {
    ContentService contentService = new ContentService();
    ...
}

public class ContentService {
    ContentRepository contentRepository = new ContentRepository();
    ...
}

Test에서 Service를 불러올 때 Repository를 주입해서 호출하기

class ContentServiceTest {

    ContentService contentService = new ContentService(new ContentRepository());
}

public class ContentService {

    ContentRepository contentRepository;

    public ContentService(ContentRepository contentRepository) {
        this.contentRepository = contentRepository;
    }
}

@Autowired 사용

  • ContentService에서 ContentRepository를 불러올 때 ContentRepository 타입으로 생성 후 new ContentRepository()를 해줄 필요없이 @Autowired를 사용하면 됨

  • @Autowired를 사용했을 때의 장점

    1. 매번 new 해줄 필요 없음
    2. new를 할 때마다 다시 메모리 영역에 올라가게 되는데 @Autowired를 사용하면 이 작업을 안하게 되어서 Single Tone을 유지할 수 있음
  • 주의할 점

    1. Test 쪽에서 사용하기 위해선 Test 클래스에 @SpringBootTest를 붙여 줘야 함
    2. @Autowired 되는 ContentService, ContentRepository에는 모두 @Component를 붙여 줘야 함
      • @Controller, @Service, @Repository 등의 어노테이션에는 @Component가 포함되어 있음
@SpringBootTest
class ContentServiceTest {

    @Autowired
    ContentService contentService;
}

@Service
public class ContentService {

    @Autowired
    ContentRepository contentRepository;
}

@RequiredArgsConstructor 사용

  • Lombok 라이브러리를 추가했다면 사용 가능한 어노테이션
  • @Autowired 대신 private final을 붙여줘서 자동으로 주입해줌
  • 단, 테스트 쪽에서는 lombok 적용이 안되므로 사용 불가
@SpringBootTest
class ContentServiceTest {

    @Autowired
    ContentService contentService;
}

@Controller
@RequiredArgsConstructor
public class ContentService {

    private final ContentRepository contentRepository;
}
반응형

↓ 클릭시 이동

복사했습니다!