Whiteship's Note


BeanPostProcessor 사용 예

Spring/Chapter 3 : 2007.03.13 15:35


BeanPostProcessor 인터페이스는 다음과 같습니다.
사용자 삽입 이미지
이 인터페이스를 구현한 클래스들 입니다. 유용하니까 만들어 뒀을 텐데 언제 어떤걸 사용하면 좋을지는 나~~~중에 알아봐야겠네요.
AbstractAdvisorAutoProxyCreator, AbstractAutoProxyCreator, ActionServletAwareProcessor, AdvisorAdapterRegistrationManager, AnnotationAwareAspectJAutoProxyCreator, ApplicationContextAwareProcessor, AspectJAwareAdvisorAutoProxyCreator, BeanNameAutoProxyCreator, DefaultAdvisorAutoProxyCreator, InstantiationAwareBeanPostProcessorAdapter, PersistenceAnnotationBeanPostProcessor, PersistenceExceptionTranslationPostProcessor, PortletContextAwareProcessor, RequiredAnnotationBeanPostProcessor, ScriptFactoryPostProcessor, ServletContextAwareProcessor, SimplePortletPostProcessor, SimpleServletPostProcessor
SIA(Spring In Action) 74쪽 부터 몇 장에 걸쳐 postProcessAfterInitialization 메소드를 사용하는 예제가 나와있습니다.

Reference에서는 이 인터페이스를 사용하는 예제라기 보다는 BeanFactory와 Applcation Context에 등록하는 방법을 주로 다루고 있습니다.

Member 객체의 id 속성 값이 "혜인이"이라면 "이쁘니"로 값을 바꾸는 예제를 만들어 보겠습니다.
    @Test public void beanPostProcessing(){
        Member keesun15 = getMember("keesun15");
        assertTrue(keesun15.getId().equals("이쁘니"));
    }

설정 내역은 다음과 같습니다.
    <bean id="keesun15" class="beanConfiguration.Member" >
        <property name="id" value="혜인이">
    </bean>
테스트는 실패합니다. keesun15 bean의 id 속성 값이 "혜인이"이기 때문입니다.

KeesunPostProcessor 를 구현합니다.
그리고 설정 파일에 bean으로 등록 해주면 테스트가 통과 합니다.[각주:1]

<bean class="beanConfiguration.KeesunPostProcessor" />

현재 사용중인 container가 ApplicationContext 종류이기 때문에 간단하게 bean으로 등록 해두기만 하면 container가 알아서 BeanPostProcessor를 읽어서 적용시켜 줍니다.

BeanFactory를 사용할 경우에는 Reference에 나온대로 addBeanPostProcessor를 소스 코드에서 등록해 줘야 합니다.
ConfigurableBeanFactory factory = new XmlBeanFactory(...);
           
    // now register any needed BeanPostProcessor instances
    MyBeanPostProcessor postProcessor = new MyBeanPostProcessor();
    factory.addBeanPostProcessor(postProcessor);

    // now start using the factory


  1. 이 객체를 받아와서 사용할 일은 없어 보이니까..id나 name을 굳이 적어줄 필요가 없겠네요. [본문으로]

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

MessageSource 사용 예  (0) 2007.03.15
MessageSource 인터페이스  (2) 2007.03.15
3.8. The ApplicationContext  (0) 2007.03.14
'만들 수 없는 것'을 FactoryBean으로 만들기  (2) 2007.03.14
BeanFactoryPostProcessor 사용 예  (0) 2007.03.13
BeanPostProcessor 사용 예  (0) 2007.03.13
3.7. Container extension points  (0) 2007.03.13
3.6. Bean definition inheritance  (0) 2007.03.12
ObjectFactoryCreatingFactoryBean 사용 예  (0) 2007.03.12
BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
top

Write a comment.


3.7. Container extension points

Spring/Chapter 3 : 2007.03.13 14:39


3.7.1. Customizing beans using BeanPostProcessors

Bean의 LifeCycle을 보면 initailization을 하기 전 과 후에 어떤 작업을 추가할 수 있는 인터페이스로 보입니다.

사용자 삽입 이미지

BeanPostProcessor 사용 예

3.7.2. Customizing configuration metadata with BeanFactoryPostProcessors

BeanPostProcessor와 비슷하지만 적용되는 대상이 Configuration Metadata 입니다. bean을 만들고 DI하기 전에 설정 내용을 변경할 수 있습니다.

BeanFactoryPostProcessor 사용 예

3.7.3. Customizing instantiation logic using FactoryBeans

FactoryBean 인터페이스를 구현해서 직접 factory를 만들어서 container에 끼워넣을 수 있습니다.

getBean()의 인자로 &를 붙여 주면 해당 bean 객체를 생성하는 FactoryBean을 얻을 수 있습니다.

ObjectFactoryCreatingFactoryBean 사용 예
'만들 수 없는 것'을 FactoryBean으로 만들기 (2)

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

MessageSource 인터페이스  (2) 2007.03.15
3.8. The ApplicationContext  (0) 2007.03.14
'만들 수 없는 것'을 FactoryBean으로 만들기  (2) 2007.03.14
BeanFactoryPostProcessor 사용 예  (0) 2007.03.13
BeanPostProcessor 사용 예  (0) 2007.03.13
3.7. Container extension points  (0) 2007.03.13
3.6. Bean definition inheritance  (0) 2007.03.12
ObjectFactoryCreatingFactoryBean 사용 예  (0) 2007.03.12
BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
top

Write a comment.


3.6. Bean definition inheritance

Spring/Chapter 3 : 2007.03.12 16:05


bean 설정 내용 사이에 상속 관계를 정의할 수 있습니다.

1. 부모쪽 bean 설정 파일에는 아무것도 설정하지 않아도 괜찮지만 만약 class 속성에 아무것도 지정하지 않을 경우에는 abstract="ture"를 추가해야 합니다.

2. 자식쪽 bean 설정에서는 상속할 bean을 parent 속성에 적어 주면 됩니다.

abstract="true"를 설정한 bean의 객체는 만들 수 없습니다. 테스트는 다음과 같이 작성했습닏.
@Test public void beanDefinitionInheritance(){
        try{
            Member keesun13 = getMember("keesun13");
            fail("keesun13 cannot be instantiation");
        }catch (Exception e) {
        }
        Member keesun14 = getMember("keesun14");
        assertTrue(keesun14.getId().equals("기선이다"));
        assertTrue(keesun14.getPassword().equals("password"));
        assertTrue(keesun14.getAge() == 26);
    }

설정 파일은 다음과 같습니다.
    <bean id="keesun13" abstract="true">
        <property name="id" value="기선" />
        <property name="password" value="password" />
    </bean>

    <bean id="keesun14" class="beanConfiguration.Member" parent="keesun13">
        <property name="id" value="기선이다" />
        <property name="age" value="26" />
    </bean>
테스트가 통과 합니다.
top

Write a comment.


ObjectFactoryCreatingFactoryBean 사용 예

Spring/Chapter 3 : 2007.03.12 11:44


앞의 예를 Reference 3.5.2.1 에서 사용한 ObjectFactoryCreatingFactoryBean를 사용하도록 수정하겠습니다.

1. Member에서 BeanFactoryAware 인터페이스를 구현하는 내용을 제거 합니다.
2. ticketFactory의 type을 ObjrctFactory로 바꿉니다.
3. getTicket메소드의 구현을 바꿉니다.
4. 설정 파일에서는 대신 많은 일을 해줘야 겠습니다.(Member에 factory연결하고 factory에서는 어떤 객체 넘겨 줄지 설정이 필요할 것 같네요.)
public class Member {
...
    private ObjectFactory ticketFactory;
...
    public void setTicketFactory(ObjectFactory ticketFactory) {
        this.ticketFactory = ticketFactory;
    }
...
    public Ticket getTicket() {
        return (Ticket)ticketFactory.getObject();
    }
}

구현 부분은 저번이랑 비슷하지만 자세히 보면 좀 다릅니다. 이제 설정 부분을 바꿔 줍니다.
    <bean id="keesun12" class="beanConfiguration.Member">
        <property name="ticketFactory">
            <bean
class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
                <property name="targetBeanName">
                    <idref local="ticket" />
                </property>
            </bean>
        </property>
    </bean>

    <bean id="ticket" class="beanConfiguration.Ticket" scope="prototype" />

설정 부분은 저번보다 훨씬 복잡해 진것 같지만...하늘색 부분을 빼곤 템플릿 처럼 사용되는 부분입니다.

이렇게 하면 저번 테스트 였던 아래 코드가 녹색으로 통과 하는 것을 확인할 수 있습니다.
    @Test public void singlePrototype(){
        Member keesun12 = getMember("keesun12");
        Ticket ticket1 = keesun12.getTicket();
        Ticket ticket2 = keesun12.getTicket();
        assertNotSame(ticket1, ticket2);
    }



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

'만들 수 없는 것'을 FactoryBean으로 만들기  (2) 2007.03.14
BeanFactoryPostProcessor 사용 예  (0) 2007.03.13
BeanPostProcessor 사용 예  (0) 2007.03.13
3.7. Container extension points  (0) 2007.03.13
3.6. Bean definition inheritance  (0) 2007.03.12
ObjectFactoryCreatingFactoryBean 사용 예  (0) 2007.03.12
BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
top

Write a comment.


BeanFactoryAware 사용 예

Spring/Chapter 3 : 2007.03.12 11:21


Member 가 영화표를 구매 하려고 합니다. 매번 구매하는 영화표는 다른 객체여야 겠죠? Ticket은 prototype으로 하고 Member는 singleton으로 하겠습니다.

티켓 두 개는 달라야 합니다.
   @Test public void singlePrototype(){
       ...
       assertNotSame(ticket1, ticket2);
   }

티켓 두 개는 하나의 멤버가 산거죠.
   @Test public void singlePrototype(){
       ...
       Ticket ticket1 = Member.getTicket();
       Ticket ticket2 = Member.getTicket();
       assertNotSame(ticket1, ticket2);
   }

멤버는 keesun12라는 bean이라고 하면 다음과 같이 테스트 케이스가 만들어집니다.
   @Test public void singlePrototype(){
       Member keesun12 = getMember("keesun12");
       Ticket ticket1 = keesun12.getTicket();
       Ticket ticket2 = keesun12.getTicket();
       assertNotSame(ticket1, ticket2);
   }

그리고 구현을 아래 처럼 합니다.
class Member {
...
    Ticket ticket;
...
    public Ticket getTicket() {
        return ticket;
    }

    public void setTicket(Ticket ticket) {
        this.ticket = ticket;
    }
}

그리고 설정은 아래 처럼 Member는 singleton으로.. TIcket은 prototype으로 했습니다.
    <!-- BeanFactoryAware -->
    <bean id="keesun12" class="beanConfiguration.Member">
        <property name="ticket" ref="ticket1" />
    </bean>

    <bean id="ticket1" class="beanConfiguration.Ticket" scope="prototype"/>

테스트는 당연히 통과 하지 않습니다. 두개의 티켓 객체가 같기 때문이죠. 이걸 해결하려고 다음과 같이 구현한 부분을 수정합니다.
1. ticket 필드를 삭제합니다. setTicket 메소드도 삭제합니다. getTicket은 남겨둬야겠죠.
2. Member 클래스가 BeanFactoryAware 인터페이스를 구현합니다.
3. BeanFactory 타입의 변수 추가합니다.
그럼 다음 처럼 됩니다.
class Member implements BeanFactoryAware {
...
    BeanFactory ticketFactory;
...
    Ticket getTicket(){
       return (Ticket)ticketFactory.getBean("ticket");
    }
...
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}

설정부분에서 더이상 ticket을 DI를 이용하지 않으므로 더 단순해 졌네요.
    <bean id="keesun12" class="beanConfiguration.Member" />

    <bean id="ticket" class="beanConfiguration.Ticket" scope="prototype" />

이제 테스트는 통과 합니다.

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

BeanFactoryPostProcessor 사용 예  (0) 2007.03.13
BeanPostProcessor 사용 예  (0) 2007.03.13
3.7. Container extension points  (0) 2007.03.13
3.6. Bean definition inheritance  (0) 2007.03.12
ObjectFactoryCreatingFactoryBean 사용 예  (0) 2007.03.12
BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
top

  1. 마을5 2011.11.07 13:49 PERM. MOD/DEL REPLY

    <aop:scoped-proxy />를 사용해 보세요.

Write a comment.


BeanFactoryAware

Spring/Chapter 3 : 2007.03.12 10:51


어떤 클래스에서 bean을 꺼낼(look up) 수 있는 factory가 필요하다면 BeanFactoryAware 인터페이스를 구현하거나.. 다른 방법도 있습니다.

 void setBeanFactory(BeanFactory beanFactory)

구현해야 할 메소드는 요고 하나 있습니다.

Reference에서는 이 인터페이스를 사용하는 것은 IoC답지 않고[각주:1] 소스코드가 Spring framwork에 종속성이 생기기 때문에 다른 방법을 사용한 예제를 보여 주고 있습니다.[각주:2]

3.3 맨 끝에서 Method Injection에 관한 부분에서 이게 필요한 상황이 나왔었습니다. 예를 들어 A가 singleton이고 B가 prototyp인데 A가 B를 가지고 있으면.. B는 prototype인데도 하나의 A가 한번만 만들어 지니까 A가 다른 bean에 참조 되거나 look up 됐을 때 마다 B가 새로 생기는게 아니라 기본에 만들어져있던 A를 계속 쓰게 되는 상황을.. BeanFactoryAware 인터페이스를 사용해서 해결할 수 있다고 했었습니다. 물론 그것 보다 더 좋은 방법은 Method Injection인데 아직 공부를 안해서 모르겠네요.

BeanFactoryAware 사용 예
ObjectFactoryCreatingFactoryBean 사용 예
  1. Dependency Lookup은 IoC답지 않은 것으로 생각하는 것 갔습니다. 어떤 책에서는 IoC 중에 DL과 DI가 있고 DI중에 Setter Injection과 Costructor Injection, Method Injection이 있다고 써놨던 것 같은데.. 햇갈리네요. [본문으로]
  2. ObjectFactoryCreatingFactoryBean 이것을 사용하여 설정 파일에서 DI를 사용하는 방법입니다. [본문으로]

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

BeanPostProcessor 사용 예  (0) 2007.03.13
3.7. Container extension points  (0) 2007.03.13
3.6. Bean definition inheritance  (0) 2007.03.12
ObjectFactoryCreatingFactoryBean 사용 예  (0) 2007.03.12
BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
top

Write a comment.


init-method & destroy-method

Spring/Chapter 3 : 2007.03.10 14:31


사용자 삽입 이미지
이 전 글에서 사용한 방식으로 Bean의 LifeCycle에 끼어들 수도 있지만 InitializingBean이나 DisposableBean과 같은 Spring 프레임웤 소스에 종속성이 생기게 됩니다.

<bean /> 태그의 init-method 와 destroy-method 속성을 이용하여 initializingBean과 DisposableBean을 대체 할 수 있습니다.
1. 초기화 메소드와 소멸자 메소드 이름을 마음대로 정할 수 있습니다.
2. Spring 프레임웤 종속성이 생기지 않습니다.
3. 모든 bean들 에게 공통의 이름을 사용하고 싶다면 <beans /> 태그에서 default-init-method와 default-destroy-method 속성을 사용하면 됩니다.
4. <beans /> 태그에 있는 defaut-xxx-mehot 속성을 <bean /> 태그에 있는 xxx-method 가 oveeriding 합니다.

<bean id="keesun11" class="beanConfiguration.Member" init-method="init" destroy-method="dispose" />

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

3.7. Container extension points  (0) 2007.03.13
3.6. Bean definition inheritance  (0) 2007.03.12
ObjectFactoryCreatingFactoryBean 사용 예  (0) 2007.03.12
BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
top

Write a comment.


InitializingBean & DisposableBean

Spring/Chapter 3 : 2007.03.10 13:38


    @Test public void initializingBean(){
        Member keesun10 = getMember("keesun10");
        assertEquals("initializing", keesun10.getLogMessage());
    }

이렇게 해놓고 다음과 같이 구현했습니다.
public class Member implements InitializingBean{
...
    public void afterPropertiesSet() throws Exception {
        logMessage = "initializing";
    }
}
테스트는 통과 합니다.

테스트 하기가 애매한건.. DisposableBean..
웹 어플리케이션이 아닌 경우에는 destroy() 콜백을 사용하려면 AbstractApplicationContext 의 registerShutdownHook() 를 호출 해주어야 합니다.

public class Member implements InitializingBean, DisposableBean{
...
    public void destroy() throws Exception {
        logMessage += " -> disposing now";
    }
}
이렇게 구현해 놓고.. test 하려면 안됩니다. 로그를 Member 객체 안에 있는 문자열로 다루면 안됩니다. 하나의 test 메소드가 끝날 때 destroy() 메소를 호출하게 되기 때문에 test메소드 안에서 Member객체의 문자열을 통해서 로그 메시지를 테스트 하는건... 글쎄요.. 방법이 없어 보입니다.

로그 메시지를 텍스트 파일이나 다른 객체에 기록을 하게 하고 테스트 메소드에서는 그 텍스트 파일이나 메시지를 읽어서 이전에 사용한 bean들의 로그 메시지를 확인하는 방법으로 테스트할 수 있겠습니다.

제일 위에 있는 테스트 메소드를 수정합니다.
    @Test public void initializingBean(){
        Member keesun10 = getMember("keesun10");
        assertTrue(Log.contains("initializing"));
    }

테스트를 통과하게 만든 후 detroy 메소드가 호출 되는지 테스트 하는 메소드를 만듭니다.
    @Test public void initializingAndDisposingLog(){
        assertTrue(Log.contains("disposing"));
    }

통과 하지 못합니다. 하지만 txt 파일을 열어 보면 disposing이 적혀 있습니다. 같은 테스트 클래스에 위치 하면 안될 것 같습니다. LogTest 클래스로 메소드를 옮겼습니다. 그랬더니 테스트가 통과 합니다.
미쳐 disposing 하기 전에 테스트를 실행해서 그렇습니다. 다른 테스트 클래스로 옮겨도 Test Suite을 만들고 두개의 테스트 클래스를 빠르게 실행하면 통과 하지 못합니다. disposing하도록 살짝 delay를 만든 다음에 테스트 하면 통과합니다.
public class LogTest {
    @Test public void disposingTest(){
        assertTrue(Log.contains("disposing"));
    }
}

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

3.6. Bean definition inheritance  (0) 2007.03.12
ObjectFactoryCreatingFactoryBean 사용 예  (0) 2007.03.12
BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
top

Write a comment.


Bean's Life Cycle

Spring/Chapter 3 : 2007.03.10 12:47


사용자 삽입 이미지

Spring In Action에 BeanFactory에서의 Bean Life Cycle 그림(p48)을 따라 그려봤습니다. BeanPostProcessor가 두 번 나오는데 처음에 나올 때는 ProcessBeforeInitialization() 이걸 호출 하고 나중에는 postProcessAfterInitialization() 이걸 호출한다고 합니다.

BeanPostProcessor API를 보니깐 BeanFactory는 BeanPostProcessor를 등록해줘야 하지만 AppicationContext에서는 bean으로 적어 두면 알아서 찾아서 묶어 주나 봅니다.

Bean Factory에서 제거 될 때는 아래의 순서를 거치게 됩니다.
사용자 삽입 이미지
파란 색 부분을 사용해서 bean이 초기화 되고 소멸 될 때 로깅 하는 걸 test 해봐야겠네요.

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

ObjectFactoryCreatingFactoryBean 사용 예  (0) 2007.03.12
BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
top

Write a comment.


The IoC container

Spring/Chapter 3 : 2007.03.10 11:51


3.1. Introduction
이번 장에서는 Spring 프레임웤이 구현한 IoC에 관해 다룹니다. IoC는 Spring이 제공하는 여러 기능들에 가장 기본이 됩니다.

IoC 컨테이너의 기능은 BeanFactory와 ApplicationContext 인터페이스를 통해 제공되며 BeanFactory가 객체를 관리하기 위한 기본적인 기능을 제공하는 반면 ApplicationContext는 거기에 추가해서 보다 다양한 기능을 제공합니다.

BeanFactory와 ApplicationContext 인터페이스 비교

3.2. Basics - containers and beans
bean은 IoC container에 의해 관리 되는 객체를 말합니다. 이 둘에 대한 기본적인 내용들을 담고 있습니다.

http://whiteship.tistory.com/519

3.3. Dependencies
bean들 간의 종속성을 주입하는 방법에 대해 나와있습니다.
3.3. Dependencies

3.4. Bean scopes

종속성 뿐만 아니라 bean의 scope도 설정할 수 있습니다.
3.4. Bean scopes

3.5. Customizing the nature of a bean
bean 생명주기에 껴들어서 좀 더 bean의 설정을 취미에 맞게 바꿀수 있습니다.
3.5. Customizing the nature of a bean

3.6. Bean definition inheritance
bean 설정 파일간에 상속을 통해 bean 설정을 재사용할 수 있습니다.
3.6. Bean definition inheritance

3.7. Container extension points
Spring 프레임웤의 IoC 컴포넌트는 확장을 고려하여 설계했습니다.

3.7. Container extension points

3.8. The ApplicationContext
BeanFactory의 기본 기능에 ApplicationContext가 추가한 기능들에 대한 설명이 있습니다.

3.8. The ApplicationContext

3.9. Glue code and the evil singleton

The majority of the code inside an application is best written in a DI style, where that code is served out of a Spring IoC container, has its own dependencies supplied by the container when it is created, and is completely unaware of the container.

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

BeanFactoryAware 사용 예  (1) 2007.03.12
BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
top

Write a comment.


3.5. Customizing the nature of a bean

Spring/Chapter 3 : 2007.03.10 11:49


3.5.1. Lifecycle interfaces

Spring container에서 사용된는 bean의 lifecycle에 부가적인 일을 추가할 수 있습니다. InitializingBeanDisposableBean 같은 인터페이스를 구현 하면 됩니다. 하지만 그렇게 되면 코드가 Spring 프레임웤에 종속성이 생기기 때문에 다른 방법도 있습니다.

Bean's Life Cycle
InitializingBean & DisposableBean
init-method & destroy-method

3.5.2. Knowing who you are

BeanFactory를 가지는 bean을 만들 수 있습니다.
BeanFactoryAware 인터페이스를 구현하면 되지만 그렇게 되면 Spring 프레임웤에 종속이 되기 때문에 다른 방법도 있습니다.

BeanFactoryAware

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

BeanFactoryAware  (0) 2007.03.12
init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
top

Write a comment.


Singleton & Prototype

Spring/Chapter 3 : 2007.03.09 15:07


<bean /> 엘리먼트의 scope 속성을 사용하여 bean의 scope을 지정해 줄 수 있습니다. default 값은 singleton입니다.
사용자 삽입 이미지

    <bean id="email2" class="beanConfiguration.Email" />

    <bean id="keesun6" class="beanConfiguration.Member">
        <property name="email" ref="email2" />
    </bean>

    <bean id="keesun7" class="beanConfiguration.Member">
        <property name="email" ref="email2" />
    </bean>

위와 같이 설정 해뒀다면 keesun6과 keesun7 이라는 Member bean은 같은 email 객체를 가지게 됩니다. 그래서 아래 처럼 원하지 않는 일이 발생할 수 있습니다.

@Test public void singletonScope(){
        Member keesun6 = getMember("keesun6");
        Member keesun7 = getMember("keesun7");
        Email email6 = keesun6.getEmail();
        Email email7 = keesun7.getEmail();
        assertEquals(email6, email7);
        String emailAddress = "hi@email.com";
        email6.setAddress(emailAddress);
        assertEquals(emailAddress, email7.getAddress());
    }

email2 bean의 scope을 prototype으로 지정해 줍니다.
사용자 삽입 이미지

    <!-- prototype -->
    <bean id="email3" class="beanConfiguration.Email" scope="prototype"/>

    <bean id="keesun8" class="beanConfiguration.Member">
        <property name="email" ref="email3" />
    </bean>

    <bean id="keesun9" class="beanConfiguration.Member">
        <property name="email" ref="email3" />
    </bean>

다음의 테스트를 통해서 email3 bean이 참조 대상 마다 생긴 것을 확인 할 수 있습니다.

    @Test public void prototypeScope(){
        Member keesun8 = getMember("keesun8");
        Member keesun9 = getMember("keesun9");
        Email email8 = keesun8.getEmail();
        Email email9 = keesun9.getEmail();
        assertNotSame(email8, email9);
    }

번외.. ref 에서 자동 완성 기능 사용 시 스크린 샷
사용자 삽입 이미지
역시.. 좋아요.

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

init-method & destroy-method  (0) 2007.03.10
InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
top

Write a comment.


3.4. Bean scopes

Spring/Chapter 3 : 2007.03.09 14:19


설정 파일에서 bean들을 정의하고 다른 bean들 과의 종속성을 정의 하는 것 말고도 각각 bean들의 scope을 설정해 줄 수 있습니다.

ScopeDescription

singleton

Spring Ioc 컨테이너 내에서 bean 정의 당 하나의 객체

prototype

매번 같은 Type의 새로운의 객체

request

Http request 당 하나 씩, web-aware ApplicationContext

session

Http session 당 하나 씩, web-aware ApplicationCotext

global session

Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.


3.4.1. The singleton scope

Container 당 하나의 객체라는 의미에서 singleton 입니다.[각주:1]

3.4.2. The prototype scope

bean을 요청 할 때[각주:2] 마다 새로운 객체를 만들어 줍니다.

Singleton & Prototype

3.4.3. The other scopes

request, session, grobalSession은 web-based ApplicationContext에서 사용할 수 있습니다.[각주:3]

3.4.4. Custom scopes

새로운 Scope을 만들거나 기존의 Scope을 변경할 수 있습니다.
  1. JVM의 classloader당 하나의 객체라는 의미의 GoF의 Singleton과는 다릅니다. [본문으로]
  2. DI 되거나 getBean(String)에 의해 호출 될 때 [본문으로]
  3. WebApplicationContext 인터페이스를 구현한 클래스들을 말하는 것이 아닐지 생각해 봤습니다. [본문으로]

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

InitializingBean & DisposableBean  (0) 2007.03.10
Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
idref 엘리먼트  (0) 2007.03.08
top

Write a comment.


Autowiring

Spring/Chapter 3 : 2007.03.09 12:47


<bean /> 엘리먼트의 autowire 속성을 사용하여 bean들을 자동으로 묶을 수 있습니다. autowire에 지정할 수 있는 값은 다섯가지가 있습니다.

no : 기본값입니다. autowire를 사용하지 않겠다는 겁니다.
byName :  bean의 property 이름으로 다른 bean을 찾아서 연결합니다.
byType : bean의 property 타입으로 다른 bean을 찾아서 연결합니다. 같은 type의 bean이 여러개면 에러가 발생합니다.
constuctor : byType과 비슷한데 생성자에 있는 인자들의 Type으로 찾아서 연결합니다.
autodetect : constuctor 또는 byType으로 찾게 됩니다. default 생성자가 있으면 byType으로 찾는다는 군요.

명시적으로 <property /> 나 <constructor-arg /> 를 사용하여 종속성을 적어 줄 경우에는 autowiring으로 연결된 종속성을 overriding 합니다.
장점
1. configuration 파일의 크기를 줄여 줍니다.
2. 객체가 변하거나 추가 될 때 설정 파일의 많은 변경이 필요하지 않습니다.

단점
1. 너무 매직 스러움.
2. wiring 정보를 감춰져서 문서화 하는 도구에서 알아채질 못합니다.
3. type으로 wiring할 경우 애매한 상황이 조금이라도 발생하면 명시적으로 적어줘야 합니다.

Email 클래스를 추가하고 Member 당 하나의 Email 레퍼런스를 가지고 있습니다.

    <bean id="email" class="beanConfiguration.Email">
        <property name="type" value="google" />
        <property name="address" value="myemail@gmail.com" />
    </bean>

    <bean id="keesun5" class="beanConfiguration.Member" autowire="byName" />

Member 클래스에 setEmail(Email email) 메소드가 있기 때문에 email 이라는 이름의 bean을 찾아서 자동으로 엮어 줍니다.

    @Test public void autowiringByName(){
        Member keesun = (Member) bf.getBean("keesun5");
        Email email = keesun.getEmail();
        assertEquals("google", email.getType());
        assertEquals("myemail@gmail.com", email.getAddress());
    }



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

Bean's Life Cycle  (0) 2007.03.10
The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
idref 엘리먼트  (0) 2007.03.08
Constructor Injection 할 때 인자 구분  (0) 2007.03.08
top

Write a comment.


Collection Merging

Spring/Chapter 3 : 2007.03.09 10:48


<list /> <set /> <map /> <props />는 parent bean - child bean의 관계에 있을 때 merge가 가능합니다. merge를 하고 싶을 때는 위 태그들의 속성 중에 merge 속성에 "true" 값을 주면 됩니다.

    <bean id="keesun3" class="beanConfiguration.Member">
        <property name="wishList">
            <list>
                <value>NDS</value>
                <value>Wii</value>
                <value>WOW</value>
            </list>
        </property>
    </bean>

    <bean id="keesun4" parent="keesun3" class="beanConfiguration.Member">
        <property name="wishList" >
            <list merge="true">
                <value>MacBook</value>
                <value>WOW</value>
            </list>
        </property>
    </bean>

keesun3 이 keesun4 의 parent bean인 상태에서 <list /> merge 속성을 true를 지정했기 때문에 아래의 테스트가 통과 합니다.

    @Test public void listMerging(){
        Member keesun = (Member) bf.getBean("keesun4");
        List<String> wishList = keesun.getWishList();
        assertEquals(5, wishList.size());
        assertEquals("NDS", wishList.get(0));
        assertEquals("Wii", wishList.get(1));
        assertEquals("WOW", wishList.get(2));
        assertEquals("MacBook", wishList.get(3));
        assertEquals("WOW", wishList.get(4));
    }

chile bean의 콜렉션에 같은 요소가 있을 경우 <list /> 와는 다르게 <set /> <map /> <props /> 는 child bean의 콜렉션이 parent bean에 있는 collection을 overriding 합니다.


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

The IoC container  (0) 2007.03.10
3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
idref 엘리먼트  (0) 2007.03.08
Constructor Injection 할 때 인자 구분  (0) 2007.03.08
Setter Injection & Constructor Injection  (0) 2007.03.08
top

Write a comment.


Collections - <list />

Spring/Chapter 3 : 2007.03.08 23:06


<list /> 엘리먼트는 Java의 List에 대응 합니다. 다음과 같이 설정할 수 있습니다.
    <bean id="keesun3" class="beanConfiguration.Member">
        <property name="wishList">
            <list>
                <value>NDS</value>
                <value>Wii</value>
                <value>WOW</value>
            </list>
        </property>
    </bean>
순서대로 NDS가 첫번째 WOW가 세번째 입니다.

    @Test public void list(){
        Member keesun = (Member) bf.getBean("keesun3");
        List<String> wishList = keesun.getWishList();
        assertEquals("NDS", wishList.get(0));
        assertEquals("Wii", wishList.get(1));
        assertEquals("WOW", wishList.get(2));
    }
위의 테스트 코드로 확인할 수 있습니다.

번외로.. Eclipse 자동 완성 기능 정말 좋네요.
사용자 삽입 이미지



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

3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
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
top

Write a comment.


Inner beans

Spring/Chapter 3 : 2007.03.08 22:09


<propery /> 또는 <constructor-arg /> 의 하위 엘리먼트로 <bean /> 을 사용하면 됩니다.
<bean id="outer" class="...">
  <!-- instead of using a reference to a target bean, simply define the target bean inline -->
  <property name="target">
    <bean class="com.mycompany.Person"> <!-- this is the inner bean -->
      <property name="name" value="Fiona Apple"/>
      <property name="age" value="25"/>
    </bean>
  </property>
</bean>
inner bean의 id나 name 속성은 사용하지 않아도 됩니다.
=> 어차피 inner bean을 둘러싸고 있는 bean에서만 사용 될 것이기 때문에 굳이 식별자가 필요하지 않으며 id나 name을 적어도 container가 무시하게 됩니다.

inner bean의 scope는 항상 protorype 입니다.
=> 흠.. local 변수 처럼 생각하면 되겠죠?

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

Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
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
top

Write a comment.


idref 엘리먼트

Spring/Chapter 3 : 2007.03.08 18:45


<property /> 와 <constructor-arg /> 에서 DI를 할 때 다른 bean을 참조 한다면 idref 를 사용할 수 있습니다.
<bean id="theTargetBean" class="..."/>

<bean id="theClientBean" class="...">
    <property name="targetName">
        <idref bean="theTargetBean" />
    </property>
</bean>
이건 아래의 것과 같습니다.
<bean id="theTargetBean" class="..."/>

<bean id="client" class="...">
    <property name="targetName">
        <value>theTargetBean</value>
    </property>
</bean>

차이점
1. idref를 사용하면 참조하는 이름의 bean이 실제 존재하는지 배포 시에 검증하게 됩니다.
2. 참조 하는 bean이 같은 파일 안에 정의 되어 있을 때 <idref local="빈이름" />형태로 쓸 수 있는데 이렇게 쓰면 XML 파싱 할 때 XML 검증을 통해 설정에 문제가 있을 때 에러를 발견할 수 있습니다.

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

3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
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
top

Write a comment.


Constructor Injection 할 때 인자 구분

Spring/Chapter 3 : 2007.03.08 18:16


Setter Injection을 할 때는 property의 name이 표기가 되니까 어디로 들어가는 값인지 명확하지만 Constructor Injectoin을 할 때는 순서에 의존하게 되는데.. 좀.. 불명확 합니다.

   <bean id="keesun2" class="beanConfiguration.Member">
       <constructor-arg value="whiteship" />
       <constructor-arg value="1234" />
       <constructor-arg value="26" />
   </bean>

그래서 <constructor-arg /> 태그의 type 이나 index 속성을 사용해서 명확히 해주는게 좋겠습니다. 특히 primitive type의 경우에는 전부 <value /> 라는 하위 엘리먼트 또는 value 속성으로 적어 주게 되어있는데 이럴 때 써주는게 좋을 것 같습니다. non-primitive type 일 경우에는 type보다는 index가 좋겠네요. index는 0부터 시작해서 첫번째 인자를 나타냅니다.

    <bean id="keesun2" class="beanConfiguration.Member">
        <constructor-arg index="0" value="whiteship" />
        <constructor-arg index="1" value="1234" />
        <constructor-arg index="2" value="26" />
    </bean>

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

Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
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
top

Write a comment.


Setter Injection & Constructor Injection

Spring/Chapter 3 : 2007.03.08 14:19


예제로 사용될 Member 클래스 입니다.
1. Setter Injection

이것을 사용하기 위해서는 setter가 있어야 합니다. 설정파일에는 다음과 같이 <property /> 태그를 이용해서 Injection을 합니다.
    <bean id="keesun" class="beanConfiguration.Member">
        <property name="id" value="whiteship" />
        <property name="password" value="pass" />
        <property name="age" value="26" />
    </bean>

다음과 같이 테스트 메소드를 작성한 뒤 테스트 해 봅니다.
    @Test public void setterInjection(){
        Member keesun = (Member) bf.getBean("keesun");
        assertEquals("whiteship", keesun.getId());
        assertEquals("pass", keesun.getPassword());
        assertEquals(26, keesun.getAge());
    }
됩니다. 이때 적절한 primitive type으로 알아서 바꿔주는 것을 확인할 수 있습니다.

2. Constructor Injection

이것을 사용하기 위해서는 인자가 있는 생성자가 필요합니다. 설정파일에는 <constructor-arg /> 태그를 사용합니다.
    <bean id="keesun2" class="beanConfiguration.Member">
        <constructor-arg value="whiteship" />
        <constructor-arg value="pass" />
        <constructor-arg value="26" />
    </bean>
테스트 코드는 위에서 getBean("keesun2")로만 바꿔주면 됩니다.

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

Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
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
top

Write a comment.


3.3. Dependencies

Spring/Chapter 3 : 2007.03.08 11:36


3.3.1. Injecting dependencies

DI(Dependency Injection)이 적용되면 클래스들간의 관계에 고도의 디커플링을 유지할 수 있고 코드가 훨씬 깨끗해 집니다. 주로 setter injection과 constructor injection으로 나뉩니다.

Service Locater 패턴
참조.
Setter Injection & Constructor Injection

3.3.2. Constructor Argument Resolution

생성자의 인자를 구분 할 필요가 있는 경우에 인자의 type 또는 index로 구분할 수 있습니다.

Constructor Injection 할 때 인자 구분

3.3.3. Bean properties and constructor arguments detailed

<property /> 태그(=엘리먼트)와 <constructor-arg /> 태그는 종속성을 가지는 대상에 따라 사용할 수 있는 하위 태그들이 여러개 있습니다. ex. <value /> <idref /> <ref /> <bean />[각주:1] <list /> <set /> <map /> <props /> <null />

idref 엘리먼트
Inner beans
Collections - <list />
Collection Merging

3.3.4. Using depends-on

<bean /> 태그의 depends-on 속성에 bean의 id를 적어주면 현재 bean을 초기화하기 전에 depends-on 속성에 적어준 bean들을 먼저 초기화 합니다.
<bean id="beanOne" class="ExampleBean" depends-on="manager"/>

<bean id="manager" class="ManagerBean" />
위와 같이 설정 한다면 beanOne을 초기화 하기 전에 manager bean을 먼저 초기화 합니다.

만약 여러개의 bean에 종속성을 가지고 그 bean들이 먼저 초기화 되길 바란다면 아래 처럼 여러개를 적을 수 있습니다.
<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
  <property name="manager" ref="manager" />
</bean>

<bean id="manager" class="ManagerBean" />
<bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />

3.3.5. Lazily-instantiating beans

ApplicationContext를 구현한 container들은 모든 bean들을 기본적으로 singleton scope의 bean들을 pre-instantiation(초기 생성?) 합니다. [각주:2] 그렇게 함으로써 초기에 설정이나 기타 환경에 대한 에러들을 초기에 발견할 수 있습니다.

하지만~ 초기에 모든 bean들을 만들어 내기 싫을 수가 있는데요. 그럴 때는 <bean /> 태그에 lazy-init="true" 를 추가하여 하나의 bean이 초기화 지연 기법을 사용할 수 있으며...
container의 기본 설정을 바꾸려면 configuration metadata의 최상위 엘리먼트인 <beans /> 태그에 default-lazy-init="true" 를 추가하면 됩니다.

주의 : pre-instantiation bean이 lazy bean에 종속성을 가진다면..먼저 만들어야 할 bean 때문에 나중에 만들 bean도 먼저 만들게 됩니다.

3.3.6. Autowiring collaborators

bean들 간의 종속성을 자동으로 맺어 줄 수 있는 기능이 있습니다. 장단점을 알아봐야겠습니다.

Autowiring

3.3.7. Checking for dependencies

bean에 있는 모든 property들이 잘 세팅이 되었는지 확인하고 싶을 때 사용할 수 있습니다. <bean /> 태그에 dependency-check 속성에 네가지 모드 값 중에 하나를 선택에서 넣어주면 됩니다.

ModeExplanation
none

No dependency checking. Properties of the bean which have no value specified for them are simply not set.

simple

Dependency checking is performed for primitive types and collections (everything except collaborators, i.e. other beans)

object

Dependency checking is performed for collaborators only

all

Dependency checking is done for collaborators, primitive types and collections


3.3.8. Method Injection

singlton bean(매번 같은 객체) A가 non-singleton bean(매번 다른 객체) B를 사용하게 된다면(종속성을 가지면)...B는 의도 했던 바와는 다르게.. 매번 같은 객체만 사용될 것입니다.
 
이 문제를 해결 하는 방법으로는.. A가 BeanFactoryAware 인터페이스를 구현해서 B를 요구할 때마다 getBean("B")를 이용하는 방법이 있긴 한데...

이러면 A라는 클래스가 BeanFactoryAware라는 Spring Framework의 코드에 종속되기 때문에 Method Injection이라는 것을 사용해서 좀 더 깔끔하게 이 문제를 해결 할 수 있다고 합니다.
  1. inner bean [본문으로]
  2. pre-instantiation은 container의 초기화 과정에서 객체를 생성하고 종속성을 설정하게 되는 것을 말합니다. [본문으로]

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

Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
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
top

Write a comment.


Bean 생성하기

Spring/Chapter 3 : 2007.03.07 15:37


bean 생성하는 방법 세 가지
1. 생성자 사용하기.
2. static factory method 사용하기.
3. instance factory method 사용하기.

bean태그의 class 속성에는 굳이 JavaBean 스펙을 따르지 않는 클래스라도 자유롭게 설정파일에 지정하면 사용할 수 있습니다.

1. 생성자 이용하기.
<bean id="혜인" name="이쁘니" class="beanConfiguration.Member"/>
여태까지 하던데로 지정하면 됩니다. 단.. 이때 적절한 생성자가 필요합니다. 위에 있는 설정은 한 default 생성자를 사용하여 객체를 만들겠다는 것입니다. 따라서 default 생성자 없다면 BeanCreationException이 발생합니다.

2. static factory method 사용하기.
<bean id="pizza" class="keesun.PizzaStore" factory-method="createPizza"/>
<bean /> 태그 안에 class는 static factory 메소드를 가지고 있는 클래스 경로를 적어 주고 factory-method 속성에 해당 메소드 명을 적어 줍니다.

3. instance factory method 사용하기.
<bean id="pizzaStore" class="keesun.pizzaStrore" />
<bean id="pizza" factory-bean="pizzaStore" factory-method="createPizza" />
팩토리 메소드를 가지고 있는 객체를 통해 팩토리 메소드에 접근 하려면 bean으로 해당 클래스를 등록 해두고 factory-bean에 클래스를 적어주고 나머진 2번과 동일합니다.

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

Inner beans  (0) 2007.03.08
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
top

Write a comment.


복잡한 Alias

Spring/Chapter 3 : 2007.03.07 15:04


사용자 삽입 이미지
    <bean id="혜인" name="이쁘니" class="beanConfiguration.Member"/>

    <alias name="이쁘니" alias="효도르" />
    <alias name="이쁘니" alias="지름쟁이" />

이 전 글에 이어서.. 이 상태에서 왠지 "지름쟁이"와 "효도르"로 얻어낸 bean은  "이쁘니"로 얻어낸 bean과 같을 것 같았는데... 다르네요.

        Member bean1 = (Member) bf.getBean("혜인");
        Member bean2 = (Member) bf.getBean("이쁘니");
        Member alias1 = (Member) bf.getBean("효도르");
        Member alias2 = (Member) bf.getBean("지름쟁이");

        assertFalse(bean2.equals(alias1));
        assertFalse(bean2.equals(alias2));

하지만 getAlias("효도르") 나 getAlias("지름쟁이")를 호출하게 되면 String 배열에는 "이쁘니"가 포함되어 있습니다. -_-;; 오.. 점점 혼란스러워 지는 군요.

"효도르"와 "지름쟁이"는 "이쁘니"의 Alias는 맞는데 "이쁘니"와 같은 객체는 아닙니다.

이렇게.. 복잡한 상황이 발 생할 수 있기 땜시..BeanDefinition 이름으로 alias를 설정해 주어야 합니다.

    <bean id="혜인" name="이쁘니" class="beanConfiguration.Member"/>
    <alias name="혜인" alias="착한 아이" />
    <alias name="혜인" alias="얌전한 아이" />
사용자 삽입 이미지


    @Test public void beanDefinitionNameAliasing(){
        String[] aliases = bf.getAliases("혜인");
        assertTrue(aliases.length == 3);

        Member bean1 = (Member) bf.getBean("혜인");
        Member bean2 = (Member) bf.getBean("이쁘니");
        Member alias1 = (Member) bf.getBean("착한 아이");
        Member alias2 = (Member) bf.getBean("얌전한 아이");

        assertTrue(bean1.equals(bean2));
        assertTrue(bean1.equals(alias1));
        assertTrue(bean1.equals(alias2));
        assertTrue(alias1.equals(alias2));
    }
테스트는통과 합니다. 혜인이는 이쁘니, 착한 아이, 조용한 아이로 불러온 bean과 동일합니다.

String[] getAlias(String name) 이 메소드는 name에 혜인, 이쁘니, 착한 아이, 얌전한 아이를 넣으면 모두 자기 자신을 제외한 alias 3개씩을 가지게 됩니다.

"이쁘니", "착한 아이", "얌전한 아이"는 "혜인"의 alias이면서 "혜인"과 같은 객체입니다.

'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.


Aliasing Beans

Spring/Chapter 3 : 2007.03.07 13:30


이전 글 id와 name 그리고 BeanDeinition 이름에서 bean의 유일한 식별자를 구별해 낼 수 있게 됐습니다. 유일한 식별자 이외 나머지는 모두 별칭(alias)이 됩니다.[각주:1]

다수의 name을 사용해서 별칭을 만들수도 있지만 <alias /> 태그를 사용해서 만들 수도 있습니다. 이 때 주의해야 할 것은 별명을 진짜 대상(유일한 식별자)에다가 붙여야 한다는 것입니다.

즉..bean의 유일한 식별자 즉 BeanDefinition 이름을 alias 태그의 name 속성에 적어 두어야 합니다.

사용자 삽입 이미지

만약에 "이쁘니"라는 별명이 있는 "혜인"이가 있다고 했을 때 즉.. "혜인"이 BeanDefinition 이름이고 "이쁘니"는 alias입니다.
<bean id="혜인" name="이쁘니" class="keesun.lover.Hein" />
또는
<bean name="혜인, 이쁘니" class="keesun.lover.Hein" />
이런 식으로 지정하면 가정한 상황처럼 됩니다.

여기에 또 다시 "효도르", "지름쟁이"라는 별칭을 "이쁘니"에 다가 매겼다고 생각해 봅니다.
<alias name="혜인" alias="효도르" />
<alias name="혜인" alias="지름쟁이" />

그럼 이제.. "효도르"는 혜인이의 별명인가요?? 아니죠? "이쁘니"의 별명이 "효도르"일뿐 혜인이의 별명이 "효도르"는 아닙니다. alias는 추이적인 속성이 없기 때문에 절대로 혜인이는 효도르로 불려지지 않으며 더욱이 "지름쟁이"라는 별명으로 혜인이를 부르려고 해봤자 헛수고 입니다.
    <bean id="혜인" name="이쁘니" class="beanConfiguration.Member"/>
    <alias name="이쁘니" alias="효도르" />
    <alias name="이쁘니" alias="지름쟁이" />

    @Test public void beanAliasing(){
        String[] aliases = bf.getAliases("혜인");
        assertTrue(aliases.length == 1);
        assertTrue(aliases[0].equals("이쁘니"));

        Member bean1 = (Member) bf.getBean("혜인");
        Member bean2 = (Member) bf.getBean("이쁘니");
        Member alias1 = (Member) bf.getBean("효도르");
        Member alias2 = (Member) bf.getBean("지름쟁이");

        assertTrue(bean1.equals(bean2));

        assertFalse(bean1.equals(alias1));
        assertFalse(bean1.equals(alias2));

        assertTrue(alias1.equals(alias2));
    }
테스트는 통과 합니다.

  1. BeanFactory에 있는 String[] getAlias(String name) 메소드를 이용해서 확인할 수 있습니다. [본문으로]

'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.


id, name and BeanDefinitionName

Spring/Chapter 3 : 2007.03.06 13:50


참조 : 빈(bean)의 이름 지정

bean의 식별자를 지정하는 방법은 두 가지
가 있습니다.
1. bean 태그에 id 속성에 값을 지정할 수 있습니다.
=> id 속성에는 하나의 값만 쓸 수 있습니다. 빈 공간(스페이스)이나 콤마(,) 세미콜론(;)등을 사용할 수 없습니다.
2. bean 태그에 name 속성에 값을 지정할 수 있습니다.
=> 여러개의 값을 지정할 수 있습니다. 빈 공간, 콤마, 세미콜론 등으로 구분 할 수 있습니다.
사용자 삽입 이미지

그리고 BeanDefinition 이름은 bean마다 하나씩 가지게 됩니다. 그리고 BeanDefinition 이름은 나중에 aliasing을 할 때 알아 둬야 하기 때문에 어떤 식별자가 BeanDefinition 이름이 되는지 알아둘 필요가 있습니다.
1. id와 name 모두 없는 경우
<bean class="beanConfiguration.Member" />

    @Test public void beanDefinitionName(){
        ListableBeanFactory lbf = (ListableBeanFactory)bf;
        List<String> names = new ArrayList<String>();
        for(String name : lbf.getBeanDefinitionNames())
            names.add(name);
        assertTrue(names.size() == 1);
        assertTrue(names.get(0).equals("beanConfiguration.Member"));
    }
=> inner bean을 사용할 때 id와 name을 모두 명시 하지 않을 수 있으며 이때 BeanDefinition 이름을 찍어보면 default로 패키지 경로가 붙은 클래스 이름으로 지정 된 것을 확인할 수 있습니다.

2. id만 있는 경우
<bean id="member" class="beanConfiguration.Member" />

    @Test public void beanDefinitionName(){
        ListableBeanFactory lbf = (ListableBeanFactory)bf;
        List<String> names = new ArrayList<String>();
        for(String name : lbf.getBeanDefinitionNames())
            names.add(name);
        assertTrue(names.size() == 1);
        assertTrue(names.get(0).equals("member"));
    }
=> id에 지정한 이름이 BeanDefinition 이름이 됩니다.

3. name만 있는 경우(name의 값으로 하나 만 있는 경우)
<bean name="member" class="beanConfiguration.Member" />

테스트는 2번과 동일하며 통과 합니다.
=> name에 지정한 이름이 BeanDefinition 이름이 됩니다.

4. name만 있는 경우(name에 값이 여러 개인 경우)
<bean name="member, member1, member2" class="beanConfiguration.Member" />

테스트는 역시 2번과 동일하며 통과 합니다.
=> name에 지정한 이름들 중에서 가장 앞에 있는 값이 BeanDefition 이름이 됩니다.

5. id와 name이 모두 있는 경우
<bean id="member" name="member1, member2" class="beanConfiguration.Member" />

테스트는 역시 2번과 동일하며 통과 합니다.
=> id에 지정한 값이 BeanDefinition 이름이 됩니다.

결론은 그림으로 나타내면..
사용자 삽입 이미지

'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.


FileSystemResource vs ClassPathResource

Spring/Chapter 3 : 2007.03.06 00:40


FileSystemResource경로가 프로젝트 최상위 폴더 부터 시작하고 ClassPathResource는 자원의 경로를 패키지로 구분합니다. 따라서 아무것도 안쓰면 default 패키지에 있는 것으로 인식합니다.

public class MemberBeanTest {
    @Test
    public void createBean(){
        Resource resource = new FileSystemResource("beanConfiguration.xml");
        BeanFactory bf = new XmlBeanFactory(resource);
        assertNotNull(bf.getBean("member"));
    }
}

이렇게 FileSystemResource를 사용하여 설정 파일의 위치를 나타낼 경우 저 파일은 아래 그림과 같이 프로젝트 최상위 폴더에 있어야 합니다.
사용자 삽입 이미지

public class MemberBeanTest {
    @Test
    public void createBean(){
        Resource resource = new ClassPathResource("beanConfiguration.xml");
        BeanFactory bf = new XmlBeanFactory(resource);
        assertNotNull(bf.getBean("member"));
    }
}

이렇게 코드를 바꾼뒤에 테스트를 실행하면 BeanDefinitionStoreException이 발생합니다. 이 Exception은 bean 설정 파일을 못찾거나 설정 파일이 잘 못 됐을 때 발생하는 에러 입니다.
사용자 삽입 이미지
위 처럼 설정 파일의 위치를 소프 폴더로 옮겨 놓으면 됩니다.

사용자 삽입 이미지
이번에는 conf 라는 디렉토리 밑으로 설정 파일을 옮겼습니다. 도저히 패키지 명을 사용해서 접근할 방법은.. 모르겠네요; 없지 않나요.ㅋ;  이때는 아래 처럼 FileSystemResource의 생성자 인자로 쩜 하나를 사용해서 상대 경로로 찾아가게 할 수 있습니다.
public class MemberBeanTest {
    @Test
    public void createBean(){
        Resource resource = new FileSystemResource("./conf/beanConfiguration.xml");
        BeanFactory bf = new XmlBeanFactory(resource);
        assertNotNull(bf.getBean("member"));
    }
}


'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

  1. Favicon of http://decoder.tistory.com BlogIcon decoder 2007.03.06 01:24 PERM. MOD/DEL REPLY

    저렇게 될 경우에는 classpath를 이클립스 설정창에서 추가해 주면 됩니다. 빈 설정 파일이 들어있는 폴더를 프로젝트 -> Properties -> Java Build Path -> Libraries 탭 -> Add Class Folder로 추가해 주면 될것 같습니다. 지금 같은 경우엔 conf 폴더를 추가해 주시면 될 것 같네요. 단, 설정파일을 프로젝트 루트에 위치시키고 루트를 클래스 패스로 추가하는 건 안되는 것 같네요. :)

    그리고 xml 파일은 리소스라서(Java 클래스가 아니라서) 패키지 형식으로 접근할 수 있을진... 잘모르겠습니다. ^^;

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

    아.. 그렇군요.

    패키지 형식으로 접근 한다는 것이 아니라. 패키지 경로에 따라 적어줘야 한다는걸 제가 잘못 표현 했네요.

    abc.xml 이라고 적으면 default 패키지..
    keesun/abc.xml 이라고 적으면 keesun 패키지에 들어있어야 한다는 것이였어요. 흐흣

Write a comment.


3.2. Basics - containers and beans

Spring/Chapter 3 : 2007.03.05 13:21


3.2.1. The container

사용자 삽입 이미지
3.2.1.1. Configuration metadata

Spring IoC Container가 어떻게 bean을 만들고, 설정하고, 엮을지 적어 놓은 것으로 주로 XML을 사용하지만 XML이 유일한 방법은 아닙니다.

XML 기반의 Configuration metadata 예.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  <bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
  </bean>
  <bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
  </bean>
  <!-- more bean definitions go here... -->
</beans>

Configuration Metadata 이해

3.2.2. Instantiating a container

Container를 생성하는 방법은 쉽습니다.
Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
요래..
ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
요래..
ApplicationContext context = new ClassPathXmlApplicationContext(
        new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
// of course, an ApplicationContext is just a BeanFactory
BeanFactory factory = (BeanFactory) context;
할 수 있습니다. 마지막 꺼는 xml 설정 파일 두 개를 Container에 불러 왔네요.

FileSystemResource vs ClassPathResource (2)
id, name and BeanDefinitionName

3.2.2.1. Composing XML-based configuration metadata

설정을 여러 개의 파일로 나눠 둘 수 있고 당연히 여러 개의 설정 파일을 위에 나온 방식 처럼 Container를 만들 때 사용할 수 있습니다. 그러나 위에 처럼 설정 파일 명을 프로그램 파일 내부에 표기 하는 것 보다는 xml 안에 숨겨 두는 것이 좋습니다. <import /> 를 사용하여 설정 파일을 지정할 수 있습니다.
<beans>

    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>

</beans>

3.2.3. The beans

bean 설정 데이타는 BeanDefinition이라는 객체로 표현됩니다.

3.2.3.1. Naming beans

모든 bean들은 하나 이상의 id를 가집니다. 이런 id들은 유일해야 하며 하나 이상의 id를 가지는 bean의 경우 하나를 제외한 나머지는 별칭으로 취급 됩니다. <bean /> 태그의 id와 name속성을 사용하여 지정할 수 있습니다.

빈(bean)의 이름 지정
Spring의 naming/aliasing 정책에 대한 수사 (상)
Spring의 naming/aliasing 정책에 대한 수사 (중)
Spring의 naming/aliasing 정책에 대한 수사 (하)

이쪽은 뭔가 좀더 자세히 봐야 겠습니다.

Aliasing Beans (4)
복잡한 Alias
Bean 생성하기

3.2.4. Using the container

BeanFactory를 사용하는 방법입니다.
InputStream is = new FileInputStream("beans.xml");
BeanFactory factory = new XmlBeanFactory(is);
위 코드는 맨 위에 있는 그림 중에 빡스와 설정 파일 부분에 해당하며..

application에서는 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.


BeanFactory와 ApplicationContext 인터페이스

Spring/Chapter 3 : 2007.03.05 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.