'스프링'에 해당되는 글 12건

  1. 2007.12.19 불가능은 없다. FactoryBean
  2. 2007.12.17 LifeCycle 확장
  3. 2007.12.17 LifeCycle
  4. 2007.12.14 <aop:scoped-proxy /> 작동 방식 (5)
  5. 2007.12.10 Autowiring

FactoryBean에게 불가능이란 없습니다.
기존의 XML문서에 정의된 bean들은 생성자 삽입과 setter 삽입에 의해 생성 되었습니다.
하지만 이러한 조건으로 모든 bean을 생성하기엔 불가능한 상황도 있습니다. 예를들어 private 생성자를 가지고 있거나 setter가 없거나... 이런 경우는 어떻게 생성을 할 수가 없습니다. 더불어 복잡한 로직에 의한 객체생성 또한 제한적입니다. 하지만 FactoryBean은 다릅니다. 기존의 XML설정으로
불가능 했던 복잡한 로직들을 이용해 자체적인 Factory 기능으로 bean을 생성 합니다.

구현해야 할 메소드는 다음과 같습니다.

public Object getObject()        : 이 factory가 생성 하는 객체를 반환 합니다.
public Class getObjectType()  : getObject()로 생성되는 객체의 타입을 반환 합니다. 만약 타입을 알 수                                              없을 경우 null을 반환 합니다.
public boolean isSingleton()   : getObject()로 생성되는 객체의 관리방식을 반환 합니다.

Spring에서는 다른 프레임워크와의 쉬운 통합을 위해 수많은 FactoryBean 구현체들이 존재 합니다.
그중의 하나인 SqlMapClientFactoryBean은 iBatis의 다소 복잡한 sqlMapClient 생성 로직이 포함되어 간단한 xml 설정만으로 sqlMapClient를 쉽게 생성해 줍니다.

간단한 예제를 보겠습니다.
FactoryBean을 구현한 클래스 와 XML 설정 입니다.


출력결과
FooFactory 생성
Foo 생성
jjaeko.Foo@4a9387
jjaeko.FooFactory@1b86c7

타입이 FooFactory지만 실제로 내부에서 생성된 Foo 인스턴스를 리턴 합니다. 만약 FactoryBean 자체의 인스턴스를 얻고 싶다면 위 예제에서 알 수 있듯이 빈이름 앞에 "&"를 붙이면 됩니다.

신고

'Spring > Core' 카테고리의 다른 글

ApplicationContext의 초기화 과정  (2) 2007.12.20
MessageSource 사용하기(다국어 지원)  (0) 2007.12.19
불가능은 없다. FactoryBean  (0) 2007.12.19
LifeCycle 확장  (0) 2007.12.17
LifeCycle  (0) 2007.12.17
<aop:scoped-proxy /> 작동 방식  (5) 2007.12.14
Posted by 째코

LifeCycle 확장

Spring/Core 2007.12.17 20:48

BeanPostProcessor(후처리기)를 구현한 bean은 다른 bean보다 먼저 생성이 되며 후처리기로 등록이 됩니다. 그 이후 일반적인 bean들이 생성 될 때 이 후처리기를 거치게 됩니다.
Spring에 기본적으로 등록된 BeanPostProcessor's 도 상당히 많습니다.
대표적으로 ApplicationContextAwareProcessor가 있습니다. 이 후처리기의 이름이 전혀 낯설지가
않은 이유는 앞서 소개 했던 ApplicationContext 컨테이너에서 작동되는 LifeCycle 인터페이스
(ResourceLoaderAware,ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware) 의 메소드를 호출하는 후처리기이기 때문 입니다.

LifeCycle을 확장할 수 있는 또 하나의 인터페이스인 BeanFactoryPostProcessorBeanPostProcessor 보다 먼저 생성이 되며 생성 직후 postProcessBeanFactory 메소드가 호출 됩니다. 이 것은 컨테이너가 시작 될때 아직 생성 되지 않은 일반적인 bean 설정정보에 대한 조작을 가능케 합니다. 대표적으로 흔히 사용되는 PropertyPlaceholerConfigurer 가 있습니다.

2개 이상의 후처리기를 사용 할 경우 여러가지 요인에 의해 어떤 후처리기가 먼저 등록될지
예측 하기란 어렵습니다. 정확한 순서를 결정하기 위해서 Ordered인터페이스를 구현하면
됩니다.

간단한 예제 입니다.

CustomFactoryPostProcessor 클래스

CustomPostProcessor 클래스

설정파일

출력결과
CustomFactoryPostProsessor 생성
BeanFactoryPostProcessor - postProcessBeanFactory 호출
CustomPostProcessor 생성
Foo 생성
BeanPostProcessor - postProcessBeforeInitialization 호출
BeanPostProcessor - postProcessAfterInitialization 호출
Foo 생성
BeanPostProcessor - postProcessBeforeInitialization 호출
BeanPostProcessor - postProcessAfterInitialization 호출

앞서 설명 했던 것처컨테이너가 시작 될 때 CustomFactoryPostProsessor가
생성이 되고 바로
postProcessBeanFactory메소드가 호출 됩니다. 그 후 CustomPostProcessor 가 생성되며 이후에 생성 되는 일반적인  bean들은 CustomPostProcessor 를 거치게 됩니다.
신고

'Spring > Core' 카테고리의 다른 글

MessageSource 사용하기(다국어 지원)  (0) 2007.12.19
불가능은 없다. FactoryBean  (0) 2007.12.19
LifeCycle 확장  (0) 2007.12.17
LifeCycle  (0) 2007.12.17
<aop:scoped-proxy /> 작동 방식  (5) 2007.12.14
Bean scopes  (0) 2007.12.14
Posted by 째코

LifeCycle

Spring/Core 2007.12.17 19:24

bean이 생성 될때 다음의 초기화 작업들이 수행 됩니다.
1. BeanNameAware's - setBeanName
2. BeanClassLoaderAware's - setBeanClassLoader
3. BeanFactoryAware's - setBeanFactory
4. ResourceLoaderAware's - setResourceLoader (ApplicationContext 일 경우)
5. ApplicationEventPublisherAware's - setApplicationEventPublisher
(ApplicationContext 일 경우)
6. MessageSourceAware's - setMessageSource
(ApplicationContext 일 경우)
7. ApplicationContextAware's - setApplicationContext (ApplicationContext 일 경우)
8. ServletContextAware's - setServletContext (WebApplicationContext 일 경우)
9. BeanPostProcessors - postProcessBeforeInitialization
10. InitializingBean's afterPropertiesSet
11. XML에 정의된 init-method
12.
BeanPostProcessors - postProcessAfterInitialization

아래는 컨테이너가 종료될때 수행되는 작업입니다.
1. DisposableBean's - destroy
2. XML에 정의된 destroy-method

1~12번 까지의 인터페이스들 중 BeanPostProcessors는 Spring의 후처리기로써 다른 인터페이스들 보다 좀 더 특별한 기능을 합니다. BeanPostProcessors는 따로 알아보도록 하고 나머지 인터페이스들을 모두 구현하여 테스트 해보겠습니다.
(WebApplicationContext가 아니기 때문에
ServletContextAware는 제외 했습니다.)

설정 파일

테스트 파일

출력결과
BeanNameAware - setBeanName 호출
BeanClassLoaderAware - setBeanClassLoader 호출
BeanFactoryAware - setBeanFactory 호출
ResourceLoaderAware - setResourceLoader 호출
ApplicationEventPublisherAware - setApplicationEventPublisher 호출
MessageSourceAware - setMessageSource 호출
ApplicationContextAware - setApplicationContext 호출
InitializingBean - afterPropertiesSet 호출
Custom init-method 호출

신고

'Spring > Core' 카테고리의 다른 글

불가능은 없다. FactoryBean  (0) 2007.12.19
LifeCycle 확장  (0) 2007.12.17
LifeCycle  (0) 2007.12.17
<aop:scoped-proxy /> 작동 방식  (5) 2007.12.14
Bean scopes  (0) 2007.12.14
메소드 삽입  (0) 2007.12.14
Posted by 째코
<aop:scoped-proxy /> 요소는 이전 글(링크) 에서 소개했는데
이번엔 좀 더 자세히 작동 방식에 대해 정리해 보겠습니다.
아래 설정을 보시면 bar가 참조하는 foo의 scope는 session 입니다.

이 설정을 기반으로 한 WebApplicationContext 컨테이너는 foo를 생성할 때
<aop:scoped-proxy /> 요소가 있으므로 foo에 대한 Proxy 객체를 생성 합니다.
Foo(Proxy)객체에 적용된 intercept는 다음과 같습니다.(CGLIB 사용 할 경우)
Cglib2AopProxy$DynamicAdvisedInterceptor
Cglib2AopProxy$DynamicUnadvisedInterceptor
Cglib2AopProxy$SerializableNoOp
Cglib2AopProxy$SerializableNoOp
Cglib2AopProxy$AdvisedDispatcher
Cglib2AopProxy$EqualsInterceptor
Cglib2AopProxy$HashCodeInterceptor

여기서 중요한 것은
DynamicUnadvisedInterceptor 입니다.
DynamicUnadvisedInterceptor 가 적용 되는 메소드는 Object 클래스의 toString(), clone(), finalize() 메소드와 사용자정의 public 메소드(non-static) 입니다.

DynamicUnadvisedInterceptor의 intercept 구현 내용은 크게 2단계로 나뉩니다.
첫번째로 getTarget() 호출 두번째로 원본 메소드 호출이 되겠습니다.
getTarget() 메소드는 최종적으로 AbstractBeanFactory 의 getBean() 메소드를 호출 합니다. 따라서 해당 bean에 정의된 scope가 현재scope(session, request) 에 의해 새로운 객체를 생성하거나 기존의 객체를 돌려 줍니다. 그리고는 돌려 받은 target객체를 통해서 원래 메소드를 호출 합니다.

<lookup-method />는 자신이 직접 Proxy 객체가 되는 반면
<aop:scoped-proxy />는 Proxy 객체를 만들어 주입하는 차이가 있군요
신고

'Spring > Core' 카테고리의 다른 글

LifeCycle 확장  (0) 2007.12.17
LifeCycle  (0) 2007.12.17
<aop:scoped-proxy /> 작동 방식  (5) 2007.12.14
Bean scopes  (0) 2007.12.14
메소드 삽입  (0) 2007.12.14
Autowiring  (0) 2007.12.10
Posted by 째코

Autowiring

Spring/Core 2007.12.10 22:53
지금까지는 의존성 있는 bean들을 묶기 위해(DI) <property /> 나 <constructor-arg /> 요소를 사용해 왔습니다. 하지만 보다 간단한 방법이 있으니 그것은 바로 <bean /> 요소의 autowire 속성 입니다.
autowire 속성은 다음과 같은 5가지의 값을 설정 할 수 있습니다.
no default 값이며 Autowiring이 전혀 없습니다.
byName 이 값을 사용하는 bean이 foo 라는 프로퍼티가 존재 한다면 bean의 id가 foo인것을 찾아 Autowiring 합니다.
발견 되지 않는다면 Autowiring은 무시 됩니다.
byType 이 값을 사용하는 bean이 Foo 라는 타입의 프로퍼티가 존재 한다면 bean의 타입이 Foo인 것을 찾아 Autowiring 합니다.
만약 2개 이상 발견 된다면 예외를 던지며 하나도 발견 되지 않는다면 Autowiring은 무시 됩니다. 하나도 발견 되지 않을 경우 예외가 던져지길 원한다면 dependency-check="objects" 속성을 사용 합니다.
constructor byType과 비슷하지만 생성자의 인자에 적용 됩니다. byTyp과 마찬가지로 같은 타입의 bean이 2개 이상 발견되면 예외를 던집니다.
autodetect constructorbyType으로 적용 되는데 만약 디폴트 생성자가 발견된다면 byType 으로 적용 됩니다.

Autowiring 의 장점
- XML 설정량 감소 됩니다.
- bean이 변경될 때 XML을 다시 설정할 필요가 없습니다.

Autowiring 의 단점
- 명시적이지 않아서 모호한 감이 있습니다.
신고

'Spring > Core' 카테고리의 다른 글

Bean scopes  (0) 2007.12.14
메소드 삽입  (0) 2007.12.14
Autowiring  (0) 2007.12.10
lazy-init 속성  (0) 2007.12.10
간략화 된 설정  (0) 2007.12.10
null 값 다루기  (0) 2007.12.09
Posted by 째코