2012-10-23 6 views
4

특정 메소드가 실행될 때마다 또 다른 bean의 신선한 인스턴스를 필요로하는 singleton Spring bean을가집니다.Spring에서 Factory + AOP를 얻는 방법

지금까지 나는 다음과 같은 방법 바라 보았다 :

  • 단지 새로운 사용하여 X를 만듭니다. 이것은 잠시 동안 작동했지만 지금은 X 용 스프링 AOP 기능이 필요하므로 결과 인스턴스가 스프링 관리되지 않기 때문에 더 이상 작동하지 않습니다.

  • FactoryBean을 종속성으로 생각했지만 FactoryBean에서 첫 번째 인스턴스를 충족시키지 않는 단일 X 인스턴스 만 가져옵니다.

  • 현재 계획은 스프링 컨텍스트에서 X를 수동으로 찾아서 프로토 타입 종속성을 사용하여이를 선언하는 것입니다. 이것은 효과가 있지만, 나는 그것이 정말로 추악하다고 생각합니다.

=> 나는 그것의 팩토리 메소드 I 적절하고 스프링이 그것의 인스턴스를 관리 점점 볼 수있는 시간을 호출 할 수 있도록 내 콩에 공장을 주입 할 수있는 방법.

답변

12

이와 같은 시나리오에서 선택하는 방법은 lookup method injection입니다.간단히 말해, 이것은 bean 메소드에 대한 호출 방식을 사용하여 새로운 빈 인스턴스가 생성됩니다.

abstract class MyClient implements Client { 

    void businessMethod(…) { 

    Dependency dependency = getDependencyInstance(); 
    … 
    } 

    abstract Dependency getDependencyInstance(); 
} 

는 이제 가서 종속성에 대한 프로토 타입 bean 정의 구성 :뿐만 아니라

<bean id="dependency" class="….DependencyImpl" scope="prototype" /> 

을 당신은 결국 의존성 인스턴스를 제공합니다 추상적 인 방법으로 클래스를 생성하여 시작 했죠 lookup-method 요소를 사용하여 클라이언트는 항상 각 메서드 호출에 대한 종속성의 새로운 인스턴스를 얻을 같이

<bean class="….MyClient"> 
    <lookup-method name="getDependencyInstance" bean="dependency" /> 
</bean> 

이는 원인이됩니다 MyClient에 대해 CGLib 프록시를 만들고 getDependencyInstance(…)의 메소드 선언을 TargetSource으로 백업하고 BeanFactory을 참조하고 조회 할 Bean의 이름을 지정합니다. 각 메소드 호출시 bean 조회가 트리거되고 프로토 타입 구성된 Bean의 새로운 인스턴스가 리턴됩니다.

+0

나는이 기술을 내 코드에서 사용한다. 그것은 꽤 잘 작동합니다. 유일한 단점은 추상 클래스를 포함하는 클래스가 추상 클래스이므로 다른 인터페이스에서 선언 된 메소드를 작성하기 위해 IDE에서 제공 할 수있는 지원 량이 줄어 듭니다. –

2

나는 공장 콩의 문제가 표시되지 않습니다 그리고 난과 같이 그것을 할 것 :

import org.springframework.beans.factory.FactoryBean; 
import org.springframework.stereotype.Component; 

@Component 
public class X { 
    public static class XFactory implements FactoryBean<X> { 

     @Override 
     public X getObject() throws Exception { 
      return new X(); 
     } 

     @Override 
     public Class<?> getObjectType() { 
      return X.class; 
     } 

     @Override 
     public boolean isSingleton() { 
      return false; 
     }  
    } 
} 

을이 공장 빈을 주입. 그 봄이 항상 싱글에 새로운 인스턴스를 반환하는 프록시를 생성하므로

그렇지 않으면 당신은 범위

@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) 

와 X 콩 당신이 아닌 기본 프록시 모드를 사용해야 할 수 있습니다.

그렇게처럼보다 XML의 설정에 경우 :

<bean id="x" class="X" scope="prototype"> 
<aop:scoped-proxy> 
</bean> 

재밌게.

편집 :

당신이 @Component를 통해 공장에 주석을

이 (내가 위를 추가 한), #isSingleton에서 false를 반환하고 두 번 당신과 함께 공장 빈을 주입 할 수있는 X를 반환하지 않는 확인 @ 당신의 싱글 톤에 호소했습니다.

그렇지 않으면 난 그냥

예상대로 작동
import org.springframework.context.annotation.Scope; 
import org.springframework.context.annotation.ScopedProxyMode; 
import org.springframework.stereotype.Component; 

@Component 
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS) 
public class X { 
} 

을 확인했습니다.

편집 2 :

당신이 공장 빈을 주입하고 싶지만 당신이 범위 귀하의 공장을 프로토 타이핑 할 수있는 의존성을 주입하지 않으려면 (@Scope (프록시 모드 = ScopedProxyMode.TARGET_CLASS, 값 = "프로토 타입"))하지만 새로운 팩토리가 X가 관련 될 때마다 만들어지기 때문에 아마도 당신이 원하는 것이 아닐 것입니다.

공장 자체에 주사를 넣지 않으려면 Olivers 조회 방법을 사용하십시오.

+0

하지만 종속성 clas A에서 단일 X 인스턴스를 얻을 수 없습니까? 필자가 FactoryBean을 삽입하면 FactoryBean 자체가 아닌 FactoryBean의 type 매개 변수 인스턴스 만 가져옵니다. –

+0

네가 맞다면 애플리케이션 컨텍스트에서 다른 하나를 요청하면 bean의 다른 인스턴스 만 가져올 것이므로 factory를 만들어서 ApplicationContextAware를 구현하고 getX() 메소드를 제공한다. applicationcontext.getbean (X.class)를 호출하고 X를 프로토 타입으로 선언합니다. 또는 그 라인을 따라 무엇인가 –

+0

Jens : 다른 bean과 마찬가지로 factory bean을 삽입하고 직접 메소드를 호출 할 수 있습니다. –

관련 문제