화면을 붙이고 싶으면 컨트롤러와 뷰 탬플릿이 필요하다. 컨트롤러는 서비스를 통해 회원가입과 데이터를 조회할수 있어야한다.(의존관계)
@Controller를 쓰면, 스프링컨테이너라는 통이 생기는데 거기에 멤버 컨트롤러 객체가 생기고 스프링이 관리를 한다. (스프링 컨테이너에서 스프링 빈이 관리된다고 표현한다.)스프링이 관리를 하게되면 스프링컨테이너에 등록을 하고 받아서 쓰도록 해야한다.
컨트롤러에서 new로 객체를 만들면 다른 컨트롤러등에서 받아서 못쓰는 문제가 발생한다. 그래서 스프링 컨테이너에 등록해서 하나로 쓰면된다.
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
생성자에 @Autowired가 있으면 스프링이 스프링 컨테이너에 있는 memberService를 가져다가 연결시켜준다.(컨트롤러와 서비스 연결,의존관계)
그런데 오류가 나는 이유는 memberService에 가보면 순수한 자바 클래스기 때문에 스프링이 이를 알수없다. 해결방법은 memberService에 @Service를 넣어주는 것이다. (컴포넌트 스캔 방식)
컨트롤러 --> 서비스 --> 리포지토리
컨트롤러에서 외부요청을 받고 서비스에서 비즈니스 로직을 만들고 리포지토리에서 데이터를 저장하는 정형화된 패턴. @Autowired는 이 3개를 연결시켜준다.
@Component 애노테이션이 있으면 스프링 빈으로 자동 등록된다.
@Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
@Component를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록된다.
- @Controller, @Service, @Repository
참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
SpringConfing 클래스를 만들고 @Configuration 과 @Bean을 통해 등록시킨다. 대신 @Controller는 그냥 컴포넌트 스캔 방식으로 하기.
참고: 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다. 그리고 정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.
주의: @Autowired를 통한 DI는 helloController, MemberService등과 같이 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.