目录
1. DI:给属性赋值
Spring调用类的无参构造方法,创建对象,对象创建后给属性赋值。
给属性赋值有两种大的方法 :1.使用xml配置文件中的标签和属性。2.使用注解
基于xml配置文件的DI有两种方式:①set注入(设值注入)。②构造注入。
以下所有的实例均给出三块代码(相关属性类、spring配置文件、测试类)。
2. Set注入
set 注入也叫设值注入是指,通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。推荐使用
2.1.简单的set注入
先写个实体类,Student实体类
package com.liuhaiyang.bao01; public class Student { private String name; private int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", id=" + id + '}'; } }
在配置文件中写入
<!-- DI:给属性赋值 1.set注入: spring调用类的set方法,通过set方法完成属性赋值 简单类型的set注入: 语法:< bean id="XXX" class="YYY"> <property name="属性名“ value="简单类型属性值"/> ...... </bean> --> <bean id="Student" class="com.liuhaiyang.bao01.Student"> <!-- setName("李四") --> <property name="name" value="李四"/> <!-- setid("1001") --> <property name="id" value="1001"/> </bean> <!-- 声明日期类 --> <bean id="mydate" class="java.util.Date"> <!-- setTime() --> <property name="time" value="9992361646"/> </bean>
测试类
@Test public void test1(){ String config="bao01/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student stu=(Student) ctx.getBean("Student"); Date date=(Date) ctx.getBean("mydate"); System.out.println(date); System.out.println(stu); }
结果截图
2.2引用类型的set注入
当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引用关系。ref 的值必须为某 bean 的 id 值。 写两个实体类
public class School { public String name; public int banji; public School(String name, int banji) { System.out.println("school的有参构造方法"); this.name = name; this.banji = banji; } public School() { System.out.println("学校的无参构造方法"); } //set和get方法 //toString }
Student { private String name; private int id; private School school; public Student(String name, int id, School school) { System.out.println("student有参构造方法"); this.name = name; this.id = id; this.school = school; } public Student(){ System.out.println("Student的无参构造方法"); } public void setSchool(School school) { System.out.println("SetSchool =>"+school); this.school = school; } //set和get方法 //toString }
配置文件
<!--2.set注入: 引用类型set注入:语法:<bean id="xxx" class = ”yyy“> <<property name="属性名“ ref="bean的id"/> ......</bean> --> <bean id="Student" class="com.liuhaiyang.bao02.Student"> <property name="name" value="李四"/> <property name="id" value="1001"/> <property name="school" ref="myschool"/> <!-- 相当于setSchool(mySchool)--> </bean> <bean id="myschool" class="com.liuhaiyang.bao02.School"> <property name="name" value="北京大学"/> <property name="banji" value="203"/> </bean>
测试类
@Test public void test01(){ String config="bao01/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student stu=(Student) ctx.getBean("Student"); System.out.println(stu); }
结果截图
2.3构造注入(理解)
构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。 实体类同上(Studnet和School),就不写了。
配置文件
<!--构造注入用的少,大多数都是用set注入--> <!-- 构造注入:spring调用类的有参构造方法,创建对象同时给属性赋值 语法:<bean id="xxx" class="yyy"> <constructor-arg>: 表示一个构造方法的形参 标签属性: name:构造方法参名 index:构造方法的参数位置 value:简单类型的参数值 ref: 引用类型的形参值 --> <bean id="mystudent2" class="com.liuhaiyang.bao02.Student"> <constructor-arg name="id" value="23"/> <constructor-arg name="name" value="王五"/> <constructor-arg name="school" ref="myschool2"/> </bean> <!-- index方法声明对 index是按照位置声明的,参数是0,1,2位置是从左往右一次累加 下面代码和上面代码作用一样--> <!-- <bean id="mystudent2" class="com.liuhaiyang.bao02.Student"> <constructor-arg index="0" value="王五"/> <constructor-arg index="1" value="23"/> <constructor-arg index="2" ref="myschool2"/> index可以不写 但是要一一对应 <constructor-arg value="王五"/> <constructor-arg value="23"/> <constructor-arg ref="myschool2"/> </bean> --> <bean id="myschool2" class="com.liuhaiyang.bao02.School"> <constructor-arg name="name" value="上海大学"/> <constructor-arg name="banji" value="20"/> </bean>
测试类
@Test public void test03(){ String string="bao01/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(string); Student stu=(Student) ctx.getBean("mystudent2"); System.out.println(stu); }
结果截图
2.4引用类型的自动注入(基于set注入)
对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属性)。根据自动注入判断标准的不同,可以分为两种:
byName:根据名称自动注入
byType: 根据类型自动注入
2.4.1 byName(按名称注入)
当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,可使用 byName 方式,让容器自动将被调用者 bean 注入给调用者bean。容器是通过调用者的 bean 类的属性名与配置文件的被调用者 bean 的id 进行比较而实现自动注入的。
实体类同上(Studnet和School),就不写了。
配置文件
<!-- 声明bean--> <!-- 引用型自动注入: Spring 根据byName,byType规格给引用类型赋值 1.byName(按名称注入):Java类中的引用类型的属性名称和spring容器在的bean的id名称一样, 且数据类型一样的,这样的bean能够赋值给引用类型 语法: <bean id="xxx" class="yy" autowire="byname"> 简单类型属性值 <bean> --> <!-- 引用set注入--> <bean id="mystudent" class="com.liuhaiyang.bao03.Student" autowire="byName"> <property name="name" value="李四"/> <property name="id" value="1001"/> <!-- 连接操作不用写 <property name="school" ref="myschool"/> --> </bean> <!-- school声明 id必须要和属性名称一样--> <bean id="school" class="com.liuhaiyang.bao03.School"> <property name="name" value="北京大学"/> <property name="banji" value="203"/> </bean>
测试类
@Test public void mytest03(){ String config="bao03/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student student= (Student) ctx.getBean("mystudent"); System.out.println("结果=====>"+student); }
结果
2.4.2 byType(按类型注入)
Java 类中引用类型的数据类型和 Spring 容器中 bean 的 class 值是同源的,这样的 bean 赋值给引用类型。
同源关系是指:
1. Java 中引用类型的数据类型和 bean 的 class 值是一样的。
2. Java 中引用类型的数据类型和 bean 的 class 值是父子类关系的。
3. Java 中引用类型的数据类型和 bean 的 class 值是接口和实现关系的。
但这样的同源的被调用 bean只能有一个。如果多于一个,容器就不知该匹配哪一个了。实体类同上(Studnet和School),就不写了。
public class StudentZi extends School { }
配置文件
<!-- byType(按类型注入): Java类中引用类型的数据类型和bean的class是同源的, 这些的bean能够赋值给引用类型 同源关系: 1.Java中引用类型的实践类型和bean的class值是一样的. 2.Java中引用类型的实践类型和bean的class值是父子类关系 3.Java中引用类型的实践类型和bean的class值是接口和实现类关系. 语法: <bean id="xxx" class="yy" autowire="byType"> 简单类型属性赋值 <bean> 注意: 符合条件的对象只能有一个,多余的会报错 --> <bean id="mystudent" class="com.liuhaiyang.bao03.Student" autowire="byType"> <property name="name" value="王五"/> <property name="id" value="10001"/> <!-- <property name="school" ref="myschool"/> --> </bean> <!-- school声明 1.Java中引用类型的实践类型和bean的class值是一样的.--> <!-- <bean id="school" class="com.liuhaiyang.bao03.School">--> <!-- <property name="name" value="家里蹲大学"/>--> <!-- <property name="banji" value="203"/>--> <!-- </bean>--> <!-- 2.Java中引用类型的实践类型和bean的class值是父子类关系--> <bean id="school" class="com.liuhaiyang.bao03.StudentZi"> <property name="name" value="外面蹲大学"/> <property name="banji" value="203"/> </bean>
测试类
@Test public void mytest04(){ String config="bao03/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student student= (Student) ctx.getBean("mystudent"); System.out.println("结果=====>"+student); }
结果截图:
3.Spring加载多个配置文件
项目中如果使用多个spring配置文件,可以采用 分多个配置文件 的方式:
1. 按功能模块分,一个模块一个配置文件。
2. 按类的功能分,数据库操作相关的类在一个配置文件,service类在一个配置文件,redis、事务相关的在一个配置文件。
spring管理多个配置文件,常用的是包含关系的配置文件,项目中有一个总的文件,里面是有import标签包含其他多个配置文件。
目录结构实体类同上(Studnet和School),就不写了。
总配置文件
<!-- 当前是总的文件,目的是包含其他的多个配置文件,一般不声明bean 语法:<impoet resource="classpath:其他文件的路径"/> classpath:表示类路径。类文件所在的目录,spring通过类路径加载配置文件--> <!-- <import resource="classpath:bao04/spring-school.xml"/>--> <!-- <import resource="classpath:bao04/spring-student.xml"/>--> <!-- 包含关系的配置文件,可使用通配符*:表示任意字符--> <import resource="classpath:bao04/spring-*"/>
子配置文件1
<bean id="school" class="com.liuhaiyang.bao04.School"> <property name="name" value="厕所蹲大学"/> <property name="banji" value="2003"/> </bean>
子配置文件2
<bean id="mystudent" class="com.liuhaiyang.bao04.Student" autowire="byType"> <property name="name" value="赵六"/> <property name="id" value="10005"/> </bean>
测试类:
@Test public void mytest04(){ String config="bao04/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student student= (Student) ctx.getBean("mystudent"); System.out.println("结果=====>"+student); }
结果截图: