文章目录:
1.DI:给属性赋值
Spring调用类的无参构造方法,创建对象,对象创建后给属性赋值。
给属性赋值有两种大的方法:1.使用xml配置文件中的标签和属性。2.使用注解
基于xml配置文件的DI有两种方式:①set注入(设值注入)。②构造注入。
以下所有的实例均给出三块代码(相关属性类、spring配置文件、测试类)。
2.基于xml的DI
set注入也叫设值注入是指,通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。
package com.bjpowernode.ba01; /** * */ public class Student { private String name; private int age; public Student() { System.out.println("Student类无参构造方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
<!-- DI: 给属性赋值 1.set注入:spring调用类的set方法,通过set方法完成属性赋值 简单类型的set注入: 语法:<bean id="xxx" class="yyy"> <property name="属性名" value="简单类型属性值"> ... </bean> --> <bean id="myStudent" class="com.bjpowernode.ba01.Student"> <!-- setName("李四") --> <property name="name" value="李四"/> <!-- setAge(20) --> <property name="age" value="20"/> </bean> <!-- 声明日期类 --> <bean id="mydate" class="java.util.Date"> <!-- setTime() --> <property name="time" value="9992361646"/> </bean>
@Test public void test01() { String config="ba01/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student student= (Student) ctx.getBean("myStudent"); System.out.println("student===" + student); Date date= (Date) ctx.getBean("mydate"); System.out.println("date===" + date); }
2.1.2 引用类型的set注入
package com.bjpowernode.ba02; /** * */ public class School { private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }
package com.bjpowernode.ba02; /** * */ public class Student { private String name; private int age; private School school; public Student() { System.out.println("Student类无参构造方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public School getSchool() { return school; } public void setSchool(School school) { this.school = school; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
<!-- DI: 给属性赋值 2.set注入:spring调用类的set方法,通过set方法完成属性赋值 引用类型的set注入: 语法:<bean id="xxx" class="yyy"> <property name="属性名" ref="bean的id值"> ... </bean> --> <bean id="myStudent" class="com.bjpowernode.ba02.Student"> <!-- 简单类型的赋值 --> <!-- setName("李四") --> <property name="name" value="李四"/> <!-- setAge(20) --> <property name="age" value="20"/> <!-- 引用类型的赋值 --> <!-- setSchool(mySchool) --> <property name="school" ref="mySchool"/> </bean> <!-- 声明School --> <bean id="mySchool" class="com.bjpowernode.ba02.School"> <property name="name" value="北京大学"/> <property name="address" value="北京海淀区"/> </bean>
@Test public void test01() { String config="ba02/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student student= (Student) ctx.getBean("myStudent"); System.out.println("student===" + student); }
2.2 构造注入(理解就行。。。)
构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。
package com.bjpowernode.ba03; /** * */ public class School { private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }
package com.bjpowernode.ba03; /** * */ public class Student { private String name; private int age; private School school; public Student() { System.out.println("Student类无参构造方法"); } public Student(String name, int age, School school) { System.out.println("Student有参构造方法"); this.name = name; this.age = age; this.school = school; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
<!-- DI: 给属性赋值 1.构造注入:Spring调用类的有参构造方法,创建对象同时给属性赋值 语法:<bean id="xxx" class="yyy"> <constructor-arg />: 表示一个构造方法的形参 属性:name: 构造方法的形参名 index:构造方法的参数位置 value:简单类型的形参值 ref: 引用类型的形参值 </bean> --> <bean id="myStudent" class="com.bjpowernode.ba03.Student"> <!-- <constructor-arg index="0" value="李四"/> --> <constructor-arg name="name" value="李四"/> <!-- <constructor-arg index="1" value="20"/> --> <constructor-arg name="age" value="20"/> <!-- <constructor-arg index="2" ref="mySchool"/> --> <constructor-arg name="school" ref="mySchool"/> </bean> <!-- 声明School --> <bean id="mySchool" class="com.bjpowernode.ba03.School"> <property name="name" value="北京大学"/> <property name="address" value="北京海淀区"/> </bean>
@Test public void test01() { String config="ba03/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student student= (Student) ctx.getBean("myStudent"); System.out.println("student===" + student); }
2.3 引用类型的自动注入(基于set注入)
对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属性)。根据自动注入判断标准的不同,可以分为两种:
byName:根据名称自动注入
byType:根据类型自动注入
Java类中引用类型属性名称和 Spring 容器中 bean 的 id 名称一样,且数据类型也是一样的。这些 bean 能够赋值给引用类型。
package com.bjpowernode.ba04; /** * */ public class School { private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }
package com.bjpowernode.ba04; /** * */ public class Student { private String name; private int age; private School school; public Student() { System.out.println("Student类无参构造方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public School getSchool() { return school; } public void setSchool(School school) { this.school = school; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
<!-- 引用类型自动注入 --> <!-- byName --> <bean id="myStudent" class="com.bjpowernode.ba04.Student" autowire="byName"> <!-- 简单类型的赋值 --> <!-- setName("李四") --> <property name="name" value="李四"/> <!-- setAge(20) --> <property name="age" value="20"/> <!-- 引用类型的赋值 --> <!-- setSchool(mySchool) --> <!--<property name="school" ref="mySchool"/>--> </bean> <!-- 声明School --> <bean id="school" class="com.bjpowernode.ba04.School"> <property name="name" value="清华大学"/> <property name="address" value="北京海淀区"/> </bean>
@Test public void test01() { String config="ba04/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student student= (Student) ctx.getBean("myStudent"); System.out.println("student===" + student); }
2.3.2 byType(按类型注入)
Java类中引用类型的数据类型和 Spring 容器中 bean 的 class 值是同源的,这样的 bean 赋值给引用类型。
同源关系是指:
1. Java 中引用类型的数据类型和 bean 的 class 值是一样的。
2. Java 中引用类型的数据类型和 bean 的 class 值是父子类关系的。
3. Java 中引用类型的数据类型和 bean 的 class 值是接口和实现关系的。
但这样的同源的被调用 bean只能有一个。如果多于一个,容器就不知该匹配哪一个了。
package com.bjpowernode.ba05; /** * */ public class School { private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }
package com.bjpowernode.ba05; /** * */ public class Student { private String name; private int age; private School school; public Student() { System.out.println("Student类无参构造方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public School getSchool() { return school; } public void setSchool(School school) { this.school = school; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
<!-- 引用类型自动注入 --> <!-- byType --> <bean id="myStudent" class="com.bjpowernode.ba05.Student" autowire="byType"> <!-- 简单类型的赋值 --> <!-- setName("李四") --> <property name="name" value="张三"/> <!-- setAge(20) --> <property name="age" value="25"/> <!-- 引用类型的赋值 --> <!-- setSchool(mySchool) --> <!--<property name="school" ref="mySchool"/>--> </bean> <!-- 声明School --> <bean id="school" class="com.bjpowernode.ba05.School"> <property name="name" value="清华大学"/> <property name="address" value="北京海淀区"/> </bean>
@Test public void test01() { String config="ba05/applicationContext.xml"; ApplicationContext ctx=new ClassPathXmlApplicationContext(config); Student student= (Student) ctx.getBean("myStudent"); System.out.println("student===" + student); }
3.Spring加载多个配置文件
项目中如果使用多个spring配置文件,可以采用分多个配置文件的方式:
1. 按功能模块分,一个模块一个配置文件。
2. 按类的功能分,数据库操作相关的类在一个配置文件,service类在一个配置文件,redis、事务相关的在一个配置文件。
spring管理多个配置文件,常用的是包含关系的配置文件,项目中有一个总的文件,里面是有import标签包含其他多个配置文件。
<!-- 当前是总的文件,目的是包含其他多个配置文件,一般不声明bean 语法:<import resource="classpath:其他文件的路径" /> classpath: 表示类路径,spring通过类路径加载配置文件 --> <import resource="classpath:ba06/spring-school.xml" /> <import resource="classpath:ba06/spring-student.xml" /> <!-- 上面两行等价于下面这行 --> <!-- <import resource="classpath:ba06/spring-*.xml" /> -->
<!-- 引用类型自动注入 --> <!-- byType --> <bean id="myStudent" class="com.bjpowernode.ba06.Student" autowire="byType"> <!-- 简单类型的赋值 --> <!-- setName("李四") --> <property name="name" value="张三"/> <!-- setAge(20) --> <property name="age" value="25"/> <!-- 引用类型的赋值 --> <!-- setSchool(mySchool) --> <!--<property name="school" ref="mySchool"/>--> </bean>
<!-- 声明School --> <bean id="school" class="com.bjpowernode.ba06.School"> <property name="name" value="清华大学"/> <property name="address" value="北京海淀区"/> </bean>