以编程方式将Bean添加到Spring Web App上下文

时间:2010-12-27 18:04:41

标签: java spring web-applications dynamic

由于插件架构,我正在尝试以编程方式将bean添加到我的webapp中。我有一个通过@Component注释创建的Spring bean,我正在实现ApplicationContextAware接口。

我的覆盖功能如下所示:

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

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

基本上,我无法弄清楚如何将bean添加到setApplicationContext的applicationContext对象中。任何人都可以告诉我,我的方式是错误的吗?

好的,这就是我最终得到的解决方案:

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

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

5 个答案:

答案 0 :(得分:39)

在Spring 3.0中,您可以创建bean实现BeanDefinitionRegistryPostProcessor并通过BeanDefinitionRegistry添加新bean。

在以前的Spring版本中,您可以在BeanFactoryPostProcessor中执行相同的操作(尽管您需要将BeanFactory转换为BeanDefinitionRegistry,这可能会失败)。

答案 1 :(得分:34)

这是一个简单的代码:

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

答案 2 :(得分:9)

为什么需要它为GenericWebApplicationContext类型?
我认为您可以使用任何ApplicationContext类型。

通常你会使用init方法(除了你的setter方法):

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

你可以使用

连接bean

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

AutowireCapableBeanFactory.initializeBean(Object existingbean, String beanName)

答案 3 :(得分:1)

实际上<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <section id="solBlocks"> <div class="solutionBlock"> <div class="overlay"></div> <img src="http://via.placeholder.com/300" alt="A"> <div class="total-center front"> <h2 class="sBlockTitle">A</h2> </div> </div><div class="solutionBlock"> <div class="overlay"></div> <img src="http://via.placeholder.com/300" alt="B"> <div class="total-center front"> <h2 class="sBlockTitle">B</h2> </div> </div><div class="solutionBlock"> <div class="overlay"></div> <img src="http://via.placeholder.com/300" alt="C"> <div class="total-center front"> <h2 class="sBlockTitle">C</h2> </div> </div> </section>来自AnnotationConfigApplicationContext,其中有AbstractApplicationContext方法留空以进行覆盖

postProcessBeanFactory

要利用此功能,请创建/** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for registering special * BeanPostProcessors etc in certain ApplicationContext implementations. * @param beanFactory the bean factory used by the application context */ protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { } 类,其类似于以下内容(针对AnnotationConfigApplicationContextProvider实例示例,您可以使用Vertx代替...)

MyClass

创建public class CustomAnnotationApplicationContextProvider { private final Vertx vertx; public CustomAnnotationApplicationContextProvider(Vertx vertx) { this.vertx = vertx; } /** * Register all beans to spring bean factory * * @param beanFactory, spring bean factory to register your instances */ private void configureBeans(ConfigurableListableBeanFactory beanFactory) { beanFactory.registerSingleton("vertx", vertx); } /** * Proxy method to create {@link AnnotationConfigApplicationContext} instance with no params * * @return {@link AnnotationConfigApplicationContext} instance */ public AnnotationConfigApplicationContext get() { return new AnnotationConfigApplicationContext() { @Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.postProcessBeanFactory(beanFactory); configureBeans(beanFactory); } }; } /** * Proxy method to call {@link AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(DefaultListableBeanFactory)} with our logic * * @param beanFactory bean factory for spring * @return * @see AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(DefaultListableBeanFactory) */ public AnnotationConfigApplicationContext get(DefaultListableBeanFactory beanFactory) { return new AnnotationConfigApplicationContext(beanFactory) { @Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.postProcessBeanFactory(beanFactory); configureBeans(beanFactory); } }; } /** * Proxy method to call {@link AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class[])} with our logic * * @param annotatedClasses, set of annotated classes for spring * @return * @see AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class[]) */ public AnnotationConfigApplicationContext get(Class<?>... annotatedClasses) { return new AnnotationConfigApplicationContext(annotatedClasses) { @Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.postProcessBeanFactory(beanFactory); configureBeans(beanFactory); } }; } /** * proxy method to call {@link AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(String...)} with our logic * * @param basePackages set of base packages for spring * @return * @see AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(String...) */ public AnnotationConfigApplicationContext get(String... basePackages) { return new AnnotationConfigApplicationContext(basePackages) { @Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.postProcessBeanFactory(beanFactory); configureBeans(beanFactory); } }; } } 时,您可以使用

创建它
ApplicationContext

答案 4 :(得分:0)

首先初始化属性值

MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();
mutablePropertyValues.add("hostName", details.getHostName());
mutablePropertyValues.add("port", details.getPort());

DefaultListableBeanFactory context = new DefaultListableBeanFactory();
GenericBeanDefinition connectionFactory = new GenericBeanDefinition();
connectionFactory.setBeanClass(Class);
connectionFactory.setPropertyValues(mutablePropertyValues);

context.registerBeanDefinition("beanName", connectionFactory);

添加到豆子列表中

ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
beanFactory.registerSingleton("beanName", context.getBean("beanName"));