빈(Bean) : Spring에 의하여 생성되고 관리되는 자바 객체
Spring에서는 직접 new로 생성한 객체가 아니라 Spring에 의해 관리당하는 자바 객체를 사용한다.
회원 컨트롤러가 회원 서비스와 회원 리포지토리를 사용할 수 있게 의존관계를 준비한다.
스프링 빈을 등록하는 방법은 (1) 컴포넌트 스캔과 자동 의존관계 설정, (2) 자바 코드로 직접 스프링 빈 등록하기 이렇게 두가지다.
// src/main/java/hello/hellospring/controller/MemberController.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
@Controller
를 붙이면 스프링 컨테이너 안에 MemberController
컨트롤러 객체가 만들어진다.memberService
를 가져다 쓸 수 있음 => new 말고 constructor로 생성해서 하나만 만들어놓고 돌려쓰기@Autowired
가 있으면 스프링이 연관된 객체(여기서는 memberService
겠지)를 스프링 컨테이너에서 찾아서 넣어준다. (=> a.k.a 의존성 주입)
@Autowired
생성자에@Autowired
를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다. 생성자가 1개만 있으면 생략할 수 있다.
여기까지만 쓰면 memberService
가 빈으로 등록되어 있지 않다는 오류가 난다.
// src/main/java/hello/hellospring/service/MemberService.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
...
}
@Service
를 붙여서 컨테이너에 넣어줌@Autowired
를 붙여서 컨트롤러랑 서비스랑 연결시켜줌// src/main/java/hello/hellospring/repository/MemberRepository.java
import org.springframework.stereotype.Repository;
@Repository
public class MemoryMemberRepository implements MemberRepository{
...
}
@Repository
를 붙여서 컨테이너에 넣어줌
@Component
어노테이션이 있으면 스프링 빈으로 자동 등록된다.
@Component
를 포함하는 다음 어노테이션들도 스프링 빈으로 자동 등록된다.
@Controller
@Service
@Repository
원래 Bean 설정파일은 XML과 java 설정파일로 작성하는데, 요즘은 java 설정파일을 더 많이 사용하는 추세다.
DI에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있는데, 생성자 주입을 권장한다.
java 설정파일 안에 자바 클래스를 생성해서, @Configuration
어노테이션을 붙인다. 그리고 그 안에 @Bean
어노테이션을 사용해서 직접 Bean을 정의한다.
1번에서 썼던 어노테이션들 중에 @Service
, @Repository
, @Autowired
는 제거한다.
// src/main/java/hello/hellospring/service/SpringConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
return
되는 객체가 IoC 컨테이너 안에 빈으로 등록된다.
$ sudo 재연이는 바보다