스프링 빈과 의존관계
- Controller가 Service를 통해 기능을 수행(회원가입, 데이터를 조회....)할 수 있어야 한다.
=> Controller가 Service를 의존한다.- Controller와 Service에는 의존관계가 있다.
- Controller를 작성할 때 클래스 선언부 상단에 @Controller 어노테이션을 작성해줘야한다.
Service는 @Service, Repository는 @Repository로 명시한다.- Controller, Service, Repository를 어노테이션으로 명시해줌으로 스프링에서 관리해야 할 클래스임을 스프링에게 알려주는 역할이다.
- 스프링이 실행되면 스프링 컨테이너가 생긴다.
- @Controller, @Service, @Repository 어노테이션을 선언한 클래스의 객체를 생성해서 컨테이너 안에 넣어두고 관리를 한다.
=> 스프링 컨테이너에서 스프링 빈이 관리된다.
- @Controller, @Service, @Repository 어노테이션을 선언한 클래스의 객체를 생성해서 컨테이너 안에 넣어두고 관리를 한다.
@Controller
public class MemberController {
// 직접 주입하는 방식은 좋지 않다.
// private final MemberService memberService = new MemberService();
//@AutoWired를 통해 스프링 컨테이너의 MemberService를 찾아서 연결해준다.
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
- 예시와 같이 Controller와 Service의 의존관계를 명시할 때 직접 객체를 생성해서 사용하는 방식은 좋지 않다.
- @AutoWired 어노테이션을 사용하는 방식으로 의존관계를 명시해야한다.
- 스프링 컨테이너가 생성되서 Controller의 객체가 스프링 빈으로 등록되서 관리된다.
- Service의 객체도 컨테이너의 스프링 빈으로 등록되서 관리가 된다.
- Controller의 MemberService와 컨테이너의 스프링 빈으로 등록된 MemberService 객체를 연결시켜준다.
- 이 방식의 장점으로는 사용할 때마다 객체를 직접 생성할 필요 없이 컨테이너가 스프링 빈으로 등록된 객체를 필요한 곳에 주입시켜준다는 것이다.
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
//내용 생략
}
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
// 내용 생략
}
@Repository
public interface MemberRepository {
//내용 생략
}
- Controller, Service, Repository에 애노테이션을 선언함으로 스프링 컨테이너에서 객체가 스프링 빈으로 등록되고 관리할 수 있게 되었다.
- 서로 간의 의존관계를 @AutoWired 어노테이션이 붙은 생성자를 통해 컨테이너에 등록된 스프링 빈 객체를 주입해준다.
- @AutoWired를 사용하면 객체 생성 시점에 컨테이너에서 해당 스프링 빈을 찾아서 주입한다.
- 생성자가 한 개인 경우 @AutoWired를 생략할 수 있다.
- 스프링 빈을 등록하는 방법
- 컴포넌트 스캔과 자동 의존관계 설정
- @Component 와 관련된 어노테이션이 있는 클래스의 객체를 컨테이너에 자동으로 등록해서 관리한다.
- @Controller, @Service, @Repository ... 등의 내부에는 @Component가 포함하고 있다.
- 스프링을 실행하는 main()이 속한 패키지의 하위에 있는 파일들 중에 @Component가 포함된 클래스를 찾아서 스프링 빈으로 등록한다.
- main()이 속한 패키지보다 상위 패키지 클래스에 @Component를 선언해도 스프링 빈으로 등록되지 않는다.
- 자바 코드로 직접 스프링 빈 등록하기
- @Configuration 어노테이션을 선언한 클래스에 스프링 빈을 직접 등록하는 방식이다.
- 각 객체를 리턴해주는 메소드를 만들고 @Bean으로 선언해준다.
- 이전에는 XML로 작성하는 경우도 있었지만 현재는 Java 코드로 작성한다.
- 컴포넌트 스캔과 자동 의존관계 설정
- 정형화된 Controller, Service, Repository는 컴포넌트 스캔을 사용하고 정형화되지 않거나 상황에 따라 구현체를 변경해야하는 경우에는 설정을 통해 직접 스프링 빈으로 등록한다.
// 직접 스프링 빈을 등록하는 방식
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
- 스프링에서 스프링 컨테이너에 @Configuration으로 스프링 빈을 등록할 때 기본으로 싱글톤 패턴으로 등록한다.
- 유일하게 하나만 등록해서 공유하기에 같은 스프링 빈이면 모두 같은 인스턴스이다.
- @Component는 싱글톤이 보장되지 않는다.
- 유일하게 하나만 등록해서 공유하기에 같은 스프링 빈이면 모두 같은 인스턴스이다.
@Controller
public class MemberController {
// 필드 주입
@Autowired
private MemberService memberService;
// 생성자 주입
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
// setter 주입
@Autowired
public void setMemberService(MemberService memberService) {
this.memberService = memberService;
}
}
- DI(의존관계 주입) 방식
- 필드 주입
- 필드 자체에 @AutoWired로 선언하는 방식
- 스프링 시작될 때 주입한 이후로 의존관계를 바꿀 수 있는 방법이 없기 때문에 좋지 않은 방식이다.
- Setter 주입
- Setter 메소드에 @AutoWired로 선언하는 방식
- Setter 메소드를 public으로 노출시킴으로 언제 어디서든 변경이 가능하기에 위험성이 크다.
- 생성자 주입
- 생성자에 @AutoWired로 선언하는 방식
- 의존관계가 실행중에 동적으로(런타임에) 변하는 경우가 없기 때문에 생성자 주입 방식이 좋다.
- 필드 주입
- @AutoWired를 통한 DI는 스프링이 관리하는 객체에서만 동작한다.
- 스프링 빈으로 등록되지 않은 객체에서는 @AutoWired가 동작하지 않는다.
출처: [인프런 김영한 스프링 입문]
[지금 무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 강의 | 김영한 - 인프
김영한 | 스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., 스프링 학습 첫 길잡이! 개발 공부의 길을 잃지 않도록 도와드립니다. 📣 확
www.inflearn.com
'Spring > [인프런 김영한 스프링 입문]' 카테고리의 다른 글
[인프런 김영한 스프링 입문] 스프링 DB 접근 기술 (0) | 2024.08.09 |
---|---|
[인프런 김영한 스프링 입문] 회원 관리 예제 - 웹 MVC 개발 (1) | 2024.08.09 |
[인프런 김영한 스프링 입문] 회원 관리 예제 - 백엔드 개발 (0) | 2024.08.09 |
[인프런 김영한 스프링 입문] 스프링 웹 개발 기초 (0) | 2024.08.08 |
[인프런 김영한 스프링 입문] 프로젝트 환경설정 (0) | 2024.08.08 |