Spring/spring_old

05./ Spring -Member-03-Bean 등록-Dependency Injection

slow333 2023. 1. 12. 14:38

@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가 동작함... 당연한 소리긴 한데...