2010-01-24 13 views
5

Quiero crear algunos granos de primavera después del inicio en un patrón de fábrica. Por ejemplo, de vez en cuando tengo algo de trabajo que hacer y necesito crear un bean de tarea (que probablemente tenga dependientes en otros beans de primavera singleton) y ejecutarlo.Crear frijoles a pedido usando el muelle

Puede haber varios trabajos para ejecutar al mismo tiempo, por lo que cada tarea debe ser independiente (prototipo).

¿Hay algún patrón común que las personas usen para lograr esto?

Como lo veo, necesito interactuar con el contenedor/applicationContext de alguna manera, pero realmente no quiero dispersar las inyecciones de applicationContext/beanFactory y las llamadas a getBean ("...") en todas partes.

pensé en algo como esto (tenga en cuenta la "fábrica" ​​es algo que estoy imaginando, en lugar de algo que existe)

<bean id="myTask" class="MyTask" scope="prototype"> 
    <property name="entityManager" ref=".../> 
    ... 
</bean> 

<bean id="myTaskExecutor" class="MyTaskExecutor"> 
    <property name="taskFactory"> 
    <xxx:factory bean="myTask"/> 
    </property> 
</bean> 

Y luego el código

class MyTaskExecutor 
{ 
    private Factory<MyTask> taskFactory; 

    public void setTaskFactory(Factory<MyTask> taskFactory) 
    { 
    this.taskFactory = taskFactory; 
    } 
} 

Y tal vez una anotación versión

class MyTaskExecutor 
{ 
    @Factory(MyTask.class) 
    private Factory<MyTask> taskFactory; 

} 

¿Tal vez ya hay algo como lo anterior? O me estoy perdiendo algo fundamental en alguna parte.

Me doy cuenta de que podría tener un SingleTon MyTaskFactory y usarlo para crear instancias usando "nuevo", pero luego tendría que pasar todos sus dependientes de la fábrica lo cual parece estar mal.

Así que supongo que resumir la pregunta es

¿Cuál es la forma recomendada de crear prototipos de los granos de primavera bajo demanda desde el código de la aplicación?

Apreciar cualquier entrada.

Respuesta

4

Creo que está complicando demasiado el problema. Todo lo que necesitas hacer es escribir una clase TaskFactory (nada especial sobre eso, sin interfaces especiales o anotaciones). TaskFactory se inyectaría con todos los otros beans necesarios, y tendría un método createTask que crea las tareas bajo demanda, y que transfiere referencias a los beans Spring necesarios a la nueva tarea cuando se crea. El código del cliente se inyecta con TaskFactory, y llama al createTask cuando sea necesario.

Spring en sí mismo no proporciona soporte explícito para lo que estás tratando de hacer. Las características de los atributos XML factory-method y las interfaces FactoryBean solo son útiles para la creación única de un bean dentro de su alcance, y si desea crearlas bajo demanda, eso significa scope="prototype", y eso significa usar getBean().

edit: Probablemente valga la pena señalar que los granos de prototipo no son para lo que Spring está diseñado. Sí, los apoya, pero usarlos no es una experiencia muy edificante. Si realmente quiere ir por este camino, entonces vale taking a look at @Configurable. Es muy potente, pero no siempre adecuado, debido a las limitaciones del cargador de clases en tiempo de ejecución.

+1

Entiendo lo que dices, pero aún así no parece una gran solución (mencioné tener una fábrica arriba). Considere si MyTask tiene una dependencia en otros beans de ámbito prototipo, cada uno con sus propias dependencias. Tendría que fabricar todos los de la fábrica (e inyectar a sus dependientes en mi fábrica) y pasarlos a MyTask, o hacer que MyTask los cree, y tener el pase de fábrica en todos los demás dependientes del prototipo de frijol. Parece casi equivalente a no usar resortes para singletons, solo que en este caso es para prototipos de granos encuadrados. –

+0

ver la edición sobre '@ Configurable' – skaffman

0

Estoy tratando de hacer algo muy similar (Spring 3.0) a esto, así que estaría interesado en saber cómo terminó resolviendo este problema.

Mi enfoque actual es usar getBean() y he ido con el alcance singleton predeterminado con mis beans/pojos instalados por Spring. Por lo tanto, ahora tengo un código que no es seguro para subprocesos pero me gustaría mejorarlo para que sea seguro para subprocesos más adelante en la pista.

+0

Acabo de usar BeanFactoryAware en los beans relevantes y llamar a getBean() según sea necesario para fabricar mis prototipos de beans. Estoy seguro de que una solución de anotación es completamente factible, pero decidí que habría sido demasiado para mí, ya que solo necesitaba la funcionalidad en aproximadamente 5-10 lugares, de una aplicación muy grande. –

Cuestiones relacionadas