728x90

MemberController에서 MemberService를 통해 회원가입을 하고 MemberService를 통해서 데이터를 조회할 수 있어야 한다.

MemberController와 MemberService는 의존관계이다.

MemberController가 MemberService를 의존한다.

 

스프링이 시작할 때 스프링 컨테이너에 @Controller, @Service, @Repository 등의 어노테이션을 가진 클래스 객체들을 생성하고 스프링 빈으로 등록해서 관리한다.

 

스프링 컨테이너 : 스프링에서 객체를 관리하는 것. 객체의 생명주기를 관리하고 컨테이너에 담겨있는 객체들을 스프링 빈(Bean)이라고 부른다.

 

@Controller, @Service, @Repository 어노테이션이 존재하는 클래스들의 경우 객체를 스프링 빈(Bean)으로 등록해 스프링 컨테이너에서 관리한다.

 

위처럼 MemberService() 객체를 new로 할당해서 사용할 수도 있지만, Spring 컨테이너에 저장된 빈을 불러서 사용하면된다.

new를 통해 객체를 생성해서 할당할 경우, 모든 Controller가 각각의 Service 객체를 사용하게 된다.

-> 자원이 낭비되며 비효율 적이다.

스프링 컨테이너에는 각 객체들이 하나만 빈으로 등록되어 해당 빈을 공유하는 형태로 사용하기 때문에 new를통한 객체 할당을 통해서 사용하는것보다 훨씬 효율적으로 사용이 가능하다.

생성자에 @Autowired 어노테이션을 사용하면 스프링 컨테이너에 빈으로 존재하는 MemberService 객체를 연결해 준다.

-> MemberController가 memberService를 의존하게 된다. (Dependency Injection : 의존성 주입)

 

@Controller 어노테이션이 존재하는 MemberController 클래스는 스프링이 시작할 때 자동으로 스프링 컨테이너에 스프링 빈으로 등록된다.

@Autowired 어노테이션을 통해 스프링 빈을 연결하는 경우 해당 객체또한 스프링 컨테이너의 스프링빈으로 등록되어 있어야한다. 즉 위 코드에서는 memberService가 스프링 빈으로 등록되어 있어야 한다는 것이다.

@Service 어노테이션의 경우 @Controller와 마찬가지로 스프링이 시작할때 컴포넌트 스캔에 의해 스프링 빈으로 등록된다. MemberService에서도 생성자에서 @Autowired를 사용하는데 이때 사용되는 MemberRepository 또한 스프링 빈으로 등록되어 있어야한다.

@Repository 어노테이션도 스프링 시작시 스프링 빈으로 등록시켜준다.

 

코드들은 위 그림과 같이 의존관계가 연결된다.

 

 

컴포넌트 스캔과 자동 의존관계 설정

@Controller, @Service, @Repository와 같이 어노테이션으로 스프링 빈을 등록하는 경우는 컴포넌트 스캔 방식에 해당한다. @Component 어노테이션이 스프링 빈으로 등록하는 어노테이션이지만, @Controller, @Service, @Repository 어노테이션의 내부에 @Component가 존재해 세가지 어노테이션 모두 스프링 빈으로 등록된다.

 

스프링이 시작할 때 @Component 어노테이션들을 스캔해서 스프링 빈으로 등록하는 것을 컴포넌트 스캔이라고 한다.

@Autowired는 스프링빈을 연결하는 역할을 한다.(의존 관계 설정)

 

@Component스캔의 범위는 @SpringBootApplication 어노테이션이 존재하는 클래스의 패키지와 해당 패키지의 하위패키지에서만 작동한다.

@SpringBootApplication 어노테이션 내부에 @ComponentScan 어노테이션이 존재한다.

 

**스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본적으로 싱글 톤 등록을 한다.**

싱글 톤 : 하나만 등록하여 해당 객체를 공유한다.

예를 들어 MemberController의 경우도 하나의 객체만 컨테이너에 스프링 빈으로 등록해서 공유한다. MemberController 객체가 여러개 스프링빈으로 등록되지않는다.

 

자바 코드로 직접 스프링 빈 등록하기

@Service, @Repository, @Autowired 어노테이션을 제거한 후 코드를 작성한다.

SpringConfig 파일을 새로 하나 생성한다.

@Configuration 어노테이션은 설정 파일을 만들기 위한 어노테이션이며, Bean을 등록하기 위한 어노테이션이다.

@Configuration 클래스 내부에 @Bean 어노테이션 작성시 해당 객체를 Bean에 등록한다는 의미를 가진다.

위 코드는 MemberService와 MemoryMemberRepository 객체를 Bean으로 등록하는 코드이다.

 

위코드를 통해 코드로 직접 스프링 빈을 등록한 경우에도 아래처럼 구조가 가능해진다.

스프링이 시작될 때, memberRepository와 memberService를 스프링 컨테이너에 올려 빈으로 등록한다.

MemberService 생성자에 파라미터로 memberRepository를 넣어주는데 이때 들어가는 memberRepository는 빈으로 등록된 memberRepository이다.

 

자바코드로 직접 등록할 때에도 Controller는 컴포넌트 스캔으로 올라가야 하기 때문에 @Controller 어노테이션을 꼭 써줘야한다. 또한 Controller 생성자에서 스프링 빈 객체를 가져올 때도 컴포넌트 스캔 방법인 @Autowired 어노테이션을 작성해주어야한다.

 

Dependency Injection의 3가지 방법

1.생성자 주입(생성자에 @Autowired 어노테이션 사용)

2.필드주입(필드에 @Autowired 어노테이션 사용)

3.Setter 주입(set 메소드가 public으로 사용되며 어디서든 호출이 가능해져 개발중 문제가 생길 수 있다.)

 

가장 좋은 방법은 생성자 주입이다.(생성자에 @Autowired 어노테이션을 통해 빈 객체를 연결하는것)

 

실무에서는 주로 Controller, Service, Repository와 같은 코드들은 컴포넌트 스캔을 사용한다고 한다. 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하는 경우 설정을 통해 코드로 직접 스프링 빈으로 등록한다고 한다.

 

MemberRepository의 경우 Memory를 사용하는 구현체에서 DB를 사용하는 구현체로 바꿀 예정이기 때문에 컴포넌트 스캔이아닌 코드로 직접 빈에 등록하는 코드를 남겨둔다.

 

@Autowired를 통해 Dependency Injection을 하는 경우 MemberController와 MemberService 와 같이 스프링이 관리하는 객체 즉 스프링 빈 객체들에 한해서만 가능하다. 스프링 빈으로 등록되지 않은 객체들은 @Autowired 사용이 불가능하다.

 

728x90

'Programming > Spring' 카테고리의 다른 글

웹 MVC 개발  (0) 2022.01.08
회원 관리 예제  (0) 2021.12.30
웹개발 기초  (0) 2021.12.21

+ Recent posts