【问题标题】:How to programmatically create bean definition with injected properties?如何以编程方式创建具有注入属性的 bean 定义?
【发布时间】:2011-03-23 03:50:29
【问题描述】:

我想以编程方式将 bean 定义添加到应用程序上下文,但该定义的某些属性是该上下文中的其他 bean(我知道它们的名称)。我该怎么做才能注入这些属性?

例如:

GenericBeanDefinition beanDef = new GenericBeanDefinition();
beanDef.setBeanClass(beanClass);

MutablePropertyValues values = new MutablePropertyValues();
values.addPropertyValue("intProperty", 10);
values.addPropertyValue("stringProperty", "Hello, world");
values.addPropertyValue("beanProperty", /* What should be here? */);

beanDef.setPropertyValues(values);

我正在使用 Spring 3.0。

【问题讨论】:

  • 你能详细说明一下这个问题吗?没看懂

标签: java spring dynamic dependency-injection


【解决方案1】:

你可以:

【讨论】:

  • 我不能使用 Javaconfig,因为我需要动态创建这些定义。如何使用BeanDefinitionParser
  • javaconfig 在所有情况下都可以正常工作。查看 BeanDefinitionParser 的一些实现以了解它们是如何工作的。 (检查弹簧来源)
【解决方案2】:

我找到了解决方案。我必须使用另一个 BeanDefinition 作为属性,如下所示:

GenericBeanDefinition bd2 = new GenericBeanDefinition();
bd2.setBeanClass(Dependency.class);

GenericBeanDefinition bd1 = new GenericBeanDefinition();
bd1.setBeanClass(Component.class);

MutablePropertyValues values = new MutablePropertyValues();
values.addPropertyValue("dependency", bd2);

bd1.setPropertyValues(values);

【讨论】:

  • 您好,但是您最终如何将 GenericBeanDefinition 添加到容器中?
【解决方案3】:

使用RuntimeBeanReference:

values.addPropertyValue("beanProperty", new RuntimeBeanReference("beanName")); 

【讨论】:

  • 使用 BeanDefinition 作为属性有什么不同吗?
  • @Shooshpanchick: BeanDefinition 创建指定类的新内部 bean,而 RuntimeBeanReference 创建对现有类的引用。
【解决方案4】:

我会添加一个像这样可以访问 applicationContext 的 bean:

public class AppContextExtendingBean implements ApplicationContextAware{


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

        AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();

        // do it like this
        version1(beanFactory);

        // or like this
        version2(beanFactory);

    }

    // let spring create a new bean and then manipulate it (works only for singleton beans, obviously) 
    private void version1(AutowireCapableBeanFactory beanFactory){
        MyObject newBean = (MyObject) beanFactory.createBean(MyObject.class,AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
        newBean.setBar("baz");
        newBean.setFoo("foo");
        newBean.setPhleem("phleem");
        beanFactory.initializeBean(newBean, "bean1");
    }

    // create the object manually and then inject it into the spring context
    private void version2(AutowireCapableBeanFactory beanFactory){
        MyObject myObject=new MyObject("foo","phleem");
        myObject.setBar("baz");
        beanFactory.autowireBean(myObject);
        beanFactory.initializeBean(myObject, "bean2");
    }


}

【讨论】:

  • 嗨,经过大量研究后,我找到了您的帖子,并且效果很好。我正在使用版本 2。但请告诉我:使用 AutowireCapableBeanFactory 会导致内存泄漏或性能下降吗?谢谢。
  • 这个解决方案似乎很好。 MyObject 似乎是一个原型 bean(因为我们每次都是从自己创建对象)。我们是否需要提供任何类型的注释,如@Component 或@Scope? spring 如何决定创建它的作用域?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
  • 2022-07-11
  • 1970-01-01
相关资源
最近更新 更多