由于插件架构,我正在尝试以编程方式将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);
}
答案 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"));