-
TIL 20일차 (2021.11.10)TIL(Today I Learned) 2021. 11. 10. 17:12
스프링 빈, 스프링 컨테이너
MVC 과정에서 Controller는 스프링 컨테이너에 저장되어있다가 호출되는 방식.
스프링빈 의존관계 추가(컴포넌트 스캔 방식)
public class MemberController { private final MemberService memberService = new MemberService(); }
-> 이 코드는 이미 MemberService가 다른 클래스 파일에 선언되어있으므로 new로 중복되어 안정적이지 못하다, 하나만 생성해서 공유하는 방식이 효율적이다.(DI 방식,)
public class MemberController { private final MemberService memberService; // 스프링컨테이너 공용 사용 @Autowired public MemberController(MemberService memberService) { this.memberService = memberService; } }
- MemberService 생성자를 구현한다.
- Autowired를 통해 스프링컨테이너에서 MembeService 객체를 공용으로 공유할 수 있다. (DI)
//MemberService class @Service public class MemberService { private final MemberRepository memberRepository; @Autowired public MemberService(MemberRepository memberRepository) { this.memberRepository = memberRepository; }
//MemberRepository class @Repository public class MemoryMemberRepository implements MemberRepository{ //연습이기 때문에 동시성 문제 발생할 수 있음(해결방법 : Concurrent) private static Map<Long, Member> store = new HashMap<>(); private static long sequence = 0L; @Override public Member save(Member member) { member.setId(++sequence); store.put(member.getId(), member); return member; }
- hellocontroller -> memberservice -> memberrepository (서로간 AutoWired로 연결)
- hellocontroller에 memberservice를 연결해주고, memberservice에 memberrepository를 연결해준다.
- 순수 자바 클래스에서 객체 생성 위에 MemberService 위에는 @Service MemberRepository 위에는 @Repository를 선언해줘서 스프링에서
인식을 하면 Autowired되게 해준다. - @Service 또는 @Repository 안에는 'Component'라는 Annotation이 존재한다.
- 스프링은 스프링 컨테이너에 스프링빈을 하나만 등록하는 싱글톤으로 등록한다.(유일하게 하나만 등록해서 '공유'한다.)
- 따라서 같은 스프링 빈이면 모두 같은 객체이다. 단, 특별한 경우 설정으로 싱글톤이 아니게할 수 있다..
Annotation
- (Annotation = @를 사용한 주석, 컴파일러가 특정 오류를 억제하도록 지시하는것과 같이 프로그렘에 관한 데이터를 제공, 코드에 정보를 추가하는 정형화된 방법 )
- 예시 ) @Repository, @Service, @Controller, @Autowired, @Resource
- 장점 : 데이터들에 대한 유효 조건을 쉽게 파악할 수 있게되며, 코드의 양도 줄어듦,
Component Annotation
-> 기본적으로 같은 package 안에 있는 file만 선언 가능하다.(ComponentScan)
자바 스프링빈 직접 작성
//SpringConfig.java /** * spring bean을 이용한 DI */ @Configuration public class SpringConfig { @Bean public MemberService memberService(){ return new MemberService(memberRepository()); } @Bean public MemberRepository memberRepository(){ return new MemoryMemberRepository(); } }
-> 위에서 설명한 컴포넌트 스캔과 똑같이 hellocontroller -> memberservice -> memberrepository로 연결
DI 종류
-> 필드 주입
@Autowired private MemberService memberService;
필드 주입은 수정할 수가 없어서 별로 안좋다.
-> setter 주입
// @Autowired // public void setMemberService(MemberService memberService) { // this.memberService = memberService; // }
setter 주입은 public으로 설정해야해서 보안에 취약하거나, 잘못된 수정에 취약하다.
-> 생성자 주입
@Autowired // spring container 공용 사용 public MemberController(MemberService memberService) { this.memberService = memberService;
의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 통해 수정을 막을 수 있다.
스프링 빈 vs 컴포넌트 스캔
-> 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다.
-> 정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.
->@Autowired
를 통한 DI는 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.(스프링 컨테이너에 등록된것만 관리한다.)
차이) 1. 직접 생성한 객체MemberService memberService = new MemberService();
2. 스프링 컨테이너에 적재된 객체 ``` public MemberService(MemberRepository memberRepository){ this.memberRepository = memberRepository; } ```
'TIL(Today I Learned)' 카테고리의 다른 글
TIL(22일차)(2021.11.12) (0) 2021.11.12 TIL 21일차(11.11) (0) 2021.11.11 TIL 19일차(2021.11.09), 단축키 TIP 모음, intellij create git (0) 2021.11.09 TIL 18일차(2021.11.8) (0) 2021.11.08 TIL 17일차(2021.11.07) (0) 2021.11.07