我很难搞清楚这一点,我首先会提到班级结构:
CarFactory类有一个返回Car的工厂方法。在Spring XML文件(test-spring.xml)中,bean定义如下所示:
<bean id="carDealer" class="...CarDealer>
<property name="car" ref="car"/>
</bean>
<bean id="carFactory" class="...CarFactory" />
<bean id="car" factory-bean="carFactory" factory-method="createCar" />
<bean id="tire" class="...Tire" />
工厂将返回RedCar或BlueCar,调用代码不知道哪一个。但是,让我们说这个例子,它返回RedCar。
在我正在测试RedCar的测试类中,它的设置如下:
@SuppressWarnings("PMD")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:test-spring.xml" })
public class RedCarTest {
@Autowired
Car redCar;
在RedCar类中,它具有Tire属性:
public RedCar implements Car {
@AutoWired
private Tire tire;
}
在测试示例中,这工作正常,从工厂返回的redCar初始化时也依赖于Tire初始化。问题是当我尝试从我的应用服务器运行它时。
在应用程序代码中,CarDealer类引用了Car:
public CarDealer {
private Car redCar;
}
当调用此代码时,将创建CarDealer(按弹簧)并创建Car(按弹簧),但Car的Tire属性为null。我不明白为什么在测试代码下创建了Tire属性,但是在应用程序中却没有。希望这比以前提出的问题更清晰。
答案 0 :(得分:1)
您是否尝试过使用 @Resource(name =“SomeRedProperty”)代替 @Autowired ?
答案 1 :(得分:0)
当工厂返回Car(“RedCar”)时,如何确保初始化从属属性。
@Autowired
不起作用,因为你的工厂类正在实例化bean本身,Spring只能在创建bean时自动连接依赖(并作用于注释)。
确保工厂返回的对象具有所有属性集的最简单方法是设置工厂类/方法中的所有属性。
实际上,工厂可能有一个SomeRedProperty
字段,用于将其传递给它创建的RedCar
。
答案 2 :(得分:0)
我同意@matt b,确保设置所有属性都可以在工厂内完成。但是,如果您确实希望Spring管理Blue和Red Car实例的依赖项,则可以按照以下步骤操作:
您的工厂必须实现Spring的`BeanFactoryAware'接口。从界面实现该方法后,Spring将提供对创建它的bean工厂的类访问。这基本上就是你的应用环境。
在上下文中连接您的红色和蓝色汽车。 (如果它们与工厂位于同一文件中,则无关紧要,只要所有xml都加载到上下文中)。如果您希望每次调用工厂方法以提供新的完全注入实例,请确保将红色和蓝色汽车bean标记为具有“原型”范围。
在您的工厂类中,实现setBeanFactory(BeanFactory beanFactory)
,只需保存对bean工厂的引用。
在您工厂的createCar
方法中,一旦您决定要返回哪辆车,请从Bean工厂查找相应的bean并返回给调用者。
希望这有帮助。