Java -- Spring学习笔记2、基于XML的DI
1、注入分类
bean实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。根据注入方式的不同,常用的有两类:set注入、构造注入。
2、set注入
set 注入也叫设值注入是指,通过setter方法传入被调用者的实例。这种注入方式简单、直观,因而在Spring的依赖注入中大量使用。
A、简单类型
- 创建实体类、如下:
public class UserInfo
{
private int id;
private String name;
private int age;
//setter toString()
}
- 在配置文件中声明bean、并赋值:
<bean id="userInfo" class="com.rg.entity.UserInfo">
<property name="id" value="1001"/>
<property name="name" value="张三"/>
<property name="age" value="18"/>
</bean>
- 测试方法:
@Test
public void test03()
{
String config = "applicationContext.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
UserInfo userInfo = (UserInfo) ctx.getBean("userInfo");
System.out.println(userInfo);
}
- 输出:
UserInfo{id=1001, name='张三', age=18}
B、引用类型
当指定bean的某属性值为另一 bean的实例时,通过ref指定它们间的引用关系。ref的值必须为某bean的id值。
- 创建两个实体类、分别是UserInfo和School、如下:
public class UserInfo
{
private int id;
private String name;
private int age;
//引用类型
private School school;
//setter toString()...
}
public class School
{
private String name;
//setter toString()...
}
- 配置文件如下:
<!--
声明School对象
-->
<bean id="mySchool" class="com.rg.entity.School">
<property name="name" value="西北工业大学"/>
</bean>
<!--
对于其它Bean对象的引用,使用<bean/>标签的ref属性
-->
<bean id="userInfo" class="com.rg.entity.UserInfo">
<!-- 简单类型属性赋值 -->
<property name="id" value="1001"/>
<property name="name" value="张三"/>
<property name="age" value="18"/>
<!-- 引用类型赋值 -->
<property name="school" ref="mySchool"/>
</bean>
- 测试方法:
@Test
public void test03()
{
String config = "applicationContext.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
UserInfo userInfo = (UserInfo) ctx.getBean("userInfo");
System.out.println(userInfo);
}
- 输出:
UserInfo{id=1001, name='张三', age=18, school=School{name='西北工业大学'}}
3、构造注入
构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即、使用构造器设置依赖关系。
- 在实体类中添加构造函数、如下:
public class UserInfo
{
private int id;
private String name;
private int age;
private School school;
public UserInfo(int id, String name, int age, School school)
{
this.id = id;
this.name = name;
this.age = age;
this.school = school;
}
//setter toString()...
}
- 配置文件:
<bean id="mySchool" class="com.rg.entity.School">
<property name="name" value="西北工业大学"/>
</bean>
<bean id="userInfo" class="com.rg.entity.UserInfo">
<constructor-arg name="id" value="1001"/>
<constructor-arg name="name" value="张三"/>
<constructor-arg name="age" value="18"/>
<constructor-arg name="school" ref="mySchool"/>
</bean>
<constructor-arg />标签中用于指定参数的属性有:
- name:指定参数名称。
- index:指明该参数对应着构造器的第几个参数,从 0 开始。不过,该属性不要也行,但要注意,若参数类型相同,或之间有包含关系,则需要保证赋值顺序要与构造器中的参数顺序一致。
- 测试方法:
@Test
public void test03()
{
String config = "applicationContext.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
UserInfo userInfo = (UserInfo) ctx.getBean("userInfo");
System.out.println(userInfo);
}
4、引用类型属性自动注入
对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签设置 autowire 属性值,为引用类型属性进行隐式自动注入、默认是不自动注入引用类型属性。根据自动注入判断标准的不同,可以分为两种:
- byName:根据名称自动注入
- byType:根据类型自动注入
4.1、byName方式自动注入
- 实体类如下:
public class UserInfo
{
private int id;
private String name;
private int age;
//这里的属性名称是:school
private School school;
//setter toString()....
}
- 配置文件:
<!--
这里的id和UserInfo类中的属性名相同:school
-->
<bean id="school" class="com.rg.entity.School">
<property name="name" value="西北工业大学"/>
</bean>
<!--
添加:autowire="byName"
-->
<bean id="userInfo" class="com.rg.entity.UserInfo" autowire="byName">
<property name="id" value="1001"/>
<property name="name" value="张三"/>
<property name="age" value="18"/>
<!--注掉-->
<!--<property name="school" ref="mySchool"/>-->
</bean>
- 测试类同上。
4.2、byType方式自动注入
使用 byType 方式自动注入,要求:配置文件中被调用者bean的class属性指定的类,要与代码中调用者bean类的某引用类型属性类型同源。即要么相同,要么有is-a关系(子类,或是实现类)。但这样的同源的被调用bean只能有一个。多于一个,容器就不知该匹配哪一个了。
- 实体类代码不变:
public class UserInfo
{
private int id;
private String name;
private int age;
//School类型
private School school;
//setter toString()...
}
- 配置文件
<!--
这里的class:com.rg.entity.School和UserInfo类中的属性类型相同
都是:School
-->
<bean id="school" class="com.rg.entity.School">
<property name="name" value="西北工业大学"/>
</bean>
<!--
添加:autowire="byName"
-->
<bean id="userInfo" class="com.rg.entity.UserInfo" autowire="byType">
<property name="id" value="1001"/>
<property name="name" value="张三"/>
<property name="age" value="18"/>
<!--注掉-->
<!--<property name="school" ref="mySchool"/>-->
</bean>
- 测试类同上。
最后、推荐使用set注入、构造注入了解即可。