Spring框架----->(2) 基于xml配置文件的DI(依赖注解)、Spring多配置文件的方法

一、注入分类

bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。

根据注入方式的不同,常用的有两类:set 注入、构造注入。

1、set注入

spring调用类的set方法,可以在set方法中完成属性的赋值

A、简单类型
  • 语法格式:
<bean id="xx" class="yy">
      <property name="属性的名称" value="此属性的值"/>
</bean>
  • 创建Student类,为其属性定义各自的set方法
public class Student {
    
    
    private String name;
    private Integer age;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        System.out.println("setName:"+name);
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(Integer age) {
    
    
        System.out.println("setAge:"+age);
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 创建spring配置文件
<bean id="myStudent" class="com.hcz.ba01.Student">
    <property name="name" value="李四"/><!--setName("李四")-->
    <property name="age" value="23"/><!--setAge(23)-->
</bean>

注意
1、一个< property >只能给一个属性赋值
2、如果这这里name属性名有对应的set方法,则一定会执行该属性

  • 创建测试方法
@Test
public void test01(){
    
    
    //1.指定spring的配置文件
    String config = "/ba01/applicationContext.xml";
    //2.创建表示spring容器的对象,ApplicationContext
    ApplicationContext context = new ClassPathXmlApplicationContext(config);
    //3.从容器中获取某个对象
    Student student = (Student) context.getBean("myStudent");
    System.out.println(student);
}
B、引用类型

当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引用关系。ref的值必须为某 bean 的 id 值。

  • 语法格式:
<bean id="xx" class="yy">
      <property name="属性的名称" ref="外部bean的id(对象的名称)"/>
</bean>
  • 创建Student类,为其属性定义各自的set方法
public class Student {
    
    

    private String name;
    private Integer age;
    //声明一个引用类型
    private School school;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        System.out.println("setName:"+name);
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(Integer age) {
    
    
        System.out.println("setAge:"+age);
        this.age = age;
    }

    public void setSchool(School school) {
    
    
        this.school = school;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}
  • 创建spring配置文件
<bean id="myStudent" class="com.hcz.ba02.Student">
    <property name="name" value="李四"/><!--setName("李四")-->
    <property name="age" value="23"/><!--setAge(23)-->
    <!--引用类型-->
    <property name="school" ref="mySchool"/><!--setSchool(mySchool)-->
</bean>

<!--声明School对象-->
<bean id="mySchool" class="com.hcz.ba02.School">
    <property name="name" value="xx大学"/>
    <property name="address" value="广东省xx市"/>
</bean>

注意
ref:这里ref的值为引用类型的bean的id值

  • 创建测试方法
@Test
public void test01(){
    
    
    //1.指定spring的配置文件
    String config = "/ba02/applicationContext.xml";
    //2.创建表示spring容器的对象,ApplicationContext
    ApplicationContext context = new ClassPathXmlApplicationContext(config);
    //3.从容器中获取某个对象
    Student student = (Student) context.getBean("myStudent");
    System.out.println(student);
}
C、复杂类型
(1)给数组赋值
private String[] hobbies;
public void setHobbies(String[] hobbies) {
    
    
    this.hobbies = hobbies;
}
<property name="hobbies">
    <array>
        <value>book</value>
        <value>gril</value>
        <value>movie</value>
    </array>
</property>

输出结果为:
hobbies=[book, gril, movie]

(2)给list集合赋值
private List<Address> lists;
public void setLists(List<Address> lists) {
    
    
    this.lists = lists;
}
<bean id="person5" class="bean.Person1">
	<property name="lists">
	    <list>
	        <!--使用内部bean,无法从IOC容器获取对象的值-->
	        <bean id="address2" class="bean.Address">
	            <property name="province" value="广东省"></property>
	            <property name="city" value="xx市"></property>
	            <property name="town" value="xx区"></property>
	        </bean>
	        <!--使用外部bean-->
	        <ref bean="address"></ref>
	    </list>
	</property>
</bean>
<bean id="address" class="bean.Address">
    <property name="province" value="广东省"></property>
    <property name="city" value="xx市"></property>
    <property name="town" value="xx市"></property>
</bean>

输出结果为:
lists=[Address{province=‘广东省’, city=‘梅州市’, town=‘梅江区’}, Address{province=‘广东省’, city=‘广州市’, town=‘黄浦区’}]

(3)给set集合赋值
private Set<String> sets;
public void setSets(Set<String> sets) {
    
    
    this.sets = sets;
}
<!--给set属性赋值-->
<property name="sets">
    <set>
        <value>张三</value>
        <value>张三</value>
        <value>李四</value>
    </set>
</property>

输出结果为:
sets=[张三, 李四]

(4)给map集合赋值
private Map<String,Object> maps;
public void setMaps(Map<String, Object> maps) {
    
    
    this.maps = maps;
}
<!--给map属性赋值-->
<property name="maps">
    <map>
        <entry key="a" value="aaa"></entry>
        <entry key="address" value-ref="address"></entry>
        <entry key="address2">
            <bean class="bean.Address">
                <property name="province" value="上海市"></property>
            </bean>
        </entry>
        <entry>
            <key>
                <value>b</value>
            </key>
            <value>bbb</value>
        </entry>
        <entry key="list">
            <list>
                <value>1</value>
                <value>2</value>
            </list>
        </entry>
    </map>
</property>

输出结果为:
maps={a=aaa, address=Address{province=‘广东省’, city=‘广州市’, town=‘黄浦区’}, address2=Address{province=‘上海市’, city=‘null’, town=‘null’}, b=bbb, list=[1, 2]}

2、构造注入

构造注入是指:
spring调用类有参构造方法,在创建对象的同时,在构造方法中给属性赋值

  • 语法格式:
<bean id="xx" class="yy">
      <constructor-arg name=""  value=""/>
</bean>

解析
name : 表示构造方法的形参名。
index : 表示构造方法的参数位置,参数从左往右位置是0,1,2的顺序,可不需要该属性,但需要保证赋值顺序要与构造方法中的参数顺序一致。
value : 构造方法的形参是简单类型的使用value。
ref : 构造方法的形参是引用类型的使用ref。

  • 创建Student类,定义有参构造方法
public Student(String name, Integer age, School school) {
    
    
    System.out.println("Student有参构造方法");
    this.name = name;
    this.age = age;
    this.school = school;
}
  • 创建spring配置文件
<bean id="myStudent" class="com.hcz.ba03.Student">
    <constructor-arg name="name"  value="张三"/>
    <constructor-arg name="age"  value="34"/>
    <constructor-arg name="school"  ref="mySchool"/>
</bean>
<!--声明School对象-->
<bean id="mySchool" class="com.hcz.ba03.School">
    <property name="name" value="xx大学"/>
    <property name="address" value="广东省xx市"/>
</bean>
  • 创建测试方法
@Test
public void test01(){
    
    
    //1.指定spring的配置文件
    String config = "/ba03/applicationContext.xml";
    //2.创建表示spring容器的对象,ApplicationContext
    ApplicationContext context = new ClassPathXmlApplicationContext(config);
    //3.从容器中获取某个对象
    Student student = (Student) context.getBean("myStudent");
    System.out.println(student);
}

注意
1、当有多个相同参数的构造方法存在的时候,默认情况下是覆盖的过程,后面的构造方法会覆盖前面的构造方法
2、如果非要赋值给另外一个构造方法的话,可以使用type的参数进行指定,例如:

<constructor-arg  value="25" type="java.lang.Integer"/>

3、引用类型属性自动注入

对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为< bean/ >标签
设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属性)。
根据自动注入判断标准的不同,可以分为两种:

  • byName:根据名称自动注入
  • byType: 根据类型自动注入
(1)byName(按名称)方式自动注入

当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,可使用 byName 方式,让容器自动将被调用者 bean 注入给调用者 bean。容器是通过调用者的 bean类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。
简单来说就是
java类中引用类型的属性名School school和spring容器中< bean >的 id 名称一样且数据类型是一致的

  • 语法格式:
<bean id="xx" class="yy" autowire="byName">
      简单类型属性赋值
</bean>
  • 创建spring配置文件
<!--byName-->
<bean id="myStudent" class="com.hcz.ba04.Student" autowire="byName">
    <property name="name" value="张三"/>
    <property name="age" value="45"/>
</bean>

<!--声明School对象:这里的id值改为和Student中的School属性名一样-->
<bean id="school" class="com.hcz.ba04.School">
    <property name="name" value="xx大学"/>
    <property name="address" value="广东省xx市"/>
</bean>
(2)byType(按类型)方式自动注入

使用 byType 方式自动注入,要求:java类中引用类型的数据类型和spring配置文件中< bean >的 class 属性是同源关系的,这样的bean能够赋值给引用类型

这里同源关系就是一类的意思:
1、Java类中引用类型的数据类型和 bean 的 class 的值是一样的
2、Java类中引用类型的数据类型和 bean 的 class 的值是父子类关系的
3、Java类中引用类型的数据类型和 bean 的 class 的值是接口和实现类关系的

  • 语法格式:
<bean id="xx" class="yy" autowire="byType">
      简单类型属性赋值
</bean>
  • 创建spring配置文件
<!--byType-->
<bean id="myStudent" class="com.hcz.ba05.Student" autowire="byType">
    <property name="name" value="张三"/>
    <property name="age" value="45"/>
</bean>

<!--声明School对象:同源关系的第一种-->
<!--<bean id="mySchool" class="com.hcz.ba05.School">-->
    <!--<property name="name" value="xx大学"/>-->
    <!--<property name="address" value="广东省xx市"/>-->
<!--</bean>-->

<!--声明School子类:同源关系的第二种-->
<bean id="primarySchool" class="com.hcz.ba05.PrimarySchool">
    <property name="name" value="xx小学"/>
    <property name="address" value="xx市"/>
</bean>
  • 执行后的结果为:
Student{
    
    name='张三', age=45, school=School{
    
    name='xx小学', address='xx市'}}

二、为应用指定多个 Spring 配置文件

1、多个配置优势

1、每个文件的大小比一个文件要小很多,所以执行效率高
2、避免多人竞争带来的冲突,例如:多人开发一个学生管理系统项目时,张三负责学生考勤模块,李四负责学生成绩模块,那么他们模块都应对应一个配置文件,这样才不会冲突。

2、多文件的分配方式:

  1. 按功能模块,一个模块一个配置文件
  2. 按类的功能,数据库相关的配置一个文件配置文件, 做事务的功能一个配置文件, 做业务service功能的一个配置文件等

3、包含关系的配置文件

多个配置文件中有一个总文件,总配置文件将各其它子文件通过< import/ >引入。在 Java 代码中只需要使用总配置文件对容器进行初始化即可

  • 创建功能模块spring配置文件

ba06/spring-school.xml

<bean id="mySchool" class="com.hcz.ba06.School">
    <property name="name" value="xx大学"/>
    <property name="address" value="广东省xx市"/>
</bean>

ba06/spring-student.xml

student模块所有的bean声明
<bean id="myStudent" class="com.hcz.ba06.Student" autowire="byType">
    <property name="name" value="lisi"/>
    <property name="age" value="45"/>
</bean>
  • 创建spring主配置文件
  • 语法格式:
<import resource="其它配置文件的路径"/>
  • 关键字:

classpath : 表示类路径(class文件所在的目录),
在spring的配置文件中要指定其他文件的位置,需要使用classpath,告诉spring到哪里去加载读取文件

ba06/total.xml

<import resource="classpath:ba06/spring-*.xml"/>

注意
在包含关系的配置文件中,可以使用通配符( * : 表示任意字符 ),
但是主配置文件名称不能包含在通配符的范围内

  • 创建测试方法
@Test
public void test01(){
    
    
    //1.指定spring的配置文件
    String config = "/ba06/total.xml";
    //2.创建表示spring容器的对象,ApplicationContext
    ApplicationContext context = new ClassPathXmlApplicationContext(config);
    //3.从容器中获取某个对象
    Student student = (Student) context.getBean("myStudent");
    System.out.println(student);
}

猜你喜欢

转载自blog.csdn.net/hcz666/article/details/113261425