Java 以编程方式将Bean添加到SpringWeb应用程序上下文
由于插件体系结构,我试图以编程方式将bean添加到我的webapp中。我有一个通过Java 以编程方式将Bean添加到SpringWeb应用程序上下文,java,spring,web-applications,dynamic,Java,Spring,Web Applications,Dynamic,由于插件体系结构,我试图以编程方式将bean添加到我的webapp中。我有一个通过@组件注释创建的Springbean,我正在实现ApplicationContextAware接口 我的覆盖函数如下所示: @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // this fails this.appl
@组件
注释创建的Springbean,我正在实现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);
}
@覆盖
公共无效后处理BeanDefinitionRegistry(BeanDefinitionRegistry bdr)
抛出BeansException{
BeanDefinition定义=新根BeanDefinition(
(类别),;
bdr.registerBeanDefinition(“,定义);
}
在Spring3.0中,您可以通过BeanDefinitionRegistry
实现bean并添加新bean
在Spring的早期版本中,您可以在
BeanFactoryPostProcessor
中执行相同的操作(尽管您需要将BeanFactory
强制转换为BeanDefinitionRegistry
,这可能会失败)。为什么需要它的类型为GenericWebApplicationContext
?我认为您可能可以使用任何ApplicationContext类型 通常您会使用init方法(除了setter方法之外): 你可以用这两种方法中的任何一种 或 以下是一个简单的代码:
ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
beanFactory.registerSingleton(bean.getClass().getCanonicalName(), bean);
实际上,
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
)
首先初始化属性值
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);
添加到bean列表中
ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
beanFactory.registerSingleton("beanName", context.getBean("beanName"));
非常感谢。我想最难的部分是知道要查找什么。请注意,根据:
BeanFactoryPostProcessor可以与bean定义交互和修改,但不能与bean实例交互。这样做可能会导致过早的bean实例化,违反容器并导致意外的副作用。如果需要bean实例交互,请考虑实现BeaPo后继处理器。假设我写了这门课。接下来呢?如何激活它?你能告诉我更多答案吗?当我这样做时,它不会将它们添加到ApplicationContext中
Vertx vertx = ...; // either create or for vertx, it'll be passed to main verticle
ApplicationContext context = new CustomAnnotationApplicationContextProvider(vertx).get(ApplicationSpringConfig.class);
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"));