1.4.1 빈 이름
XML 설정에서의 빈 식별자와 별칭
- 빈 아이디와 빈 이름은 특정 빈을 구분하기 위해 사용되는 빈 식별자
- 빈은 하나 또는 그 이상의 식별자를 가질 수 있으며, 빈의 정의된 애플리케이션 컨텍스트 내에서 고유해야 함
- 빈의 식별자는 XML이라면 <bean> 태그의 id와 name 두 가지 애트리뷰트를 이용해 정의
id
- id를 식별자로 지정하는 경우 ID 타입의 아래의 기준이 필요
- id에는 공백이 들어갈 수 없다.
- 첫 글자는 알파벳과 밑줄(_) 그리고 허용된 일부 언어문자만 사용될 수 있다.
- 나머지 글자는 알파벳과 밑줄, 그리고 숫자와 점(.)을 허용한다. 그 외의 특수문자는 사용할 수 없다.
<bean id="_hello.Service123" class="..." /> <bean id="사용자서비스" class="..." />
- 관례적으로 id에 사용하는 값은 빈을 대표하는 타입 이름을 첫글자만 소문자로 바꿔서 사용
UserService
타입의 빈을 id로 사용하는 예시<bean id="userService" class="..." />
- id는 생략도 가능, 빈 선언에 어떠한 식별자도 부여하지 않으면 스프링 컨테이너가 자동 부여
- id를 지정하지 않았더라도 빈의 타입을 이용해 DI가 가능
- AOP 자동 프록시 생성기처럼 컨테이너가 사용하는 설정정보영 빈의 경우에도 id 생략 가능
name
- ID 타입의 형식을 따라야하는 id와 달리 name에는 특별한 제약이 없음
- 한 번에 여러 개의 이름 지정이 가능. 하나 이상의 빈 이름을 부여할 때는 콤마, 세미클론을 이용
<bean name="1234,/hello;헬로우" class="..." />
- “1234”, “/hello”, “헬로우” 세가지 이름을 갖는 빈. 1234, /hello 는 프로퍼티 이름으로 사용할 수 없으므로
getBean()
을 이용해 검색할 떄만 사용 가능
- “1234”, “/hello”, “헬로우” 세가지 이름을 갖는 빈. 1234, /hello 는 프로퍼티 이름으로 사용할 수 없으므로
- 대규모 시스템에 경우 datasource를 여러개 사용하거나, 다르게 참조하는 경우가 발생
- 그런 경우 name을 통해 접근하며, id와 name으로 각각 접근이 가능
<bean id="dataSource" name="system1DS" class="..." />
- dataSource라는 id로도 접근이 가능하고, 다른 시스템은 system1DS 이름으로 참조 가능
- 이때 system1DS가 일종의 별칭(allias) 역할
- <bean>에 손을 대지 않고 싶다면 <allias> 태그를 사용해 특정 빈의 별칭 부여도 가능
<alias name="dataSource" alias="system1DS" />
애노테이션에서의 빈 이름
- 클래스에 @Component와 같은 스테레오타입의 애노테이션을 부여해주고 빈 스캐너에 의해 자동인식되도록 만들 경우 클래스 이름을 빈 이름으로 사용하는 방법을 선호
//userService가 빈 이름으로 지정 @Component public class UserService {
- @Configuration이 달린 클래스의 @Bean 메소드를 이용해 빈을 정의하는 경우 메소드 이름이 그대로 빈 이름으로 지정
//userDao라는 이름의 빈이 생성 @Configuration public class Config { @Bean public UserDao userDao() {
- 자동 빈 스캔 대상이라면 애노테이션의 디폴트 앨리먼트 값으로 이름 지정이 가능
@Component("myUserService") public class UserService {
- JSR-330의 @Named 애노테이션을 사용해서 이름 지정이 가능
@Component @Named("myUserService") public class UserService {
- 자바 코드를 이용한 빈 등록 방식에선 @Bean 애노테이션의 name 앨리먼트를 이용
@Configuration public class Config { @Bean(name="myUserDao") public UserDao userDao() {
// 여러개 등록 @Bean(name={"myUserDao", "userDao"}) public UserDao userDao() {
- @Named와 스테레오타입 애노테이션을 동시에 사용할 경우 한가지 이름만을 사용 (다르면 예외가 발생)
1.4.2 빈 생명주기 메소드
초기화 메소드
- 빈 오브젝트가 생성되고 DI 작업까지 마친 다음에 실행 되는 메소드를 의미
- 초기화 메소드를 지정하는 네가지 방법
- 초기화 콜백 인터페이스
- init-method 지정
- @PostConstruct
- @Bean(init-method)
초기화 콜백 인터페이스
- InitializingBean 인터페이스를 구현해서 빈을 작성하는 방법
- afterPropertiesSet()은 이름 그대로 프로퍼티 설정까지 마친 뒤에 호출
- 애플리케이션 빈 코드에 스프링 인터페이스를 노출하기 때문에 추천하지 않음
- 코드의 동작방식을 이해하기 쉽다는 장점
init-method 지정
- XML로 빈을 등록한다면
<bean>
태그에init-method
애트리뷰트를 넣어 초기화 작업을 수행할 메소드 이름 지정이 가능
- 예를 들면, 빈 설정이 DI 작업까지 마친 뒤
initResource()
가 실행되도록 선언<bean id="myBean" class="MyBean" init-method="initResource"/>
- 스프링 API가 노출되지 않고 깔끔하다는 장점
- 코드만 보고는 초기화 메소드가 호출될지 알 수 없기 때문에 코드를 이해하는데 불편하고 XML 설정에서 init-method를 빼먹을 위험이 발생
<beans>
태그 안에default-init-method
를 지정해서 일괄 지정할 수 있지만 권장하지 않음
@PostConstruct
- 초기화를 담당할 메소드에 @PostConstruct 애노테이션을 부여
- @PostConstruct는 자바의 표준 공통 애노테이션(JSR-250)이므로 스프링 콜백 인터페이스를 사용하는 것보다 상대적으로 부담이 적음
- 코드에 초기화 메소드가 존재하므로 XML의
init-mehtod
설정보다 직관적
- 가장 사용이 권장되는 방식
@Bean(init-method)
- @Bean 메소드를 이용해 빈을 정의하는 경우
init-method
엘리먼트를 사용해서 초기화를 지정@Bean(init-method="initResource") public void MyBean myBean() {
제거 메소드
- 제거 메소드는 컨테이너가 종료될 때 호출돼서 빈이 사용한 리소스를 반환하거나 종료 전에 처리해야할 작업 수행
제거 콜백 인터페이스
DisposableBean
인터페이스를 구현해서destory()
를 구현하는 방법
- 스프링 API에 종속되는 코드를 만드는 단점
destroy-method
- <bean> 태그에
destory-method
를 넣어서 제거 메소드를 지정
@PreDestroy
- 컨테이너가 종료될 때 실행될 메소드에 @PreDestory를 지정
@Bean(destroyMethod)
- @Bean 애노테이션의 destroyMethod 앨리먼트를 이용해서 제거 메소드를 지정
1.4.3 팩토리 빈과 팩토리 메소드
- 생성자 대신 오브젝트를 생성해주는 코드의 도움을 받아서 빈 오브젝트를 생성하는 것을 팩토리 빈이라고 부름
- 빈 팩토리와 비슷하지만 전혀 다른것이니 혼동에 주의
- 팩토리 빈 자신은 빈 오브젝트로 사용 안함
- 빈 오브젝트를 만들어주는 기능만을 제공
- 팩토리 기능을 가진 빈을 통쨰로 사용하는 방법도 있지만, 특정 빈이나 클래스의 팩토리 메소드를 사용해서 빈을 등록하는 방법도 존재
FactoryBean 인터페이스
- 가장 단순하고 자주 사용되는 방법
- 보통 팩토리 빈은 기술 서비스 빈이나 기반 서비스 빈을 활용할 때 주로 사용
- 스프링 인터페이스를 구현하는 것이 불편하지 않다면 사용하기 적당
- 예시) Vo1에서
FactoryBean
인터페이스를 구현해서 다이내믹 프록시를 생성하는getObject()
를 구현하고 빈으로 등록해서 사용
스태틱 팩토리 메소드
- 클래스의 스태틱 메소드를 호출해서 인스턴스를 생성하는 방식
- JDK를 비롯해서 다양한 기술 API에서 자주 사용
- 빈 오브젝트를 생성해야 한다면 <bean> 태그에 사용할 수 있는
factory-method
애트리뷰트를 이용하는 것이 편리
- 오브젝트 생성과 함께 초기화 작업이 필요한 경우라면 스태틱 팩토리 메소드를 이용
- 예시)
GlobalCounter
싱글톤 클래스의createInstance
를 호출해서 빈으로 등록해주는 설정<bean id="counter" class="GlobalCounter" factory-method="createInstace" />
인스턴스 팩토리 메소드
- 오브젝트의 인스턴스 메소드를 이용해 빈 오브젝트를 생성 가능
- FactoryBean 인터페이스를 구현한 팩토리 빈이 팩토리 빈 오브젝트의 메소드를 이용해 빈 오브젝트를 생성하는 대표적인 방법
- FactorytBean이라는 스프링의 인터페이스에 종속적이라는 것이 단점
- 임의의 오브젝트의 메소드를 호출해서 빈을 생성해야 한다면, factory-bean과 factory-method를 함께 사용 가능. 이때는 팩토리 기능을 제공할 빈을 따로 등록
- 예시) logFactory 빈의 createLog 메소드를 호출해서 log 빈을 생성하는 설정 (class 지정 X)
<bean id="logFactory" class="...LogFactory" /> <bean id="log" factory-bean="logFactory" factory-method="createLog" />
@Bean 메소드
- 자바 코드에 의한 빈 등록 방식에서 사용하는 @Bean 메소드도 일종의 팩토리 메소드
- 스프링 컨테이너가 @Bean 메소드를 실행해 빈 오브젝트를 가져오는 방식이기 떄문
- 빈의 설정과 DI를 대폭 적용한다면 @Configuration이 붙은 설정 전용 클래스 사용이 편리
- 특정 빈만 팩토리 메소드를 통해 만들고 싶다면 일반 빈 클래스의 @Bean 메소드를 추가
'개발서적 > 토비 스프링 3.1-Vol.2' 카테고리의 다른 글
[토비의 스프링 - Vol.2] 1장 - 1.5.2 컨테이너 인프라 빈을 위한 자바 코드 메타정보 (0) | 2022.01.17 |
---|---|
[토비의 스프링 - Vol.2] 1장 - 1.5 스프링 3.1의 IoC 컨테이너와 DI (0) | 2022.01.17 |
[토비의 스프링 - Vol.2] 1장 - 1.3 프로토타입과 스코프 (0) | 2022.01.17 |
[토비의 스프링 - Vol.2] 1장 - 1.2.5 컨테이너가 자동등록하는 빈 (0) | 2022.01.17 |
[토비의 스프링 - Vol.2] 1장 - 1.2.4 프로퍼티 값 설정 방법 (0) | 2022.01.17 |