2012-09-06 17 views
6

Necesito poder agregar nuevos beans a un contexto web de primavera (en cualquier ámbito) para clases que podrían y no estar definidas en el classpath en tiempo de compilación.Adición de beans dinámicos al contexto web de primavera

Por ejemplo, podría crear algunas de estas clases dinámicamente y luego registrar un singleton o bean de sesión para esta clase.

He leído un poco sobre BeanFactoryPostProcessor, pero no estoy seguro de si funcionará en un contexto web, y si lo entiendo correctamente, solo funcionará antes de cargar las instancias de bean y no después, ¿o estoy equivocado?

No he podido encontrar información sobre cómo hacer esto en un AnnotationConfigWebApplicationContext, y al menos en mi prueba todos los beans que creo dinámicamente no se inyectan en otras instancias, e incluso si fueran solo veo el método para registrar beans Singleton pero no para otros ámbitos:

ctx.getBeanFactory().registerSingleton("dummy", dummy); 

PD

me encontré con esta pregunta: Dynamic creation of beans in Spring pero cuando intento agregar cualquier frijol, frijol o frijol definición constructor definición al contexto web así el frijol no quede cargado:

AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); 
ctx.setServletContext(servletContext); 
ctx.refresh(); 
// 
log.trace("Registering first test bean"); 
Test test = new Test(); 
test.setDummy("x1"); 
ctx.getBeanFactory().registerSingleton("myTestBean1", test);   

log.trace("Registering second test bean"); 
BeanDefinition testDef = new RootBeanDefinition(Test.class);   
testDef.setScope(BeanDefinition.SCOPE_SINGLETON);   
ctx.getBeanFactory().registerSingleton("myTestBean2", testDef); 

Test dummy1 = (Test)ctx.getBean("myTestBean1"); 
Object dummy2 = ctx.getBean("myTestBean2"); 

log.trace("beans: 1: {}; 2: {}", dummy1, dummy2); //<--this works, but... 
ctx.refresh(); 

ctx.register(MyConfig.class); //configuring other beans 

... Cuando hacerlo desde otro bean configurado dentro MyConfig.class o anotado con @Component (podría incluso ser también otro componente dinámico):

@Autowire Test myTestBean1; 
//Or this: 
Object a = this.ctx.getBean("myTestBean1"); //Or myTestBean2 

Se lanza una NoSuchBeanDefinitionException

Por favor, ¡ayúdenme! He estado buscando mucho y no he encontrado ninguna información útil, o tal vez tengo pero no puedo probar todo lo que encuentro en la web en tan poco tiempo y la documentación de primavera solo parece ser muy buena para casos normales y configuraciones xml, no por estas locuras que estoy tratando de hacer y no por la configuración programática.

+0

Me pregunto si se manejan de manera explícita los ciclos de vida de objeto en código Java no simplificar las cosas, gracias –

Respuesta

2

Lo que está buscando no se puede lograr, lo siento. El autocableado ocurre cuando un bean se crea inicialmente. En su caso, usted espera conectar un bean antes de agregarlo a la fábrica, lo que por supuesto no funcionará: Spring no realiza el viaje en el tiempo.

Lo que creo que buscas es el patrón de fábrica. En Spring, puede aplazar la instanciación de un bean a una fábrica que cree implementando el FactoryBean. Lee más aquí:

+0

pero en el ejemplo que crean el grano antes de Autowiring en otro frijol, edité la pregunta para ser más claro, aunque parece interesante ... voy a echar un vistazo a esto en caso de que necesite otro enfoque –

+0

@Lando En tu ejemplo, comienzas llamando 'ctx.refresh()' en línea dos, que construye toda la fábrica de frijoles y procesa todos los autowirin gs. Eso sucede antes de que hagas algo más. Independientemente, insertando manualmente frijoles en el tiempo de ejecución no es cómo debe funcionar Spring. Estoy seguro de que puedes lograr que funcione de alguna manera, pero no va a ser bonito. Si necesita retrasar/aplazar la creación de bean, debería trabajar con ámbitos y/o fábricas e interfaces. – pap

+0

Si no llamo actualizar antes, obtengo una IllegalStateException, verifico el código y valida que la fábrica no es nula al registrar nuevos singletons. El problema con las fábricas es que todavía necesitaría tener el nombre del bean definido para que la primavera delegue la creación en la fábrica. Me estoy quedando sin ideas :( –

Cuestiones relacionadas