2014-10-28 3 views
4

Spring은 bean 범위를 "Prototype"으로 제공합니다. 응용 프로그램에서 bean이 필요할 때마다, Spring container는 bean의 새로운/새로운 인스턴스를 생성합니다. 프로토 타입 디자인 패턴을 따르고 있습니까? 개체를 한 번만 생성하고 후속 요청에서 생성 된 개체의 clone() 메서드를 호출하여 새 개체를 만듭니다.프로토 타입 디자인 패턴을 따르는 스프링 프로토 타입

또한 누군가 JDK, Spring, Hibernate 또는 J2EE 프레임 워크에서 프로토 타입 예제를 제공 할 수있는 경우.

+0

나는이 두 개의 질문으로 요청을받은 것을 말함으로써 시작합니다. 당신의 1 세대를 위해 나는 [소스 코드]에 파고하지 않은 (https://github.com/spring-projects/spring-framework)하지만, 실제로 프로토 타입 패턴을 활용 않으면 나는 매우 놀랄 것입니다. 두 번째 후 질문의 경우 : http://en.wikipedia.org/wiki/Prototype_pattern#Java_Example – Floegipoky

답변

0

스프링은 프로토 타입 패턴을 사용하지 않으므로 반사를 사용합니다. 또한 clone()을 사용하려면 clone()이 보호되므로 clone()도 사용하지 않으므로 어떻게 든 bean을 서브 클래스해야합니다. 그래서

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) { 

    if (beanDefinition.getMethodOverrides().isEmpty()) { 
     Constructor<?> constructorToUse; 
     synchronized (beanDefinition.constructorArgumentLock) { 
      constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod; 
        ... 
         constructorToUse = clazz.getDeclaredConstructor((Class[]) null); 
        ... 
       } 
       ... 

    } 
    ... 
} 

용어 : 여기

는 java.lang.reflect.Constructor의와 java.lang.Class의 반사 방법의 사용을 볼 수 있습니다

org.springframework.beans.factory.support.SimpleInstantiationStrategy 

에서 코드 조각입니다 프로토 타입은 getBean을 호출 할 때마다 동일한 속성을 가진 새 인스턴스를 가져 오도록 제안하는 데 사용됩니다. 이것은 생성자에 대한 간단한 호출 이상의 의미를 가지지 만, 모든 종속성이 설정된 bean과 다른 속성이 설정된 bean을 얻게되므로 어떤 의미에서는 프로토 타입이됩니다. 또는 적어도 그것은 개념을 매우 잘 맞 춥니 다.

0

나는 봄 소스 코드에 파고하지 않은,하지만 그 콩의 Cloneable 인터페이스를 구현하는 것이 필수가 아니기 때문에 나는 clone() 방법을 사용하여 생성되지 않습니다 봄 prototype 범위와 콩을 생각합니다.

또한 clone()을 사용하여 생성한다고 가정합니다. 누군가가 얕은 사본 대신에 깊은 사본을 기대한다면 그것은 위험 할 것입니다.

언제든지 테스트하여 답변을 찾을 수 있습니다.

1

스프링은 프로토 타입 범위 인스턴스를 만들기 위해 복제를 사용하지 않습니다.

BeanUtils.instantiateClass(constructorToUse); 
0

번호 봄 범위 등 프로토 타입 :

// Create bean instance. 
if (mbd.isSingleton()) { 
    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 
     @Override 
     public Object getObject() throws BeansException { 
      try { 
       return createBean(beanName, mbd, args); 
      } 
      catch (BeansException ex) { 
       // Explicitly remove instance from singleton cache: It might have been put there 
       // eagerly by the creation process, to allow for circular reference resolution. 
       // Also remove any beans that received a temporary reference to the bean. 
       destroySingleton(beanName); 
       throw ex; 
      } 
     } 
    }); 
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 
} 

else if (mbd.isPrototype()) { 
    // It's a prototype -> create a new instance. 
    Object prototypeInstance = null; 
    try { 
     beforePrototypeCreation(beanName); 
     prototypeInstance = createBean(beanName, mbd, args); 
    } 
    finally { 
     afterPrototypeCreation(beanName); 
    } 
    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 
} 

createBean 메서드 호출이 코드를 아래에 요약된다 : 아래

는 AbstractBeanFactory.doGetBean (에서 가져온 코드) 기능입니다
또는 싱글 톤 엄격하게 디자인 패턴을 따르지 마십시오. 범위의 명명은 직관적으로 행동 컨테이너가 제안하는 데 사용되었습니다.

이렇게하면 컨테이너 내에 "싱글 톤"패턴을 만들 수 있으며 컨테이너 외부에 다른 개체를 만들 수 있습니다. 마찬가지로 "프로토 타입"패턴은 "복제"기능을 구현할 필요가 없습니다.

당신은뿐만 아니라이 링크를 조사 할 수 있습니다 : 여기
Singleton design pattern vs Singleton beans in Spring container

더 정교한 설명 :
https://springframework.guru/gang-of-four-design-patterns/prototype-pattern/