Whiteship's Note


BeanFactory와 ApplicationContext 인터페이스

Spring/Chapter 3 : 2007. 3. 5. 12:59


사용자 삽입 이미지
IoC의 가장 상위에 있는 인터페이스인 BeanFactory에 있는 메소드들 입니다.

사용자 삽입 이미지
ApplicationContext 인터페이스에 있는 메소드 들인데 이 인터페이스는 아래의 인터페이스를 확장하고 있습니다.
ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver
01234
위 인터페이스들의 클래스 다이어그램을 그려보면 다음과 같이 됩니다.

사용자 삽입 이미지

BeanFactory를 구현한 클래스들(ApplicationContext를 구현한 클래스와 중복되는 클래스는 삭제했습니다.)
AbstractBeanFactory, DefaultListableBeanFactory, StaticListableBeanFactory, XmlBeanFactory,
ApplicationContext를 구현한 클래스들
AbstractApplicationContext, AbstractRefreshableApplicationContext, AbstractRefreshablePortletApplicationContext, AbstractRefreshableWebApplicationContext, AbstractXmlApplicationContext, ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, GenericApplicationContext, GenericWebApplicationContext, StaticApplicationContext, StaticPortletApplicationContext, StaticWebApplicationContext, XmlPortletApplicationContext, XmlWebApplicationContext
이 많은 IoC container들 중에 언제 어떤 걸 써야 할런지....;;;;

참조 : BeanFactory 이해

'Spring > Chapter 3' 카테고리의 다른 글

idref 엘리먼트  (0) 2007.03.08
Constructor Injection 할 때 인자 구분  (0) 2007.03.08
Setter Injection & Constructor Injection  (0) 2007.03.08
3.3. Dependencies  (0) 2007.03.08
Bean 생성하기  (0) 2007.03.07
복잡한 Alias  (0) 2007.03.07
Aliasing Beans  (0) 2007.03.07
id, name and BeanDefinitionName  (0) 2007.03.06
FileSystemResource vs ClassPathResource  (2) 2007.03.06
3.2. Basics - containers and beans  (0) 2007.03.05
BeanFactory와 ApplicationContext 인터페이스  (0) 2007.03.05
top

Write a comment.


Object getBean(String name) 메소드 구현 살펴보기-윗 부분

Spring/Mission : 2006. 10. 27. 19:27


Object getBean(String name) throwsBeansException 메소드는 name에 해당하는bean의 객체를 반환합니다. 이 메소드는BeanFactory Singleton 또는Prototype 패턴을 사용하는 것을 보여줍니다. name으로 bean의 별명을 넘겨 줘도 그에 상응하는 bean 객체를 받아 볼수 있으며 이 경우에도 역시 해당하는 name이 없다면 상위BeanFactory에서 찾게 됩니다. 이 메소드는 특히RuntimeException을 발생 시킬 수 있는데 BeanException bean 객체를 가져오지 못했을 때 발생하며 BeanException의하위 클래스인 NoSuchBeanDefinitionException은 해당하는 name bean을 찾지 못했을 때 발생합니다.

먼저 소스코드를 보겠습니다.

public Object getBean(String name) throws BeansException {
       return getBean(name, null, null);
   }


아.. 다른 메소드를 호출 하고 있습니다. 혹시 getBean(String name, Class requiredType) 메소드도 이러한 모습을 하고 있지 않을까 예상됩니다.

public Object getBean(String name, Class requiredType) throws BeansException {
       return getBean(name, requiredType, null);
   }


역시 같은 모습을 하고 있었습니다.

이번 글에서는 두 개의 메소드 구현을 한꺼번에 살펴볼 수 있게 됐습니다. :) 이거양득?

먼저 세개의 아규먼트들이 무엇에 사용되는지 주석을 보겠습니다.

/**
    * Return the bean with the given name,
    * checking the parent bean factory if not found.
    * @param name the name of the bean to retrieve
    * @param requiredType the required type of the bean to retrieve
    * @param args arguments to use if creating a prototype using explicit arguments to a
    * static factory method. It is invalid to use a non-null args value in any other case.
    */

name과 class는 알겠는데 args 라는 final Object[] 타입이 무엇인지 잘 모르겠네요. 정적 팩토리 메소드를 사용해서prototype을 생성할 때 사용할 아규먼트들이라고 합니다.

Object getBean(String name, Class requiredType, final Object[] args) 메소드 보기


헉.... 깁니다....

메소드를 가장 밖에 있는 if 문을 기준으로 삼등분 시키겠습니다.



세 부분으로 나누니까 그래도 조금 안심이 되네요. 하지만 여전히 중간 부분이 굉장히 크네요. 먼저 제일 윗 부분 부터 살펴보겠습니다.

이 부분은 getSingleton(String) 메소드를 호출한 결과 값이 null이 아닐 경우에 실행되는 부분입니다. 그리고 크게 두 부분으로 나뉘어 지는데 첫번째 부분은 메소드 이름으로 추정해 보건데 싱글톤 객체가 현재 생성 중일 때 또는 그렇지 않을 때 logging 메시지를 처리하는 부분이라고 생각됩니다.

다음 부분은 실질적으로 빈을 생성하는 부분인듯 합니다. 빈 이름에 해당하는 빈 정의가 존재할 때와 그렇치 않을 때 각각 getObjectForBeanInstance()를 통해 bean을 받아 오고 있습니다.

이전에도 몇 번 본적이 있는 transformedBeanName(String) 메소드입니다.

Object sharedInstance = getSingleton(beanName); 여기서 호출되는 getSingleton(String)메소드 입니다. 이 메소드는 DefaultSingletonBeanRegistry 클래스에 있습니다. DefaultSingletonBeanRegistry 클래스와 AbstractBeanFactory와의 관계는 바로 다른 글에서 언급이 되었습니다. 짧게 D가 A의 아버지 입니다.

logging 관련 부분은 나중에 살펴보도록 하고 getMergedBeanDefinition(String, boolean) 메소드를 보겠습니다.

마지막으로 getObjectForBeanInstance(Object, String,  RootBeanDifinition) 메소드를 살펴보겠습니다.

getObjectForBeanInstance 메소드는 좀 더 자세히 살펴 봐야겠습니다.

top

Write a comment.


BeanFactory와 AbstractBeanFactory의 관계

Spring/Mission : 2006. 10. 26. 15:57



AbstractBeanFactory는 총 네 개의 인터페이스 구현에 대한 책임이 있지만 abstract class인 관계로 몇몇 메소드는 abstract인 채로 하위 클래스에서 구현하도록 되있습니다.

그리고 네 개의 인터페이스 중에 하나 인 SingletonBeanRegistry 인터페이스는 DefaultSingletonBeanRegistry 클래스에서 구현을 했고 이 클래스를 상속 받고 있는 구조입니다.

UML에 차마 다 그리기가 힘들어서 ConfigurableBeanFactory의 메소드들과 AbstractBeanFactory의 필드와 메소드들을 비워놨습니다.

현재 BeanFactory 인터페이스, HierachicalBeanFactory 인터페이스, SingletonBeanRegistry 인터페이스 만 모두 표현해 둔 상태입니다.

mission1의 문제는 Xml을 읽어들여 BeanFactory가 작동하는 방식을 규명하는 것인데..

결국 XmlBeanFactoy까지 내려 가야 할텐데 지금은 AbstractBeanFactory에서 BeanFactory 인터페이스의 책임들을 어떻게 구현해 두었는지 살펴보고 있습니다.


ps : getBean 메소드 무지 길어요. 이거 리팩토링 해야되는거 아니에요? ^^


top

Write a comment.


String[] getAliases(String name) 메소드 구현 살펴보기

Spring/Mission : 2006. 10. 26. 12:37


BeanFactory 인터페이스에 있는 메소드들을 어떻게 구현했나 살펴보고 있습니다.


if (!fullBeanName.equals(name)) {
           aliases.add(fullBeanName);
       }
저는 이부분이 이해가 잘 안가네요.

name은 매개변수로 받아온 이름이고 만약에 그 name이 &로 시작을 하면 fullBeanName은 transformedBeanName(String) 메소드 호출하여 반환 된 값을 참조하는 beanName에 &를 붙인 값이 됩니다.

그런데 transformedBeanName(String) 메소드는 아래에 보시다시피 &로 시작하는 name이 오면 맨 앞에 &를 제외한 상태로 문자열을 반환하게 됩니다.

transformedBeanName(String) 메소드


그렇게 때문에 if (!fullBeanName.equals(name)) 여기서 어떻게 name하고 fullName하고 달라질 수가 있는지.. 모르겠네요.

이 메소드에서 호출되는 다른 메소드 들도 containsBean(String) 메소드에서 확인바 있습니다.


ps : 이 메소드에서도 역시 제가 아직 풀지 못한 수수께끼.. FACTORY_BEAN_PREFIX  이 변수와 관련해서 name으로 받아온 String의 제일 앞 글자가 &로 시작하면 무슨일이 벌어지는 걸까요...


top

Write a comment.


boolean containsBean(String name) 메소드 구현 살펴보기.

Spring/Mission : 2006. 10. 26. 11:52


BeanFactory 인터페이스에 있는 메소드의 구현을 살펴보겠습니다.

String[] getAliases(String name) 메소드는 name으로 참조 되는 bean의 다른 이름들 즉 별명들을 String 배열로 반환하는 메소드 입니다. name으로 넘겨진 값이별명 중에 하나였다면 그에 상응하는 bean의 원래 name과별명들을 같이 반환합니다. 이때 원래 name은 배열의 제일처음에 위치합니다. 이 메소드 또한 현재 BeanFactory에서해당하는 bean을 찾지 못한다면 부모 BeanFactory에서찾게 됩니다.

Best 시나리오 일때는 자기 자신의 favtory안에서 String type의 매개변수에 해당하는 bean을 찾을 겨우 입니다. 이때는 다음과 같은 메소드 호출 Stack으로 파악할 수 있습니다.


AbstractBeanFactory에 구현된 boolean containsBean(String)


containsLocalBean(String) 메소드


containsSingleton(String) 메소드 와 containsBeanDefinition(String) 메소드


자기 자시의 BeanFactory에서 찾지 못할 때는 부모 BeanFactory에서 찾게 됩니다. 아래는 그림은 containsBean 메소드의 구조를 도식화 한것입니다.


containsBean 메소드에 넘어온 매개변수를 originalBeanName 메소드의 인자로 전해주고(파란선) 그 결과 값을 다시 parentBeanFacory.containsBean(String) 메소드의 인자로 넘겨줍니다.(빨간선)
parentBeanFactory.containsBean(String) 이부분을 Stack 구조로 나타내면 다음과 같습니다.


getParentBeanFactory() 메소드


originalBeanName(String) 메소드


AbstractBeanFactory transformedBeanName(String) 메소드와BeanFactoryUtils에 있는 transformedBeanName(String) 메소드




ps : BeanFactory 인터페이스를 구현한 AstractBeanFactory에 있는 method들을 살펴보았습니다.
앞서 궁금해 했던 BeanFactory.FACTORY_BEAN_PREFIX 이 필드를 사용하는 것을 볼 수 있는데요. &를 생성하고자 하는 Bean name앞에 붙여서 getBean을 하게 되면 어떻게 되는건지 해봐야겠네요.

ps : 오타가 많은 듯 한데 찾기가 쉽지 않군요. ㅎㅎ;;;

top

  1. Favicon of https://springframework.tistory.com BlogIcon 영회 2006.10.26 00:44 신고 PERM. MOD/DEL REPLY

    조금 간결해졌으면 좋겠고.. ^^
    어떤 흐름으로 메소드가 호출되는지 볼 수 있으면 더 좋겠구나.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2006.10.26 08:38 신고 PERM MOD/DEL

    네~ Simple.. and Visual

Write a comment.


BeanFactory 인터페이스 살펴보기

Spring/Mission : 2006. 10. 25. 14:03


먼저 org.springframework.beans.factory.BeanFactory가 책임지는 것은 무엇들이 있는지 살펴 보겠습니다.

BeanFactoryAPI를 살펴보겠습니다. 일반적으로BeanFactory XML 같은configuration data 안에 저장된 Bean에 대한 정의들을 읽어 들이고, org.springframwork.beans 패키지를 사용하여 Bean을설정합니다.

BeanFactory 인터페이스가 가지고 있는 필드 입니다.

Field Summary

static String

FACTORY_BEAN_PREFIX
         Used to dereference a FactoryBean and distinguish it from beans created by the FactoryBean.


BeanFactory 인터페이스 안에 들어있는 메소드들은 다음과 같습니다.

Method Summary

boolean

containsBean(String name)
         Does this bean factory contain a bean definition with the given name?

String[]

getAliases(String name)
         Return the aliases for the given bean name, if defined.

Object

getBean(String name)
         Return an instance, which may be shared or independent, of the given bean name.

Object

getBean(String name, Class requiredType)
         Return an instance (possibly shared or independent) of the given bean name.

Class

getType(String name)
         Determine the type of the bean with the given name.

boolean

isSingleton(String name)
         Is this bean a singleton?


메소드들은 대강 어떤 일을 책임을 지고 있는지 알겠는데 맨 위에 있는 필드 하나가 잘 모르겠네요.

org.springframework.beans.factory.BeanFactory
public static final StringFACTORY_BEAN_PREFIX"&"

Used to dereference a FactoryBean and distinguish it from beans created by the FactoryBean. For example, if the bean named myEjb is a FactoryBean, getting &myEjb will return the factory, not the instance returned by the factory.

dereference라는 단어는 처음보네요 ^^;; reference는 수도없이 봐왔는데. FactoryBean과 FactoryBean에 의해 생성된 bean을 구분하기 위해 사용한다고 하는군요. 예를 든 것을 보면 빈 이름이 myEjb이면 FactoryBean이고 &myEjb는 factory에 의해 반환되는 객체가 아니라 factory를 반환한다.

지쟈스... 무슨 말인지... Someboby PLZ HELP~
top

Write a comment.


Spring ApplicationContexts



Spring ApplicationContexts

Spring 에플리케이션의 심장과 정신에 해당하는 ApplicationContext 안에서 실제 DI를 수행합니다.

ApplicationContext는 BeanFactory를 특화시킨 것입니다.(ApplcationContext가 BeanFacotory를 상속받았죠.) BeanFactory는 Spring에서 사용되는 객체들의 레지스트리입니다. BeanFactory는 bean의 생성과 그들 간의 종속성 주입, 그리고 bean lookup(찾아 주기)를 담당합니다.

ApplicationContext는 이러한 BeanFactory의 기능에 부가적인 기능을 추가시킨 것입니다. 보통 BeanFactory대신에  이것을 사용한답니다. 웹 에플리케이션의 경우 웹에 특화된 WebApplicationContext를 사용합니다. ApplicationContext는 BeanFactoryPostProcessors를 가지고 초기화를 거친 후에 BeanFactory를 자동으로 처리할 수 있다고 합니다.(뭐가 어떻게 돌아간다는 건지는 잘 모르겠네요--;) 이밖에도 메시지를 internationalication(국제화)하는 기능, loosely coupled(약하게 결합된) 생산자와 소비자를 위한 event-routing mechanism, ApplicationContextAware같은 생명주기 인터페이스를 지원합니다.

ApplicationContext는 주로 XML 파일을 사용하여 bean들을 설정합니다. 매우 간단한 applicationContext.xml파일을 보겠습니다.



위 설정 파일에서 두 개의 bean을 등록한 것을 볼 수 있습니다. 이 bean들을 생성하고 관리하는 것이 ApplicationContext가 할일 입니다. 저 위의 <property> 속성을 보시면 Dependency Injection을 정의해 둔 것을 볼 수 있습니다. cashRegister bean에서 priceMatrix 레퍼런스가 priceMatrixBean을 사용하도록 정의한 것입니다.

위 설정 파일 없이도 그러한 것은 다음 순수 java code로도 가능합니다.

The Return of the POJO


이전 글과 이번 글에 걸쳐 DI와 ApplicationContext에 대해 배웠습니다. 이 두 개념은 Spring의 핵심 개념입니다. 이 것들을 에플리케이션(심지어 웹 에플리케이션 마저)을 Plain Old Java Object(POJO)로 개발 하기 위한 도구 입니다. 이것이 가능하기 때문에 강력한 Object Oriented 개념을 웹 에플리케이션 개발에 사용할 수 있습니다. 프레임웤에 특화된 코드를 작성하기 보다 비즈니스 로직에만 집중하여 개발하기 때문입니다. 이 책에서는 앞으로 도메인 객체를 먼저 작성하고 그런 다음 프레임웤을 사용하여 그것들을 웹 에플리케이션으로 향상시도록 할 것입니다.

여기까지 1장을 모두 요약하자면
  • Dependency Injection은 Inversion Of Control의 한 종류이다. 이것은 코드에 종속성을 주입하는 원리이다. 이것을 사용하면 객체 생성 또는 그것을 위치시키는 일을 프레임웍에게 전가 시키기 때문에 코드 자체의 테스트가 용이해진다.
  • ApplicationContext는 Spring의 주요 객체 레지스트리와 통합 포인트다. 주로 XML파일을 통해서 bean과 그들의 종속성을 설정한다. 많은 기능이 있지만 그 중에 객체 생성과 DI가 핵심 기능이다.
  • 마지막으로 POJO 스타일로 개발이 가능하다는 것이다. 따라서 객체 지향 개발 기술의 사용이 가능하며 POJO로 개발 된 시스템은 테스트가 용이하고 유연하다. 또한 개발자들이 프레임웤을 어떻게 다루는지 보다는 문제 영역과 비즈니스 로직에 집중하여 개발이 가능해진다.

'Spring MVC > 2장 Spring 기본요소' 카테고리의 다른 글

Spring ApplicationContexts  (0) 2006.10.06
Inversion of Control  (4) 2006.10.06
top

Write a comment.