我们有自动装配特定类型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不会根据类型跟踪依赖性。
答案 0 :(得分:0)
您可以实施InitializingBean
。如果你这样做,Spring会在连接依赖后调用afterPropertiesSet()
。您可以添加任何特殊逻辑来覆盖这些依赖项。
答案 1 :(得分:0)
非常有趣的问题。最简单的方法:制作MyComponent
原型并在每次需要时创建新实例。这样,Spring将使用最新的IValidator
实例列表执行自动装配。考虑<lookup-method/>
。
不太优雅的方法是建立一个工厂(不一个FactoryBean
),它将根据需要检索实施IValidator
的所有bean,并且只要你在任何时候调用这个工厂需要它。当然,根本不是春天的精神。
其他方法更加麻烦且容易出错。您可以创建自己的后处理器,将新发现的IValidator
添加到需要所有类的列表的所有类中。您也可以开发自己的List<IValidator>
实现,每次请求时都会查找ApplicationContext
- 这有点挑战,特别是在考虑并发时。
最后有一个 Composite 设计模式:只有一个IValidator
会将所有调用委托给IValidator
中手动发现的目标ApplicationContext
列表