스프링을 실행하면 package hello.hellospring.controller; 경로에 있는 controller를 확인한다.
service를 사용하는데, service에 알맞는 스프링 빈이 없으면 에러가 발생한다.
스프링 빈이 잘 등록되어 있다면 아래와 같은 구조로 스프링은 동작한다.
그렇다면, 스프링 빈은 어떻게 등록하는가??
아래에서 알아보자.
스프링에서 빈(bean) 등록하는 방법에는 2가지가 있다.
1. 컴포넌트 스캔과 자동 의존관계 설정 ( @ComponentScan, DI(Dependency Injection) )
컴포넌트 스캔은 클래스를 스프링 빈에 등록해주는 역할을 한다.
@Component 어노테이션이 있으면 해당 클래스는 스프링 빈으로 자동 등록된다.
어라?? 학원에서 공부할때나 영상에서는 @Component를 안쓰던데..?
@Controller @Service @Repository 같은것만 쓰던데...?
맞다.
@Controller @Service @Repository 에 @Component 어노테이션이 포함(내장)되어 있다.
그래서 @Controller @Service @Repository 로 각각의 클래스의 역할을 나누어서 스프링 빈으로 등록해두고
필요한 객체를 생성할때 @Autowired를 사용해서 스프링 컨테이너에서 일치하는 빈 을 찾아서 연결해준다.
@Service
public class MemberService {
//생성자를 직접 생성해보자.
private final MemberRepository memberRepository = new MemoryMemberRepository();
}
위의 코드에서 new 연산자를 사용해서 MemoryMemberRepository() 객체를 직접 생성했다.
하지만, 스프링은 스프링 컨테이너가 등록된 빈(Bean)을 관리한다.
아래의 코드는 생성자를 직접 생성하지 않고, @Autowired 어노테이션을 사용해서
스프링이 스프링 컨테이너에서 선언된(private final MemberRepository memberRepository;) 객체를
외부에서 넣어준다. 주입한다. => Dependency Injection
인텔리제이(Intellij)에서는 alt+insert 키를 누르면 DI를 할 수 있는 객체가 있는지, 있다면 직접 생성해준다.
@Service
public class MemberService {
//직접 생성하지 않고, 외부에서 주입받아 보자. DI
private final MemberRepository memberRepository;
//DI 완료
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
2. 자바 코드로 직접 스프링 빈(Bean) 등록하기
@Configuration 어노테이션을 사용해서 직접 스프링 빈을 등록할 수 있다
@Bean 어노테이션을 사용해서 메서드를 스프링 빈에 등록할 수 있다.
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired //생성자
//@Autowired 를 사용하면, 스프링이 스프링컨테이너에서 관리하는 항목중에 일치하는것을 가져와서 알아서 사용함
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
public class MemberService {
//직접 생성하지 않고, 외부에서 주입받아서 써보자. DI
//private final MemberRepository memberRepository = new MemoryMemberRepository();
private final MemberRepository memberRepository;
//DI 완료
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
1번 방법과 다르게, 자바 코드로 직접 스프링 빈을 등록해보자.
@Service 어노테이션이 없기 때문에 위 클래스는 스프링 빈에 등록되어 있지 않다.
그렇기 때문에 @Controller 어노테이션이 있는 클래스에서 MemberService와 MemberRepository를 연결 받을 수 없다.
@Configuration 어노테이션을 사용해서 직접 스프링 빈을 등록해보자.
@Bean 어노테이션을 사용해서 메서드를 스프링 빈에 등록할 수 있다.
MemberService는 구현체 memberRepository()를 매개변수로 받도록 => service는 repository를 인자로..
MemberRepository는 인터페이스는 생성할 수 없으니 구현체 MemoryMemberRepository()를 반환한다.
이렇게 service와 repository를 스프링 빈에 직접 등록할 수 있다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository(); /* 구현체 MemberRepository 를 생성한다.
=> public class MemoryMemberRepository implements MemberRepository
인터페이스는 new 할수없기 때문에. MemberRepository 는 interface 이기 때문이다.
==> 즉, 인터페이스는 new 불가 / 구현체는 new 가능
*/
}
}
[Spring] @ResponseBody 어노테이션 처리/반환 (0) | 2024.02.28 |
---|---|
[Spring] getter / setter 단축키 (인텔리제이) (0) | 2024.02.27 |
[Spring] java 버전, SDKs 등 변경 후 메인 메서드 실행시 오류 (인텔리제이) (2) | 2024.02.27 |
[Spring] gradle build 그래들 빌드하기 (0) | 2024.02.27 |
[Spring] 인텔리제이 Java version 확인, 환경변수 JAVA_HOME 확인/변경 방법 (2) | 2024.02.27 |