1. XML 없이 빈 정의
클래스패스 스캔
- Spring은 자동으로 후보 클래스를 탐지하고 이를 빈으로 등록할 수 있음
- XML 구성이 아닌 어노테이션으로 지원함
2. Bean Annotation
메타 어노테이션
어노테이션 | 설명 | 용도 |
@Component | Spring 관리 빈을 정의하는 일반적인 어노테이션 |
모든 컴포넌트 클래스
|
@Repository | 영속성 계층을 담당하는 클래스에 사용 예외 자동 변환 지원 |
데이터 액세스 객체(DAO) 클래스
|
@Service | 서비스 계층을 담당하는 클래스에 사용 |
서비스 클래스
|
@Controller | 웹 계층(Spring MVC)을 담당하는 클래스에 사용 |
웹 컨트롤러 클래스
|
복합 어노테이션
어노테이션 | 사용된 메타 어노테이션 | 설명 |
@RestController | @Controller, @ResponseBody |
REST API 컨트롤러로 사용
HTTP 응답 본문에 데이터를 직접 반환하도록 처리 |
@SessionScope | @Scope(WebApplicationContext.SCOPE_SESSION) |
세션 범위에서만 유효한 빈을 생성
기본적으로 proxyMode는 TARGET_CLASS로 설정 |
3. @Bean
- 사용자 빈 정의 어노테이션
- @Configuration / @Component 내에서 메서드 정의를 통해 등록할 수 있음
예제
더보기
더보기
@Component
public class FactoryMethodComponent {
@Bean
@Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
public void doWork() {
// Component method implementation omitted
}
}
애노테이션
어노테이션 | 역할 | 비고 |
@Bean | 메서드가 빈 팩토리 메서드로 작동 |
메서드가 빈을 정의하는 역할
|
@Qualifier | 특정 빈을 구별하는 역할 |
같은 타입의 빈이 있을 때 구별을 위한 이름 지정
|
@Scope | 빈의 스코프 정의 |
Singleton, Prototype 등
|
@Lazy | 지연 초기화 |
의존성 주입 시 lazy proxy 생성
|
@Value | Spring Expression Language (SpEL) 사용 |
값 주입에 SpEL 사용 가능
|
특징
주제 | 설명 |
InjectionPoint 사용 |
@Bean 메서드에서 InjectionPoint를 사용하여 빈 생성에 필요한 메타데이터를 접근할 수 있음
|
Static @Bean 메서드 |
정적 @Bean 메서드는 CGLIB 프록시를 우회할 수 있음
초기화 단계에서 문제가 발생하지 않음 |
빈 이름 자동 생성 |
기본적으로 빈 이름은 클래스 이름을 소문자로 변환한 값으로 자동 생성됨
|
예제) InjectionPoint
더보기
더보기
@Component
public class FactoryMethodComponent {
@Bean @Scope("prototype")
public TestBean prototypeInstance(InjectionPoint injectionPoint) {
return new TestBean("prototypeInstance for " + injectionPoint.getMember());
}
}
고급 기능
주제 | 설명 |
BeanNameGenerator | @ComponentScan에서 빈 이름 생성 전략을 커스터마이즈할 수 있음. 기본적으로 AnnotationBeanNameGenerator가 사용됨 이를 커스터마이즈하려면 BeanNameGenerator를 구현해야 함. |
ScopeResolver | 빈의 스코프를 해결하는 전략을 커스터마이즈할 수 있음. ScopeMetadataResolver를 구현하여 사용자 정의 스코프 해결 전략을 설정. |
ScopedProxy |
비싱글톤 스코프의 빈에 대한 프록시를 생성할 때 사용하는 설정.
scopedProxy 속성을 사용하여 targetClass 또는 interfaces로 설정. |
예제) BeanNameGenerator
더보기
더보기
@Configuration
@ComponentScan(basePackages = "com.example", nameGenerator = CustomBeanNameGenerator.class)
public class AppConfig {
// 빈 설정
}
class CustomBeanNameGenerator implements BeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, AnnotationConfigApplicationContext context) {
// 커스터마이즈된 빈 이름 생성 로직
return "custom" + definition.getBeanClassName().toLowerCase();
}
}
예제) ScopeResolver
더보기
더보기
@Configuration
@ComponentScan(basePackages = "com.example", scopeResolver = CustomScopeResolver.class)
public class AppConfig {
// 빈 설정
}
class CustomScopeResolver implements ScopeMetadataResolver {
@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
// 사용자 정의 스코프 해결 전략 (예: 프로토타입 빈으로 설정)
ScopeMetadata metadata = new ScopeMetadata();
metadata.setScopeName("prototype");
return metadata;
}
}
예제) ScopedProxy
더보기
더보기
@Configuration
@ComponentScan(basePackages = "com.example", scopedProxy = ScopedProxyMode.TARGET_CLASS)
public class AppConfig {
// 빈 설정
}
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MyPrototypeBean {
// 프로토타입 빈 설정
}
3. 클래스패스 스캔
@ComponentScan
- 특정 조건에 맞는 컴포넌트를 자동으로 스캔하여 빈을 등록할 수 있음
- 반드시 @Configuration과 함께 사용해야 함
속성 | 설명 |
basePackages | 스캔할 기본 패키지 경로 지정 (복수 패키지 지정 가능) |
basePackageClasses | 스캔할 기본 패키지 경로를 클래스 기준으로 지정 |
includeFilters | 포함할 클래스를 필터링하는 필터 목록 (조건에 맞는 클래스만 스캔) |
excludeFilters | 제외할 클래스를 필터링하는 필터 목록 (조건에 맞는 클래스 제외) |
useDefaultFilters | 기본 필터 사용 여부 설정 (기본값 true, 기본 필터를 사용하지 않으려면 false로 설정) |
lazyInit | 빈 초기화를 지연시킬지 여부 (기본값 false -> 초기화 즉시) |
scopeResolver | 스코프를 결정할 커스텀 resolver 지정 |
nameGenerator | 빈의 이름 생성기를 지정 |
필터
유형 | 예시 표현식 | 설명 |
annotation | org.example.SomeAnnotation |
클래스에 특정 어노테이션이 있어야 매칭
|
assignable | org.example.SomeClass |
특정 클래스나 인터페이스를 상속하거나 구현한 클래스를 매칭
|
aspectj | org.example..*Service+ |
AspectJ 표현식을 사용해 매칭
|
regex | org\.example\.Default.* |
클래스 이름에 대해 정규 표현식으로 매칭
|
custom | org.example.MyTypeFilter |
사용자 정의 필터를 적용해 매칭
|
예제
더보기
더보기
@Configuration
@ComponentScan(basePackages = "org.example",
includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
excludeFilters = @Filter(Repository.class))
public class AppConfig {
// ...
}
고려사항
자동 등록 빈
자동 등록 빈 | 담당 역할 |
AutowiredAnnotationBeanPostProcessor | @Autowired 의존성 주입 담당 |
CommonAnnotationBeanPostProcessor | @PostConstruct, @Resource 빈 등록 생명주기 후크 수행 |
- 비활성화하거나 커스터마이징하려면 annotation-config=false 속성 사용
예제
더보기
더보기
public class CustomAutowiredProcessor extends AutowiredAnnotationBeanPostProcessor {
@Override
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
// 커스텀 로직 추가
return super.determineRequiredStatus(ann);
}
}
모듈 경로
- 클래스패스 스캐닝 기능을 모듈 경로에서 사용할 때 module-info.java 파일에 클래스를 내보내는 설정을 해야 함
예제
더보기
더보기
module com.example.module {
// 모든 모듈에 공개
exports com.example.service;
// 특정 모듈에만 공개
exports com.example.repository to com.example.consumer;
// 리플렉션 허용
opens com.example.controller;
}
출처
'Spring > Spring' 카테고리의 다른 글
[Spring][Core] 3-4. Container: Environment Abstraction (0) | 2025.04.06 |
---|---|
[Spring][Core] 3-3. Container: Using JSR 330 Standard Annotations (0) | 2025.04.06 |
[Spring][Core] 3-1. Container: Annotation-based Configuration (0) | 2025.04.06 |
[Spring][Data Access] 5-1. ORM Data Access: Introduction to ORM with Spring (0) | 2024.08.11 |
[Spring][Data Access] 2. DAO Support (0) | 2024.08.11 |