2010-12-27 24 views
41

Debido a una arquitectura de complemento, intento agregar un bean programáticamente a mi aplicación web. Tengo un Spring Bean creado a través de la anotación @Component, y estoy implementando la interfaz ApplicationContextAware.Agregar bean mediante programación al contexto de la aplicación web de Spring

Mi función de anulación se ve así:

@Override 
public void setApplicationContext(ApplicationContext applicationContext) 
     throws BeansException { 

    // this fails 
    this.applicationContext = (GenericWebApplicationContext) applicationContext; 
} 

Básicamente, no puedo encontrar la manera de añadir un grano al objeto applicationContext dado a setApplicationContext. ¿Alguien puede decirme cómo voy sobre esto de la manera incorrecta?

Ok, esto es lo que terminó con la solución:

@Override 
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry bdr) 
     throws BeansException { 
    BeanDefinition definition = new RootBeanDefinition(
      <My Class>.class); 

    bdr.registerBeanDefinition("<my id>", definition); 
} 

Respuesta

34

En Spring 3.0 puede hacer su grano de implementar BeanDefinitionRegistryPostProcessor y añadir nuevos granos a través de BeanDefinitionRegistry.

En versiones anteriores de Spring, puede hacer lo mismo en BeanFactoryPostProcessor (aunque necesita convertir BeanFactory en BeanDefinitionRegistry, que puede fallar).

+7

gracias. Supongo que la parte más difícil es saber qué buscar. – user146714

+1

Por favor, tenga cuidado de que según [JavaDoc] (http://static.springsource.org/spring/docs/3.0.x/javadoc-api/index.html?org/springframework/beans/factory/config/BeanPostProcessor.html): 'Un BeanFactoryPostProcessor puede interactuar con y modificar las definiciones de bean, pero nunca las instancias de bean. Si lo hace, puede causar una instanciación de frijol prematura, violando el contenedor y causando efectos secundarios no deseados. Si se requiere una interacción de instancia de bean, considere implementar BeanPostProcessor en su lugar. – dgiffone

+0

¿Qué hacer con 'BeanDefinitionRegistryPostProcessor'? Supongamos que escribí esta clase. ¿Qué sigue? ¿Cómo activarlo? – Dims

8

¿Por qué necesita que sea del tipo GenericWebApplicationContext?
Creo que probablemente puedas trabajar con cualquier tipo de ApplicationContext.

Por lo general, se utilizaría un método init (además de su método setter):

@PostConstruct 
public void init(){ 
    AutowireCapableBeanFactory bf = this.applicationContext 
     .getAutowireCapableBeanFactory(); 
    // wire stuff here 
} 

y que le cablear las habas estén utilizando

AutowireCapableBeanFactory.autowire(Class, int mode, boolean dependencyInject)

o

AutowireCapableBeanFactory.initializeBean(Object existingbean, String beanName)

28

Aquí hay un código simple:

ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory(); 
beanFactory.registerSingleton(bean.getClass().getCanonicalName(), bean); 
Cuestiones relacionadas