복붙노트

[SPRING] 싱글 톤 빈과 의존성 주입과 결합 된 스프링 프로토 타입 빈. 구성 만하는 접근 방식이 있습니까?

SPRING

싱글 톤 빈과 의존성 주입과 결합 된 스프링 프로토 타입 빈. 구성 만하는 접근 방식이 있습니까?

나는 함수의 각 호출마다 다른 (새로운) 프로토 타입 빈에 대한 참조를 리턴하는 데 필요한 싱글 톤 빈을 가지고있다. 이 작업을 수행하는 유일한 방법은 getBean () 메소드를 호출하여 BeanFactory / ApplicatioContext에서 새로운 프로토 타입 bean 인스턴스를 프로그래밍 방식으로 검색하는 것이다. 코드 샘플이 따라옵니다 ...

이 작업을 수행하는 더 좋은 방법이 있습니까? 구성을 통해서만, 잘하면? (개인적으로 나는 의심 스럽다 ...)

<bean id="protoBean" scope="prototype"
        class="com.blahblah.ProtoBean" />

<bean id="singletonBean"
        class="com.blahblah.SingletonBean" />

public class ProtoBean {

    ....
}

public class SingletonBean {

    private BeanFactory factory;

    public ProtoBean dispense() {
        return (ProtoBean) factory.getBean("protoBean");
    }

    ....
}

해결법

  1. ==============================

    1.방법 주입을 한번보세요.

    방법 주입을 한번보세요.

  2. ==============================

    2.Spring 3.0부터 적절한 범위의 의존성 주입을 위해 를 사용할 수있다. 그 뒤에는 Spring이 프록시 객체를 삽입하고 올바른 범위 컨텍스트를 찾는 역할을합니다. 프로토 타입, 세션 또는 요청 등이 될 수 있습니다. 여기의 공식 문서를 참조하십시오.

    Spring 3.0부터 적절한 범위의 의존성 주입을 위해 를 사용할 수있다. 그 뒤에는 Spring이 프록시 객체를 삽입하고 올바른 범위 컨텍스트를 찾는 역할을합니다. 프로토 타입, 세션 또는 요청 등이 될 수 있습니다. 여기의 공식 문서를 참조하십시오.

    삶의 편의성을 높이기 위해 Spring은 @Scope에 proxyMode 속성도 도입 했으므로 XML 선언에만 국한되지 않습니다. 예 :

    @Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
    

    삽입 된 빈이 다른 사람들에게 getClass ()와 캐스팅이 예상 결과를 제공하지 않을 수도 있음을 경고하는 프록시임을 분명하게 문서화해야한다. 또한, 프록시 클래스의 equals () 및 hashCode ()가 클래스 변수에 직접 액세스하지 않고 액세스 메소드를 사용하는지 확인하십시오.

  3. ==============================

    3.메소드 삽입을 사용하면 singleton-bean 클래스가 단위 테스트하기가 어렵습니다. 종속성을 제공하는 메소드를 구현하려면 서브 클래스를 만들어야합니다. 또한 직접 인스턴스화 할 수 없기 때문에 재사용 성이 떨어 지므로 Spring을 사용하지 않고이 클래스를 사용하려는 경우 빈을 반환하는 메소드를 하위 클래스로 제공해야합니다.

    메소드 삽입을 사용하면 singleton-bean 클래스가 단위 테스트하기가 어렵습니다. 종속성을 제공하는 메소드를 구현하려면 서브 클래스를 만들어야합니다. 또한 직접 인스턴스화 할 수 없기 때문에 재사용 성이 떨어 지므로 Spring을 사용하지 않고이 클래스를 사용하려는 경우 빈을 반환하는 메소드를 하위 클래스로 제공해야합니다.

    더 나은 접근법 IMHO는 다음과 같이 프록시, 프로토 타입 타겟 소스 및 프로토 타입 타겟 빈을 사용합니다. 이러한 싱글 톤 빈 클래스는 단위 테스트가 가능하고 재사용이 용이합니다.

    <bean id="targetPooledObject" class="pool.PooledObject" scope="prototype">
        <constructor-arg value="42" />
    </bean>
    
    <bean id="prototypeTargetSource" class="org.springframework.aop.target.PrototypeTargetSource">
        <property name="targetBeanName" value="targetPooledObject" />
    </bean>
    
    <bean id="pooledObject" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="targetSource" ref="prototypeTargetSource" />           
    </bean>
    
    <bean id="poolConsumer" class="pool.PoolConsumer">
        <property name="pooledObject" ref="pooledObject" />
    </bean>
    

    이제 우리는 pooledObject를 singleton bean (위에 표시된 poolConsumer)에 삽입 할 수 있습니다. 그리고 우리가 그 singleton bean에 대해 수행하는 모든 메소드 호출 (예 : pooledObject.foo ()를 호출 할 때마다 poolConsumer.callPooledObjectMethod ()를 호출 할 때) 우리는 새로운 PooledObject bean을 얻는다.

    다음은 해당 코드입니다.

    public class PooledObject 
    {
        private int x;
    
        public PooledObject(int x)
        {
            this.x = x;
        }
    
        public void foo()
        {
            System.out.println("foo called");
        }
    }
    
    public class PoolConsumer
    {
        private PooledObject pooledObject;
    
        public PooledObject getPooledObject() 
        {
            return pooledObject;
        }
    
        public void setPooledObject(PooledObject pooledObject) 
        {
            this.pooledObject = pooledObject;
        }
    
        public void callPooledObjectMethod()
        {
            pooledObject.foo();
        }
    }
    
  4. from https://stackoverflow.com/questions/829463/spring-prototype-beans-in-combination-with-singleton-beans-and-dependency-inject by cc-by-sa and MIT license