[Spring] 스프링빈

정석·2024년 2월 25일

Spring

목록 보기
6/21
post-thumbnail

혼자 공부한 내용이므로 틀린 내용이 있을 수 있습니다.

SpringBean

  • 서버가 시작되면 <스프링 컨테이너> 가 생성된다. 이 컨테이너 안에는 스프링빈 들이 등록 되는데,
    스프링 빈은 @RestController와 같이 설정한 것들로 생긴다. 이렇게 스프링빈으로 등록이 되면 자동으로 객체를 생성하게 되어 따로 객체를 생성할 필요없이 '주입'해서 사용하면 된다.

그럼 굳이 왜 이런 방식을?

  • 만약 레포지토리(저장소)를 바꾸는 상황이 있다면 Repository 인터페이스를 하나 생성해서 해당 인터페이스를 구현하는 새로운 클래스를 만들어 교체하면 된다. 하지만 이러한 방식은 Repository 를 사용하는 Serivce 에서 여러개를 사용한다면 모든 코드를 바꿔야 하기에 비효율적이다.

  • 스프링 컨테이너를 사용하면 스프링빈에 등록된 것들 중에서 대신 객체를 만들어주고 알아서 Repository를 결정해서 주입시켜준다.

만약 레포지토리의 종류가 두개 MemoryRepository, MysqlRepository 가 존재한다면, 아래와 같이 작성하게 된다. 근데 두개 이상의 레포지토리가 존재한다면 직접 사용할 레포지토리는 @Primary 어노테이션을 붙여서 사용하게 된다. 예시로 MysqlRepository를 사용하도록 한다면 아래와 같다.

  • MysqlRepository
@Primary // 해당 스프링빈을 사용할 거라는 의미
@Repository // Repository 어노테이션을 통해 스프링빈 등록 -> 자동으로 객체 생성 -> Serivce에서 주입만 시켜주면 됨
public class BookMysqlRepository implements BookRepository {

    @Override
    public void saveBook() {
        System.out.println("BookMysqlRepository.saveBook");
    }
}
  • MemoryRepository
@Repository
public class BookMemoryRepository implements BookRepository {

    private final List<Book> books = new ArrayList<Book>();

    @Override
    public void saveBook() {
        System.out.println("BookMemoryRepository.saveBook");
    }
}
  • Service
@Service
public class BookService {

    private final BookRepository bookRepository;

    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    public void saveBook() {
        bookRepository.saveBook();
    }
}

그럼 결과적으로 MysqlRepository 저장소를 사용하게 된다. Service 코드에서 볼 수 있듯이 Repository 에 대한 객체를 만들지 않고 '주입'만 시켜주고 있다. (스프링빈을 사용했기 때문에)

컨테이너가 선택해 Service에 넣어주는 과정을 '의존성 주입(Dependency Injection) 이라고 한다.


스프링빈을 주입하는 방법!

  1. 생성자를 이용해 주입한다. (제일 권장되는 방법)
@RestController
public class UserController {

    private final UserService userService;

	@Autowired // 스프링 버전이 올라가며 안붙여도 상관 없음
    public UserController(UserService userService) {
        this.userService = userService;
    }

위와 같이 생성자를 통해 주입한다.

  1. 세터로 주입한다.
public class UserRepository {

    private JdbcTemplate jdbcTemplate;
    
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
  1. 필드에 @Autowired 생성
@Autowird
private jdbcTemplate jdbcTemplate;

스프링 빈을 등록하는 다른 방법

메서드에 @Bean 어노테이션을 붙이면 해당 메서드에서 반환 되는 객체가 스프링 빈에 등록된다.

@Configuration
public calss UserConfiguration {
	@Bean
    public UserRepository userRepository(JdbcTemplate jdbcTemplate) {
    	reutrun new UserRepository(jdbcTemplate);
    }
}

이렇게 해도 스프링빈에 등록될 수 있지만 이러한 방법은 외부 라이브러리를 가져올 경우 사용한다.

0개의 댓글