@Qualifier
@Qualifier 어노테이션을 통해 같은 타입의 빈이 여러개인 경우 주입받을 빈을 지정할 수 있다.
package com.sample.spring.repository;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
@Repository
@Qualifier("primaryRepository")
public class SampleRepositoryImpl2 implements SampleRepository {
public int getLastUserId() {
return 200;
}
}
package com.sample.spring;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import com.sample.spring.repository.SampleRepository;
@Component
public class Application {
private final SampleRepository sampleRepository;
public Application(@Qualifier("primaryRepository") SampleRepository sampleRepository) {
this.sampleRepository = sampleRepository;
}
public void run() {
System.out.println(sampleRepository.getLastUserId());
}
}
동일한 Qualifier를 가진 빈을 찾아 등록해준다.
SampleRepositoryImpl1에 @Primary 어노테이션을 붙이더라도 @Qualifier 어노테이션 우선순위가 더 높기 때문에 @Primary 어노테이션은 무시된다.
package com.sample.spring.repository;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;
@Repository
@Primary
public class SampleRepositoryImpl1 implements SampleRepository {
public int getLastUserId() {
return 100;
}
}
결과
200
아래와 같이 클래스명을 camelCase로 나타낸 문자열은 자동으로 Qualifier로 등록되므로, @Qualifier(”sampleRepositoryImpl2”) 없이 사용 가능하다. 그러나 구체 클래스명에 강하게 의존하므로 좋은 방법은 아니다.
public Application(@Qualifier("sampleRepositoryImpl2") SampleRepository sampleRepository) {
this.sampleRepository = sampleRepository;
}
@PropertySource
설정 클래스에 @PropertySource 어노테이션을 지정하면 외부 설정 파일을 읽어올 수 있다.
@Configuration
@ComponentScan
@PropertySource("classpath:application.properties")
public class Config {
}
# src/main/resources/application.properties
group.key = value
package com.sample.spring;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import com.sample.spring.repository.SampleRepository;
@Component
public class Application {
private final SampleRepository sampleRepository;
private final Environment env;
public Application(SampleRepository sampleRepository, Environment env) {
this.sampleRepository = sampleRepository;
this.env = env;
}
public void run() {
System.out.println(env.getProperty("group.key")); //value
System.out.println(sampleRepository.getLastUserId()); //200
}
}
또는 SpEL과 @Value 어노테이션을 이용해 Environment 객체 주입 없이 값을 가져올 수도 있다.
package com.sample.spring;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.sample.spring.repository.SampleRepository;
@Component
public class Application {
private final SampleRepository sampleRepository;
@Value("${group.key}") //SpEL 이용해 application.properties의 값을 가져옴
private String test;
public Application(SampleRepository sampleRepository) {
this.sampleRepository = sampleRepository;
}
public void run() {
System.out.println(test);
System.out.println(sampleRepository.getLastUserId());
}
}
@Profile
설정 클래스에 @Profile 어노테이션을 붙여 특정 프로파일에서만 설정 클래스가 유효하도록(특정 프로파일이 아니면 무시됨) 할 수 있다.
package com.sample.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@ComponentScan
@Profile("prod")
public class ProdConfig {
}
JVM 실행 시 -Dspring.profiles.active=”dev” 옵션을 통해 프로파일을 지정할 수 있다.
Laze load
@Component 어노테이션을 가진 클래스에 @Lazy 어노테이션을 추가하면 Lazy-initialized bean으로 지정할 수 있다.
스프링 컨테이너가 생성될 때 빈 객체가 생성되지 않고, 실제 빈 요청이 들어올 때 생성된다.
ApplicationContext의 다른 기능
ApplicationContext는 빈과 관련된 기능을 포함해 아래와 같은 기능들을 제공한다.
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#context-introduction
- BeanFactory 인터페이스를 통한 빈 생성/주입/관리
- MessageSource 인터페이스를 통한 국제화
- ResourceLoader 인터페이스를 통한 URL/파일 등의 리소스 접근
- ApplicationListener 인터페이스를 통한 Bean 이벤트 발행
- HierarchicalBeanFactory 인터페이스를 통한 계층적 context 지원
코드
https://github.com/youhogeon/lickTheSpring/tree/ccc3faf4736b12c14a89f3ad1b22b3f89d561dbc
PS
여기까지가 Spring framework document - core의 1장 내용이다.
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans
'핥아먹기 시리즈 > Spring Core 핥아먹기' 카테고리의 다른 글
13. Null Safety (0) | 2022.12.28 |
---|---|
12. Resource 인터페이스 (0) | 2022.12.28 |
10. Component Scan과 생성자 주입 (0) | 2022.12.28 |
9. 의존관계 자동 주입 (@Autowired) (0) | 2022.12.28 |
8. 빈 생명 주기 (0) | 2022.12.28 |