2010-05-13 12 views
8

Me gustaría utilizar FactoryBeans y ámbitos juntos. Específicamente, me gustaría que el objeto creado y devuelto por un FactoryBean se coloque en un ámbito especificado (quizás personalizado). La cuestión es que haciendo lo siguiente:Spring FactoryBean y ámbitos trabajando juntos

<bean class="x.y.z.TestFactoryBean" scope="test" /> 

Resultados de la FactoryBean sí están con ámbito, y tiene un comportamiento algo impredecible en el objeto creado por la fábrica. Entiendo por qué es esto; la fábrica en sí es un frijol manejado por la primavera de primera clase y tiene su propio ciclo de vida. Sin embargo, no puedo encontrar una forma de especificar que el objeto devuelto por la fábrica debe tener un alcance propio.

Por otro lado, esto hace exactamente lo que yo quiero (siempre y cuando TestFactoryBean no implementa la interfaz FactoryBean):

<bean class="x.y.z.TestFactoryBean" name="testFactory"> 
<bean class="x.y.z.TestBean" factory-bean="testFactory" 
     factory-method="getObject" scope="test" /> 

Así que la verdadera pregunta es, ¿cómo puedo hacer que la primavera se comporta como lo hace para el segundo ejemplo anterior, pero usando FactoryBeans reales?

Respuesta

6

No puede usar fácilmente un ámbito personalizado en un bean devuelto desde FactoryBean.

De Java documentation de primavera:

FactoryBeans pueden apoyar únicos y prototipos

Si desea que los FactoryBean 's devuelto frijol tener el alcance prototipo, entonces debe implementar el método isSingleton() como esto :

public class TestFactoryBean implements FactoryBean<TestBean> { 

    // the rest of the required methods are removed for simplicity reasons.. 

    public boolean isSingleton() { 
     return false; 
    } 
} 

Para admitir un ámbito personalizado, tiene para implementar la lógica usted mismo y no será muy intuitivo, ya que el FactoryBean solo proporciona el método isSingleton(). Prefiero recomendar el uso de otra solución que FactoryBean para beans con alcance personalizado.

Espero que esto ayude!

+1

puede personalizar casi todo en primavera, así que supongo que es posible de alguna manera, pero probablemente involucre una excavación muy profunda (usando un contexto de aplicación personalizado) o algo así. pero supongo que aquí –

+0

Acepto y he actualizado mi respuesta. – Espen

2

Resolví el mismo problema usando un soporte de soporte personalizado.

grano de fábrica:

@Component 
@Configurable() 
public class EventBusFactory implements FactoryBean<EventBus> { 
    @Override 
    public EventBus getObject() throws Exception { 
     return new SimpleEventBus(); 
    } 

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

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

frijol titular:

@Configurable 
@Component 
@Scope("session") 
public class EventBusHolder { 

    @Autowired 
    private EventBus eventBus; 

    public EventBus getEventBus() { 
     return eventBus; 
    } 

    public void setEventBus(EventBus eventBus) { 
     this.eventBus = eventBus; 
    } 
} 

Y luego utilizo titular en lugar de la entidad requerida.

@Component 
@Configurable 
@Scope("session") 
public class UicPlaceController extends PlaceController { 

    @Autowired 
    public UicPlaceController(EventBusHolder eventBus) { 
     super(eventBus.getEventBus()); 
    } 
    ... 
} 

La solución parece un poco fea, pero aún así, resuelve el problema.

+0

Supongo que este trabajo con Holder se puede mejorar, pero por ahora me funciona. – uthark

Cuestiones relacionadas