我有一个实现W接口的B类。它有W方法的默认实现。类C和D覆盖默认实现,它们需要一个服务,其bean由spring实例化。字符串a和b来自用户,因此我无法提前创建B / C / D的bean。所以我有一个工厂,它根据用户参数创建一个新对象(它将根据参数创建B / C / D)。有什么干净的方法我可以使用C和D内部的服务bean(aa / bb / cc / dd等)(服务器启动期间的弹簧自动装配,此时实例化B / C / D所需的参数不可用)或有没有更好的方法来解决这个问题?
Class B implements W{
String a;
String b;
B (String a, String b);
w_method(){
}
}
Class C extends B {
@Autowired
Service aa;
@Autowired
Service bb;
@Autowired
Service cc;
@override
w_method(){
}
}
Class D extends B {
@Autowired
Service dd;
@override
w_method(){
}
}
答案 0 :(得分:7)
有三种可能的方法:
构造函数参数来自用户的事实并不意味着Spring无法创建这些对象。
您可以将它们声明为范围prototype
的Spring bean,并在您的工厂中执行以下操作:
public C createC(String a, String b) {
return applicationContext.getBean("c", a, b);
}
此方法的缺点是您的工厂取决于ApplicationContext
。
您可以使用@Configurable
注释这些类并启用AspectJ编织。在这种情况下,Spring将配置这些类的对象,即使您使用new
创建它们也是如此。请参阅7.8.1 Using AspectJ to dependency inject domain objects with Spring。
您可以手动触发自动装配
applicationContext.getAutowireCapableBeanFactory().autowireBean(...);
当您无法控制需要自动装配的对象(servlet等)时,此方法很有用。
答案 1 :(得分:6)
我认为最简单的方法是将服务连接到工厂并在返回之前调用B / C / D对象上的setter,而不是尝试使用@Autowired
。
或者使用axtavt的构造函数参数方法。如果您想避免依赖ApplicationContext
,可以使用Lookup Method Injection,但是您必须根据此博客帖子修补Spring:http://nurkiewicz.blogspot.co.uk/2010/08/creating-prototype-spring-beans-on.html