我有以下设置:
<bean id="b1" class="SomeClass">
<property name="foo" ref="foo1"/>
</bean>
<bean id="b2" class="SomeClass">
<property name="foo" ref="foo2"/>
</bean>
<bean id="foo1" class="FooClass">
<constructor-arg index="0"><ref bean="dataSource1"/></constructor-arg>
...other constructor args
</bean>
<bean id="foo2" class="FooClass">
<constructor-arg index="0"><ref bean="dataSource2"/></constructor-arg>
...other constructor args
</bean>
有没有办法可以避免重复FooClass?我想在bean b1和b2中做的是添加对FooClass的引用,但指定数据源所有其他构造函数参数都是相同的。
由于
吉姆
答案 0 :(得分:1)
如果您希望在每次调用相应的getter时动态初始化/填充您的类的某个成员,您可以尝试查找方法注入。阅读第3.3.4.1页here。
因此,即使每次访问分配了查找方法的字段时,包含动态成员的类都是在scope = singletone(spring bean容器的缺省值)中创建的,您将获得一个适当的对象。在查找方法中实现的业务逻辑。
另外,我在Spring文档中发现了一个很好的example - 我认为非常清楚。看看“3.4.6.1查找方法注入”
答案 1 :(得分:1)
你在这里做的是,使用constructure自动装配类,如aviad所说,你可以使用setter和getter方法进行数据源注入
<bean id="foo" class="FooClass">
<constructor-arg index="0">datasource</constructor-arg>
...other constructor args
</bean>
<bean>your datasource bean1</bean>
<bean>your datasource bean2</bean>
在您的实施中,您可以将数据源设置如下
@Autowire
private FooClass foo;
foo.setDataSource(datasourcebean1);
你fooClass
public void FooClass(Datasource datasource){
private Datasource datasource;
public void setDatSource(Datasource datasource);
public Datasource getDataSource();
}
编辑 - 根据spring文档,如果它的值没有变化,你可以传递构造函数参数。但是对于FooClass,你希望在不同的场合传递不同的数据源(希望我能正确理解),所以在这种情况下你需要在spring初始化期间传递datasouce实例数据源1或数据源2,因为spring会期望构造函数参数在初始化FooClass时。稍后在运行时传递不同的数据源并使用setter方法设置数据源。
bean spring config
<bean id="foo" class="FooClass">
<constructor-arg index="0" ref="datasource1"></constructor-arg>
...other constructor args
</bean>
public class FooClass(){
// on spring initialization, it will inject datasource1
public void FooClass(DataSource dataSource){
}
have your setter and getter method for datasource
}
您的通话服务中的位置
public class dataBaseInvoke(){
public Datasource datasource2
public FooClass fooClass;
inside method{
fooClass.setDatasource(datasource2);
fooClass.addFoo();
}
}
答案 2 :(得分:0)
使用抽象bean
<bean id="foo" class="FooClass">
// Set all properties except datasoure
<property name="..." />
</bean>
<bean id="foo1" parent="foo">
<property name="datasource" ref="ds1" />
</bean>
<bean id="foo2" parent="foo">
<property name="datasource" ref="ds2" />
</bean>
当然,您必须使用空的构造函数实例化,并使用访问器公开FooClass属性。如果您在其他地方不需要foo1
和foo2
,请选择内部bean。
答案 3 :(得分:0)
考虑到您的实现,您可能希望选择 Bean定义继承。
从春天documentation:
bean定义可以包含很多配置信息, 包括构造函数参数,属性值和 容器特定的信息,如初始化方法,静态 工厂方法名称,等等。子bean定义继承 来自父定义的配置数据。孩子的定义可以 根据需要覆盖某些值或添加其他值。使用父母和孩子 bean定义可以节省大量的输入。实际上,这是一种形式 模板化。
基本上它说的是你可以有一种“Bean定义的模板”将其标记为抽象,并在其他兼容的bean中使用它作为 parent 来继承这些配置。
此样本取自春季documentation:
<bean id="inheritedTestBean" abstract="true"
class="org.springframework.beans.TestBean">
<property name="name" value="parent"/>
<property name="age" value="1"/>
</bean>
所以此时此bean未实例化,仅用于bean定义继承。
<bean id="inheritsWithDifferentClass"
class="org.springframework.beans.DerivedTestBean"
parent="inheritedTestBean" init-method="initialize">
<property name="name" value="override"/>
<!-- the age property value of 1 will be inherited from parent -->
</bean>
在这里你可以看到org.springframework.beans.DerivedTestBean
用于实例化bean,但它将使用父的所有定义,而且,它将覆盖属性name
。不需要在父项上指定类,但如果在父项(inheritedTestBean
)上指定而不在子项(inheritsWithDifferentClass
)上指定,则将使用父类来实例化子项。并非所有内容都是继承的,我们可以在这里看到:
子bean定义继承构造函数参数值property 值和来自父级的方法覆盖,以及要添加的选项 新的价值观。任何初始化方法,destroy方法和/或静态 您指定的工厂方法设置将覆盖 相应的父设置。
其余设置始终取自子定义: 取决于,autowire模式,依赖性检查,单例,范围,懒惰 初始化。
以下是使用您的课程的示例:
<!-- the way you are already using it -->
<bean id="b1" class="SomeClass">
<property name="foo" ref="foo1"/>
</bean>
<!-- if you use it just once, you could declare it inside the bean that uses it -->
<bean id="b2" class="SomeClass">
<property name="foo">
<bean id="foo1" class="FooClass" parent="foo">
<constructor-arg index="0"><ref bean="dataSource1"/></constructor-arg>
</bean>
</property>
</bean>
<!-- here no class definition, only the default configuration -->
<bean id="foo" abstract="true">
<!-- constructor arg 0 is defined only on child beans -->
<constructor-arg index="1" value="whatever1" />
<constructor-arg index="2" value="whatever2" />
<constructor-arg index="3" value="whatever3" />
<constructor-arg index="4" value="whatever4" />
</bean>
<bean id="foo2" class="FooClass">
<constructor-arg index="0"><ref bean="dataSource2"/></constructor-arg>
</bean>