Spring Bean은 Spring IoC 컨테이너에서 관리하는 자바 객체이다. Spring Bean을 등록하면 Spring 컨테이너에서 관리해주고, 그것을 필요로 하면 직접 new를 통해 새로 생성해서 사용하는 것이 아니라 Spring이 관리하는 객체를 주입 받아서 사용하게 된다.
예를 들어 MemberController 라는 컨트롤러에서 MemberService 라는 서비스를 사용해야 한다고 하자. 그러면 Spring에서는 MemberController 에서 new MemberService(); 를 통해 직접 MemberService를 생성해서 쓰는 것이 아니라, 다음 화면과 같이 Spring이 관리하는 객체를 주입 받아서 사용해야 한다.

MemberService 를 생성자의 인자로 전달받아서 그것을 인스턴스에 등록하여 사용하는 형태로 되어있다. Spring이 구동되면서 Spring Bean을 등록하고 생성자 위에 @Autowired를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다. 생성자가 1개만 있으면 @Autowired 는 생략할 수 있다. 즉, @Autowired 애노테이션이 있으면 Spring 컨테이너에서 관리하는 연관된(서비스, 레포지토리 등) 객체를 찾아서 주입시켜 연결해준다. 이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI(Dependency Injection), 의존성 주입이라고 한다.

memberService 와 memberRepository 가 스프링 컨테이너에 스프링 빈으로 등록되었다.
Spring Bean을 사용하려면 우선 Spring Bean을 등록해야하는데, 등록하는 방법으로는 2가지가 있다.
컨트롤러는 스프링이 뜰 때 스프링 컨테이너에 뜬다.
Spring이 구동될 때, 컴포넌트들을 찾으면서 이것들을 Spring Bean으로 자동 등록한다. 즉, Spring Bean으로 특정 객체를 등록하고 싶다면 컴포넌트라는 것을 애노테이션으로 명시해두면 된다.
다음과 같은 컴포넌트 스캔 원리로 애노테이션을 명시한다.
컴포넌트 스캔 원리
스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
SpringConfig 파일을 생성하고 생성자 앞에 @Bean 어노테이션을 붙여 스프링 빈을 등록할 수 있다.
- DI에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있다. 의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.
- 생성자 주입 - 생성자를 통해서 들어옴 ( 가장 권장)
- 필드 주입 - 생성자를 빼고 필드에다 @Autowired를 앞에 붙인다. ( 별로 좋지 않은 방법 ) -> 중간에 바꾸기가 힘들기 때문에
- Setter 주입 - Setter 메소드 앞에 @Autowired , 단점은 누군가가 멤버 컨트롤러를 호출했을 때, 퍼블릭으로 열려있어야하기 떄문에 노출됨
- 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다.
그리고 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.- @Autowired 를 통한 DI는 helloConroller , memberService 등과 같이 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
요청이오면 먼저 관련 Controller 이 있는지 찾고 없으면 static 파일을 찾음
url 창에 url 입력하고 엔터치는 것은 보통 @GetMapping(조회할 때 사용)
@PostMapping : 데이터를 폼 같은 곳에 넣어서 전달할 때 사용 (데이터 등록할 때 사용)
@PostMapping이 사용된 메소드가 호출되고 그 메소드의 파라미터는 memberform 클래스이므로 memberform에서 name (html 파일name값과 같다)값을 스프링에서 setter 메소드를 호출하여 값을 넣어준다. name 변수 자체는 private이기 때문에 접근 불가능하다.