Spring教程 - Spring构造函数注入
Spring教程 - Spring构造函数注入
我们可以通过构造函数注入依赖。
构造函数依赖注入发生在Java Bean的依赖关系在其构造函数中提供给它。
Java Bean声明一个构造函数或一组构造函数,从参数中获取其依赖性,以及IoC容器在实例化时将依赖性传递给Java Bean。
例子
假设我们定义了以下接口和Java bean。
package com.www.w3cschool.cnmon;
public interface Printer
{
public void print();
}
之后,我们将创建CSV打印机,将输出CSV格式的数据。CSV打印机实现打印机接口。
package com.www.w3cschool.cnmon;
public class CSVPrinter implements Printer
{
public void print(){
System.out.println("Csv Output Printer");
}
}
然后是时间创建JSON打印机将输出JSON格式的消息。JSON打印机还实现了打印机接口。
package com.www.w3cschool.cnmon;
public class JSONPrinter implements Printer
{
public void print(){
System.out.println("Json Output Printer");
}
}
一个带有构造函数的助手类。
package com.www.w3cschool.cnmon;
public class OutputHelper
{
Printer outputGenerator;
public OutputHelper(){
}
public OutputHelper(Printer p){
this.outputGenerator = p;
}
public void print(){
outputGenerator.print();
}
}
以下Spring bean配置文件声明并通过使用 constructor-arg 标记的构造函数注入来设置依赖关系。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="outputHelper" class="com.www.w3cschool.cnmon.OutputHelper">
<constructor-arg>
<bean class="com.www.w3cschool.cnmon.CSVPrinter" />
</constructor-arg>
</bean>
<bean id="csvPrinter" class="com.www.w3cschool.cnmon.CSVPrinter" />
<bean id="jsonPrinter" class="com.www.w3cschool.cnmon.JSONPrinter" />
</beans>
加载配置和运行
下面的代码展示了如何加载Spring配置文件并运行应用程序。
package com.www.w3cschool.cnmon;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"SpringBeans.xml");
OutputHelper output = (OutputHelper)context.getBean("outputHelper");
output.print();
}
}
输出

Download Java2s_Spring_Constructor_Injection.zip
构造函数注入类型模糊
以下Employee类有两个构造函数方法。它们都接受具有不同数据类型的3个参数。
package com.www.w3cschool.cnmon;
public class Employee
{
private String name;
private String address;
private int age;
public Employee(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}
public Employee(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String toString(){
return " name : " +name + " address : " + address + " age : " + age;
}
}
第一个具有以下参数
public Employee(String name, String address, int age)
第二个定义如下。
public Employee(String name, int age, String address)
年龄和地址切换位置。
当在Spring配置中创建Employee对象时,我们使用xml文件 constructor-arg 标记来为构造函数中的参数提供值。
在下面的Spring bean配置文件中,我们传递了“java2s"的name,“1000"表示地址,“28"表示年龄。
<myPreCode>
<beans ...
<bean id="myEmployee" class="com.www.w3cschool.cnmon.Employee">
<constructor-arg>
<value>java2s</value>
</constructor-arg>
<constructor-arg>
<value>1000</value>
</constructor-arg>
<constructor-arg>
<value>28</value>
</constructor-arg>
</bean>
</beans>
这里是运行我们上面设置的配置的代码。
package com.www.w3cschool.cnmon;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App
{
public static void main( String[] args )
{
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"Spring-Employee.xml"});
Employee cust = (Employee)context.getBean("myEmployee");
System.out.println(cust);
}
}
输出

从结果字符串,我们可以看到第二个构造函数而不是第一个构造函数。
Spring将参数“1000"转换为int,然后调用接受第二个构造函数,即使我们在值中作为String类型传递。
如果Spring找不到正确的构造函数使用,它会提示以下错误信息
constructor arguments specified but no matching constructor found in bean "myEmployee" (hint: specify index and/or type arguments for simple parameters to avoid type ambiguities)
为了在构造函数中匹配参数类型,我们可以通过type属性指定构造函数的数据类型在 constructor-arg 标记中。
<beans ...
<bean id="myEmployee" class="com.www.w3cschool.cnmon.Employee">
<constructor-arg type="java.lang.String">
<value>java2s</value>
</constructor-arg>
<constructor-arg type="java.lang.String">
<value>1000</value>
</constructor-arg>
<constructor-arg type="int">
<value>28</value>
</constructor-arg>
</bean>
</beans>
再次运行。