spring Bean(1)

한지개·2023년 4월 3일
0

spring

목록 보기
2/7

컨테이너란?
스프링 컨테이너는 스프링에서 자바 객체를 관리하는 공간이다.
자바 객체를 스프링에선 Bean(빈)이라고 한다.
스프링 컨테이너는 이 빈의 생성~소멸까지 개발자 대신 관리해 주는 곳이다.

스프링 컨테이너에 빈을 등록하는 이유는?
스프링이 각 객체간 의존 관계를 관리하도록 만들기 위함.
의존 관계 - 객체가 의존 관계를 등록할 때는 스프링 컨테이너에서 해당 빈을 찾고 그 빈과 의존성을 만든다.

코드

@Controller
public class MemberController {
	private final MemberService memberService;
    @Autowired
    public MemberController(MemberService memberService) {
    	this.memberService = memberService;
    }
}

@Service
public class MemberService {
	private final MemberRepository memberRepository;
    ...
}

MemberController 클래스에는 @Controller annotation을, 생성자에는 @Autowired annotation을 적어두면 이 인스턴스는 MemberService와 의존 관계를 가진다는 의미이다.

단, @Autowired가 정상적으로 동작하려면 두 인스턴스가 빈으로써 스프링 컨테이너에 들어가 있어야 한다.

(+) 수업 내용

스프링 빈을 등록하는 2가지 방법
1. 컴포넌트 스캔과 자동 의존관계 설정

memberController가 memberService를 통해서 회원가입을 하고, 회원정보를 조회할 수 있어야 한다.
-> 서로 의존 관계가 있다. == memberController가 memberService를 의존한다.

MemberController는 MemberService를 가져다 써야 한다.
privaite final MemberService memberService = new MemberService();
위 처럼 new로 생성해서 쓸 수도 있지만, spring이 관리를 하게되면 전부 spring 컨테이너에 등록하고, spring 컨테이너에서 받아쓰도록 바꿔야 한다.

이유 - MemberController 말고도 다른 컨테이너들이 MemberService를 가져다 쓸 수 있다. 예를 들어서 주문 컨테이너에서도 MemberService를 쓸 수도 있다.

그리고 MemberService를 확인해 보면 별 기능이 없다. 그래서 하나 생성해놓고 공용으로 사용하는 것이 좋다.

연결해주는 방법 :
생성자에 @Autowired를 붙여준다.

MemberController는 spring 컨테이너가 뜰 때 생성을 한다. 그럼 그때 생성자를 호출하는데(MemberController의 생성자) 생성자에 @Autowired가 붙어있으면 MemberService를 spring이 spring 컨테이너에 있는 MemberService를 가져다가 연결 시켜준다.

하지만, HelloSpringApplication을 Run해보면
'hello.hellospring.service.MemberService' that could not be found 라는 에러가 뜬다.
-> @Autowired는 spring 컨테이너에서 MemberService를 가져오는 것인데 HelloController는 spring이 제공하는 컨트롤러여서 spring 빈에 자동 등록된다. (@Controller가 있으면 자동 등록)

MemberService.java를 보면 순수 자바 코드이기 때문에 spring이 자기가 생성해야하는 얜줄 모른다.


그래서 MemberService.java에 @Service를 붙여주고, 이와 마찬가지로 MemoryMemberRepository에는 @Repository를 붙여준다.

Controller와 Service를 연결할 때 생성자에 @Autowired를 붙인다.
-> memberController가 생성이 될때 spring 빈에 등록되있는 memberService 객체를 가져다 넣어준다.
-> DI 의존 관계 주입

@Autowired를 붙여주면 memberService 생성시 spring이 service를 spring 컨테이너에 등록하면서 생성자를 호출한다. 그때 @Autowired가 있으면 spring 컨테이너에 memberRepository를 넣어준다. (memorymemberRepository를 service에 주입해줌.)

컨포넌트 스캔 원리

  • @Component annotation이 있으면 스프링 빈으로 자동 등록된다.
  • @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
  • @Component를 포함하는 다음 annotation도 스프링 빈으로 자동 등록된다.
    (@Controller, @Service, @Repository)

참고: 생성자에 @Autowired 를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다. 생성자가 1개만 있으면 @Autowired 는 생략할 수 있다.

스프링 빈 등록 이미지

memberService 와 memberRepository 가 스프링 컨테이너에 스프링 빈으로 등록되었다.

참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.

참고
김영한 스프링 입문편

profile
평생 소원이 누룽지

0개의 댓글