为了账号安全,请及时绑定邮箱和手机立即绑定

Spring构造函数注入

标签:
Java

Spring可以通过构造函数和setter属性方法来做依赖注入,这里我们先介绍下如何使用构造函数做依赖注入。

我们要注入的类代码如下:

package cn.outofmemory.spring_DI_constructor; public class Person { private String firstName; private String lastName; private int age; private String classNo; public Person() { } public Person(String firstName, String lastName, int age, String classNo) { this.setFirstName(firstName); this.setLastName(lastName); this.setAge(age); this.setClassNo(classNo); } public Person(String firstName, int age, String classNo) { this(firstName, null, age, classNo); } public Person(String firstName, String lastName) { 
 this(firstName, lastName, 0 , null); 
 } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getClassNo() { return classNo; } public void setClassNo(String classNo) { this.classNo = classNo; } }

Person类有四个属性,分别为firstName,lastName,age和classNo;有三个构造函数,无参构造函数、4个参数和3个、2个参数的构造函数。

我们在spring配置文件中通过构造函数注入,配置一个Person bean:

<?xml version="1.0" encoding="UTF-8"?> <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.xsd"> <bean class="cn.outofmemory.spring_DI_constructor.Person" id="personA"> <constructor-arg><value>James</value></constructor-arg> <constructor-arg><value>Bonde</value></constructor-arg> </bean> </beans>

 配置文件中的bean指定了两个构造函数。这样spring会自动匹配到有两个参数的构造函数。我们测试一下效果,请看下面App代码:

package cn.outofmemory.spring_DI_constructor; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /**  * Hello spring!  *  */ public class App  {     public static void main( String[] args )     {         ApplicationContext appContext = new ClassPathXmlApplicationContext("/spring.xml");         Person personA = (Person)appContext.getBean("personA");         System.out.println("personA firstName is " + personA.getFirstName() + ", lastName is " + personA.getLastName());     } }

 运行程序将输出:

personA firstName is James, lastName is Bonde

可以看到spring正确的调用了对应的构造函数。

对于spring bean的constructor-arg节点,需要注意它的value的类型如果不指定默认情况是根据字面意思来推断的,这个有时候会容易引起混淆,比如我需要1301表示班级号,classNo是一个String类型,如果让spring默认解析的话会解析成int类型,这时候我们可以通过指定constructor-arg节点的type属性来解决。比如下面配置信息:

<?xml version="1.0" encoding="UTF-8"?> <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.xsd"> <bean class="cn.outofmemory.spring_DI_constructor.Person" id="personA"> <constructor-arg type="java.lang.String"><value>James</value></constructor-arg> <constructor-arg type="java.lang.String"><value>Bonde</value></constructor-arg> <constructor-arg type="int"><value>20</value></constructor-arg> <constructor-arg type="java.lang.String"><value>1302</value></constructor-arg> </bean> </beans>

在这个配置中我们指定了每一个构造函数参数的type属性。这样就可以避免因为参数类型导致的构造函数混淆了。

在构造函数中注入复杂类型

假定我们的Person类有一个复杂属性ContactInfo,我们也可以通过构造函数来注入这个属性,如下是ContactInfo的定义:

package cn.outofmemory.spring_DI_constructor; public class ContactInfo { private String address; private String zipCode; public ContactInfo(String address_, String zipCode_) { this.address = address_; this.zipCode = zipCode_; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } }

 我们在Person类中添加Contact属性,和对应的构造函数,如下代码:

 private ContactInfo contact; public ContactInfo getContact() { return contact; } public void setContact(ContactInfo contact) { this.contact = contact; } public Person(String firstName, ContactInfo contactInfo) { this.setFirstName(firstName); this.setContact(contactInfo); }

这样我们就可以在spring的配置文件中注入Person的contact属性了:

<?xml version="1.0" encoding="UTF-8"?> <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.xsd"> <bean class="cn.outofmemory.spring_DI_constructor.Person" id="personA"> <constructor-arg type="java.lang.String"><value>James</value></constructor-arg> <constructor-arg type="java.lang.String"><value>Bonde</value></constructor-arg> <constructor-arg type="int"><value>20</value></constructor-arg> <constructor-arg type="java.lang.String"><value>1302</value></constructor-arg> </bean> <bean class="cn.outofmemory.spring_DI_constructor.Person" id="personWithContact"> <constructor-arg><value>James</value></constructor-arg> <constructor-arg ref="contactOfPersonWithContact"></constructor-arg> </bean> <bean class="cn.outofmemory.spring_DI_constructor.ContactInfo" id="contactOfPersonWithContact"> <constructor-arg><value>河北省邢台市</value></constructor-arg> <constructor-arg><value>054000</value></constructor-arg> </bean> <bean class="cn.outofmemory.spring_DI_constructor.Person" id="personWithContactA"> <constructor-arg><value>James</value></constructor-arg> <constructor-arg> <bean class="cn.outofmemory.spring_DI_constructor.ContactInfo"> <constructor-arg><value>河北省邢台市</value></constructor-arg> <constructor-arg><value>054000</value></constructor-arg> </bean> </constructor-arg> </bean> </beans>

我们定义了另外两个Person:personWithContact和personWithContactA,personWithContact的contact属性是通过constructor-arg的ref属性注入进来的,而第二个person是通过直接将ContactInfo的bean写道constructor-arg节点内来实现的。

两种方法都是可用的,第一种方式适合于contact会被别的bean共享的方式,而第二种写法是不可以在其他bean之间共享的。

源码下载:spring-DI-constructor.zip

原文链接:http://outofmemory.cn/java/spring/spring-DI-via-constructor

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消