Spring——IoC中基于xml的DI

简介: Spring——IoC中基于xml的DI

文章目录:


1.DI:给属性赋值

2.基于xmlDI

2.1 set注入(推荐使用!!!)

2.1.1 简单类型的set注入 

2.1.2 引用类型的set注入

2.2 构造注入(理解就行。。。)

2.3 引用类型的自动注入(基于set注入)

2.3.1 byName(按名称注入)

2.3.2 byType(按类型注入)

3.Spring加载多个配置文件

3.1 总配置文件 

3.2 分配置文件1

3.3 分配置文件2

1.DI:给属性赋值


Spring调用类的无参构造方法,创建对象,对象创建后给属性赋值。

给属性赋值有两种大的方法:1.使用xml配置文件中的标签和属性。2.使用注解

基于xml配置文件的DI有两种方式:set注入(设值注入)。构造注入。 

以下所有的实例均给出三块代码(相关属性类、spring配置文件、测试类)。

2.基于xml的DI


2.1 set注入(推荐使用!!!)

set注入也叫设值注入是指,通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。

2.1.1 简单类型的set注入 

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根据类型自动注入 

2.3.1 byName(按名称注入)

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标签包含其他多个配置文件。

3.1 总配置文件 

    <!--
        当前是总的文件,目的是包含其他多个配置文件,一般不声明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" />
    -->

3.2 分配置文件1

    <!-- 引用类型自动注入 -->
    <!-- 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>

3.3 分配置文件2

    <!-- 声明School -->
    <bean id="school" class="com.bjpowernode.ba06.School">
        <property name="name" value="清华大学"/>
        <property name="address" value="北京海淀区"/>
    </bean>
相关文章
|
3天前
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
3天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
2天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
7天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
40 6
|
23天前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
44 2
|
1月前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
1月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
44 0
|
2月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
80 0
|
2月前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
88 0
|
2月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
58 0