- 데이터베이스
- jpa
- string
- spring
- springboot
- java
- spring boot
- 스프링
- DI
- 자바
- Django
- session
- 스프링부트
- 프로그래머스
- sql
- @transactional
- nginx
- join
- 문자열
- select
- 1차원 배열
- Docker
- SSL
- PYTHON
- ORM
- spring security 6
- Git
- spring mvc
- AWS
- mysql
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
개발하는 자몽
[Spring]빈 등록과 의존관계 주입 본문
수동 빈 등록과 의존관계 주입
@Bean 애노테이션은 method-level로 수동으로 빈을 등록할 때 사용한다. 메서드가 선언된 클래스 상단에는 @Configuration 애노테이션을 붙여 설정 정보 클래스임을 알려주고, 싱글톤이 깨지지 않도록 한다. (@Configuration을 붙이지 않아도 @Bean을 붙이면 다 빈으로 동록 되지만 싱글톤이 깨진다.)
/*
수동 빈 등록 및 의존관계 주입
@Configuration, @Bean
*/
package hello.core;
...
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
//memberService에 의존관계로 memberRepository 주입
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
//orderService에 의존관계로 memberRepository, discountPolicy 주입
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
각 메소드 상단에 위치한 @Bean 애노테이션은 메서드 이름으로 스프링 빈을 스프링 컨테이너에 등록한다는 의미이다.
이러한 설정정보 클래스나 파일을 이용하여 DIP, OCP를 준수하여 의존관계를 주입할 수 있다. 위 예제를 이용하자면, MemberServiceImpl, OrderSerivceImpl의 생성자를 호출하면 의존관계 주입이 처리된다. 스프링은 이러한 동적인 객체 인스턴스 의존관계를 다 연결해준다. (객체의 참조값이 연결됨)
Note @Configuration 스프링 공식 문서 - Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime, for example: ..
자동 빈 등록과 의존관계 주입
@ComponentScan 애노테이션은 @Component 애노테이션이 붙은 클래스를 자동으로 빈으로 등록한다. @Configuration 애노테이션도 붙여줘서 설정 정보 클래스임을 알려주고 싱글톤을 깨뜨리지 않도록 한다.
/*
자동 빈 생성과 의존관계 주입
@Configuration, @ComponentScan
*/
package hello.core;
...
@Configuration
@ComponentScan
public class AutoAppConfig {
}
Note @Configuration 애노테이션 안에는 @Component 애노테이션이 포함되어있어서 해당 애노테이션이 붙은 클래스도 빈으로 등록한다.
자동으로 빈을 생성하고 의존관계를 주입할 때는 @Bean 애노테이션과 함께 빈으로 등록할 메서드와 의존관계로 주입할 메서드를 다 입력했다. 자동의 경우 수동으로 빈을 등록하는 것에 비해 코드가 간결하다. 하지만 이 경우 의존관계를 어떻게 주입해야 할까.
위 예제를 이용하면, MemberServiceImpl와 OrderServiceImpl 생성자 위에 @Autowired 애노테이션을 붙이면 된다.
//MemberService
package hello.core.member;
...
@Component
public class MemberServiceImpl implement MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRespotiroy memberRepository) {
this.memberRepository = memberRepository;
}
...
}
// -------------------------------------------------------------------------
//OrderService
package hello.core.order;
...
@Component
public class OrderServiceImpl implement OrderSerivce {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderService(MemberRepository memberRepository, DiscountPolicy discountPolicy) {\
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
...
}
또힌 위에서 언급한 것처럼 빈으로 등록하기 위해 클래스 상단에 @Compoent 애노테이션을 붙여주면 된다. 마찬가지로 의존관계로 주입되는 클래스(구현체)의 상단 위에도 @Component 애노테이션을 붙여준다.
따라서 @ComponentScan을 사용하면 @Autowired를 사용해야 한다. 빈이 자동으로 등록되는데 의존관계를 수동으로 등록할 수 없기 때문이다.
@ComponentScan은 @Component가 붙은 클래스를 찾아 빈으로 등록한다고 했는데, 기본적으로 @ComponentScan이 붙은 클래스가 속한 패키지를 시작으로 모든 클래스를 찾는다. 또한 basePackage나 basePackageClasses를 지정하면 원하는 탐색 시작 위치를 지정할 수 있다.
/*
basePackages 또는 basePackageClasses가 없으면
default로 @ComponentScan이 붙은 클래스가 속한 패키지가 탐색 시작 위치다.
*/
package hello.core;
...
@Configuration
@ComponentScan(
// basePackages = "hello.core" //hello.core 패키지를 시작으로 탐색
// basePackageClasses = AutoAppConfig.class //이 클래스가 속한 패키지를 시작으로 탐색
)
public class AutoAppConfig {
}
'Java > Spring' 카테고리의 다른 글
프록시(Proxy) (0) | 2022.08.13 |
---|---|
Dependency LookUp (0) | 2022.08.12 |
AnnotationConfigApplicationContext와 static class (0) | 2022.08.03 |
스프링 부트 공부 (10), AOP (0) | 2022.03.20 |
스프링 부트 공부 (9), 스프링 DB 접근 기술 (0) | 2022.03.12 |