본문 바로가기
Spring_inflearn/입문

[Spring] inflearn 스프링 입문 - 스프링 빈과 의존관계 1

by clolee 2022. 9. 12.

컴포넌트 스캔과 자동 의존관계 설정

 

회원가입, 회원가입결과 html에 보여주기 <- member controller 만들어야 함

MemberController가 MemberService 통해 회원 가입하고 MemberService 통해 데이터 조회할 수 있어야 함.

MemberController가 MemberService를 의존한다. 의존관계가 있다.

 

스프링 컨테이너가 스프링 창에 뜰 때 @Controller 어노테이션이 있으면 스프링 컨테이너에 Controller객체(MemberController)를 생성해 스프링에 넣어줌. 스프링이 관리. 스프링 컨테이너에서 스프링 빈이 관리된다 고 표현

hello-spring/src/main/java/hello/hellospring/controller/MemberController.java

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;

@Controller
public class MemberController {
}

memberService 사용 시 new MemberService()로 사용할 수 있음.

private final MemberService memberService = new MemberService();

하지만 스프링이 관리하게 되면 스프링 컨테이너에 등록하고 스프링 컨테이너로부터 받아서 쓰도록 바꿔야 함

new MemberService() 로 하면 MemberController 말고 다른 여러 controller들이 MemberService 가져다 쓸 수 있음.

여러 개 인스턴스 생성하지 않고 하나만 만들어 공용으로 사용하는 것이 좋음.

 

command + N : Generate

Constructor 만들기

 

스프링 컨테이너에 등록 (하나만 됨) 하고 사용. 생성자로 연결. controller 생성 시 생성자 호출.

@Autowired : 스프링이 스프링 컨테이너에 있는 memberService를 가져다가 연결시켜줌.

package hello.hellospring.controller;

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
	public MemberController(MemberService memberService) {
		this.memberService = memberService;
	}
}

 

실행 => 오류 => MemberService를 찾을 수 없다.

 

MemberService : 순수한 자바 class. 스프링이 알 수 있는 방법이 없음.

@Service 넣어줌. 스프링이 컨테이너에 MemberService를 등록해줌 

MemoryMemberRepository : @Repository.

 

controller 통해서 외부 요청받고 service에서 비지니스 로직 만들고 repository에서 데이터 저장. 정형화된 패턴.

 

스프링이 뜰 때 controller, service, repository 가지고 옴

 

controller와 service 연결 : @Autowired 

MemberController 생성 될 때 스프링 빈에 등록되어있는 MemberService 객체를 가져다 넣어줌. Dependency Injection. 의존관계 주입

hello-spring/src/main/java/hello/hellospring/controller/MemberController.java

package hello.hellospring.controller;

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
	public MemberController(MemberService memberService) {
		this.memberService = memberService;
	}
}

hello-spring/src/main/java/hello/hellospring/service/MemberService.java

 

@Autowired

MemberService 는 MemberRepository가 필요. 스프링이 MemberService를 생성할 때 @Service 보고 스프링 컨테이너에 MemberService 등록하며 생성자 호출. 이때 @Autowired가 있으면 MemberRepository가 필요하다고 판단. MemberRepository 스프링 컨테이너에 넣어줌. MemoryMemberRepository 가 구현체로 있으므로 MemoryMemberRepository를 서비스에 주입

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class MemberService {
	private final MemberRepository memberRepository;

	// 생성자
	@Autowired
	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) {
		memberRepository.findByName(member.getName())
				.ifPresent(m -> {
					throw new IllegalStateException("이미 존재하는 회원입니다.");
				});
	}

	/**
	 * 전체 회원 조회
	 */
	public List<Member> findMembers() {
		return memberRepository.findAll();
	}

	public Optional<Member> findOne(Long memberId) {
		return memberRepository.findById(memberId);
	}
}

 

메인메소드 실행

문제없이 실행

 

컴포넌트 스캔

@Service , @Controller, @Repository : @Component의 특수화된 케이스. 들어가 보면 @Component 라고 붙어있음

스프링이 올라올 때 @Component 관련 어노테이션이 있으면 스프링이 다 객체를 생성해 스프링 컨테이너에 등록

 

Controller.java

 

자동 의존관계 설정

@Autowired는 관계를 연결해줌

MemberController가 MemberService를 쓸 수 있게 해주고, MemberService가 MemberRepository를 쓸 수 있게 됨

 

@Component 어노테이션이 있으면 스프링 빈으로 자동 등록된다.

 

@SpringBootApplication 부터 시작해  패키지를 포함한 하위 패키지들은 스프링이 어노테이션을 찾아 스프링 빈으로 등록한다.

하위 패키지가 Application 패키지와 동일하거나 하위 패키지가 아닌 경우 컴포넌트 스캔하지 않는다.

여기선 hello.hellospring

 

스프링은 스프링컨테이너에 스프링 빈을 등록할 때 싱글톤(유일하게 하나만)으로 등록한다. 하나만 등록해서 공유(ex) helloController 1개, memberService 1개, memberRepository 1개)

같은 스프링 빈이면 모두 같은 인스턴스.

 

 

 

 

댓글