스프링 빈
스프링 빈은 스프링 컨테이너에 의해서 관리되는 자바 객체를 의미.
스프링 빈 등록 방식
component scan
자바 클래스 위에 @Component 어노테이션을 붙이면 해당 클래스는 스프링이 자동으로 스프링 빈으로 등록해준다.
@Component를 상속받는 어노테이션의 종류
-@Controller
스프링 MVC 컨트롤러로 인식된다. (스프링에 다양한 정보를 던줌)
-@Repository
스프링 데이터 접근 계층으로 인식된다. (다양한 기능적인 로직 구현)
-@Service
스프링 비즈니스 계층으로 인식된다. (서비스 계층에서 레포지토리에서 만들어진 기능을 활용해 비즈니스적으로 구현)
-@Configuration
스프링 설정 정보로 인식된다.
Defendency injection (의존 관계 설정)
@Autowired
클래스가 스프링 빈으로 연결되어 스프링에서 생성자가 실행될때, 인자의 값이 이미 스프링 내부에 있는 값으로 넣어짐.
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.springframework.stereotype.Repository;
import java.util.*;
@Repository //레포지토리 스피링 빈으로 등록
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
@Override
public Member save(Member member) {
member.setId(++sequence); //member에 id 부여
store.put(member.getId(), member ); //Map에 id와 member 인스턴스 저장
return member;
}
@Override
public Optional<Member> findById(Long id) {
return Optional.ofNullable(store.get(id)); //id가 존재시 해당 멤버 반환. 없다면 null 반환
//Optional.ofNullable()은 get(id)의 반환값이 null일때를 대비해서 감싸줌
}
@Override
public Optional<Member> findByName(String name) {
return store.values().stream()
.filter(member->member.getName().equals(name)) //member의 getName() 반환값이 name과 같은 경우에만 필터링
.findAny();
}
@Override
public List<Member> findAll() {
return new ArrayList<>(store.values()); //member들이 반환
}
public void clearStore(){
store.clear(); //저장소 비우는 코드
}
}
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service //서비스 스프링 빈을 등록
public class MemberService { //MemoryMemberRepository 클래스의 기능을 비즈니스 로직으로 구현
//MemberRepository는 인터페이스. MemoryMemberRepository는 MemberRepository 상속받는 클래스
private final MemberRepository memberRepository;
@Autowired //@Autowired: defendency injection 해줌
//스프링에서 MemberService가 인스턴스 넘어가서 생성자가 실행될 때
// 스프링 내부에 있는 memberRepository를 인자로 넣어줌.
// 따라서 memberRepository는 빈으로 등록되어있어야함
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
/*
회원 가입
*/
public Long join(Member member){
//같은 이름이 있는 중복 회원x
validateDuplicateMember(member); //중복 회원 검증
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
Optional<Member> result = memberRepository.findByName(member.getName());
result.ifPresent(m -> { //ifPresent는 Optional의 메소드. 값이 널이 아니라면 실행
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
/*
* 전체 회원 조회
*/
public List<Member> findMembers(){
return memberRepository.findAll();
}
public Optional<Member> findOne(Long memberId){
return memberRepository.findById(memberId);
}
}
package hello.hellospring.controller;
import hello.hellospring.domain.Member;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller //스프링 컨트롤러로 등록(스프링 빈)
public class MemberController {
private final MemberService memberService;
@Autowired //defendency injection 해줌
//MemberController의 생성자가 실행시 스프링 내부에 있는 memberService를
//자동으로 인자로서 넣어준다.
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
(세번째 코드 블록에서)MemberController의 생성자가 실행될 때 인자로 MemberService memberService가 들어와야 하는데, 이게 이미 스프링 내부에 있는 값이 들어온다는 것임. 따라서 MemberService도 스프링 빈으로 선언이 되어 있어야한다.(스프링 내부에 존재하기 위해서)
'Spring' 카테고리의 다른 글
Spring- 스프링 컨테이너로 등록하기(1) (0) | 2023.01.17 |
---|---|
Spring- IoC, DI 컨테이너 (0) | 2023.01.17 |
Spring- Dependency Injection(의존 관계 주입) (0) | 2023.01.13 |
Spring- 객체 지향의 SOLID 원칙 (0) | 2023.01.12 |
Spring- 자바 코드로 직접 스프링 빈 등록 (0) | 2023.01.04 |