如何在插入新bean时更新现有的自动装配属性?

时间:2011-05-02 21:12:27

标签: java spring groovy

我们有自动装配特定类型bean的组件类:

@Component
public class MyComponent {
    @Autowire
    public IValidators[] validators;
}

我们的应用程序允许创建在运行时编译的Groovy类,并使用ScriptFactoryPostProcessor在Spring中注册:

ConstructorArgumentValues args = new ConstructorArgumentValues();
args.addGenericArgumentValue(groovySourceLocation); //location is on the file system
RootBeanDefinition def = new RootBeanDefinition(GroovyScriptFactory.class, args, null);
BeanDefinitionRegistry r = (BeanDefinitionRegistry) this.applicationContext.getBeanFactory();
r.registerBeanDefinition(beanName, def); //beanName is the same as the class name

//scriptFactoryPostProcessor is autowired into class from applicationConfig
scriptFactoryPostProcessor.postProcessBeforeInstantiation(GroovyScriptFactory.class, beanName);

groovy bean是正确创建的,因为我可以通过bean名称或类型从applicationContext中检索它。但是已经自动装配的组件属性没有添加的bean。当groovy类实现IValidator时,我希望使用添加到集合中的新groovy bean来更新自动装载IValidator类型的任何组件类。我该怎么做?

更新

在查看源代码后,我不认为Spring支持我的期望。我最后的希望是我可以要求一个类型的依赖bean(类似于getDependentBeans(String beanName)),但它不存在,从外观上看,Spring不会根据类型跟踪依赖性。

2 个答案:

答案 0 :(得分:0)

您可以实施InitializingBean。如果你这样做,Spring会在连接依赖后调用afterPropertiesSet()。您可以添加任何特殊逻辑来覆盖这些依赖项。

http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/beans/factory/InitializingBean.html#afterPropertiesSet()

答案 1 :(得分:0)

非常有趣的问题。最简单的方法:制作MyComponent原型并在每次需要时创建新实例。这样,Spring将使用最新的IValidator实例列表执行自动装配。考虑<lookup-method/>

不太优雅的方法是建立一个工厂(一个FactoryBean),它将根据需要检索实施IValidator的所有bean,并且只要你在任何时候调用这个工厂需要它。当然,根本不是春天的精神。

其他方法更加麻烦且容易出错。您可以创建自己的后处理器,将新发现的IValidator添加到需要所有类的列表的所有类中。您也可以开发自己的List<IValidator>实现,每次请求时都会查找ApplicationContext - 这有点挑战,特别是在考虑并发时。

最后有一个 Composite 设计模式:只有一个IValidator会将所有调用委托给IValidator中手动发现的目标ApplicationContext列表