05./ Spring -Member-03-Bean 등록-Dependency Injection
@Controller를 하면 spring container가 해당 객체를 생성해서 가지고 있음
=> spring container에서 bean이 관리되고 있는 것임
이때부터는 직접 객체를 생성하지 말고 spring container에서 받아서 써야함.
(안 그러면 이 사람, 저 사람 각자 객체를 생성해서 각자 사용함.. 안좋음 ???)
그래서 spring container에 등록해서 사용하는 방식으로 수정함
그러기 위해서는 생성자에 @Autowired를 해주면됨
그러면 controller -> service -> repository 순으로 dependency injection를 요구함
요청에 따라 @Service, @Repository 를 해줌
생성자가 한개만 있으면 @Autowired를 안해줘도 알아서 함
상호간의 의존관계
controller ===> service ==> repository
Spring bean을 등록하는 방법에는 2가지 방법이 있음
1. 컴포넌트 스캔과 자동 의존 관계 설정(위에 것)
@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 = new MemoryMemberRepository();
}
@Repository
public class MemoryMemberRepository implements MemberRepository{
private static final Map<Long, Member> store = new HashMap<>();
private Long countId = 0L;
@Override
public Member save(Member member) {
member.setId(++countId);
member.setRegDate(new Date());
store.put(member.getId(), member);
return member;
}
@Component로 해도 됨
해당되는 패키지 안에 있는 것만 scan 함.
bean을 등록할때 한개만 등록해서 공유함(특별한 경우 여러개 만들수는 있음)
위에 것은 생성자를 통해 DI(Dependancy Injection)를 수행한 것이나
이를 빼고 인스턴스 맴버 변수에 직접 @Autowired를 붙여도 되지만 잘 안씀
@Autowired private MemberService memberService;
setter를 통해서도 변경 할 수는 있으나 잘 안씀
@Autowired
public void setMemberService(MemberService memberService) {
this.memberService = memberService;
}
2. 자바로 직접 등록하는 것
annotation을 다 지우고
java class 생성(패키지 root에) => @Configuration Annotation 을 적용
내용에 @Bean을 적용하고 내용을 적음
controller ===> service ==> repository
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
}
controller는 그대로 둬야 함..
전에는 xml 파일로 생성하였으나 복잡하고 머리아픔...
3. 케이스 별 사용 예
일반적으로 정형화된 controller, service, repository는 component scan으로 사용하고
정형화되지 않거나, 상활에 따라 구현 클래스를 변경해야 하면 설정을 통해 (자바 config) spring bean에 등록한다.
* spring container에 등록된 것만 @Autowired가 동작함... 당연한 소리긴 한데...