一幅长文细学Spring(三)——DI

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 本文讲述了依赖以及依赖注入

3 DI

3.1 依赖注入之setter注入

说明:依赖注入实际上就是为当前bean中属性赋值的一个过程;在Spring中想要实现这个过程实际上非常简单,只需要在配置文件中为对应的bean标签创建子级标签property,name属性指定bean中的属性名,value属性可以为bean中属性赋值;以上的方式实际上是通过set方法来给属性赋值,故bean对应的类中必须包含有set方法。

步骤演示

image-20220929112323423

一、创建一个Student类

package di;

public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}

二、在配置文件中配置好bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="Student" class="di.Student">
        <property name="id" value="001"></property>
        <property name="name" value="ArimaMisaki"></property>
        <property name="age" value="18"></property>
        <property name="sex" value="男"></property>
    </bean>
</beans>

三、写测试类

import di.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class locTest {
    @Test
    public void locTestMethod() {
        ClassPathXmlApplicationContext loc = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = loc.getBean(Student.class);
        System.out.println(student);
    }
}


3.2 依赖注入之构造器注入

说明:除了通过set方法实现依赖注入,通过有参构造器注入也是可以的;详细的步骤是在对应的bean标签中写上constructor-arg子标签,子标签的顺序对应构造器的顺序,通过value可以按顺序给构造器中的属性进行赋值。

提示:如果不想按构造器的顺序来给属性赋值,可以使用constructor-arg标签中的name属性来指定bean对应的属性。

步骤演示

image-20220929112844088

一、创建Student类

该类中必须含有有参构造,因为该依赖注入方式通过有参构造注入

package di;

public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;

    public Student(Integer id, String name, Integer age, String sex) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}

二、编写配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="Student" class="di.Student">
        <constructor-arg value="001"></constructor-arg>
        <constructor-arg value="ArimaMisaki"></constructor-arg>
        <constructor-arg value="18"></constructor-arg>
        <constructor-arg value="男"></constructor-arg>
    </bean>
</beans>

三、编写测试类

import di.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class locTest {
    @Test
    public void locTestMethod() {
        ClassPathXmlApplicationContext loc = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = loc.getBean(Student.class);
        System.out.println(student);
    }
}


3.3 特殊值处理

空值:如果一个属性是空值的话,要么可以不为该属性赋值,要么可以使用null子标签来表示属性为空。

特殊符号:如果想要在属性值中加入特殊符号,那么必须使用xml字符实体。

CDATA节:CDATA中的字段会被XML解析为纯文本数据,故CDATA字节可随意写特殊符号;想要在Spring配置文件中写入CDATA节,则需要用value标签包裹,然后输入大写的CD即可生成CDATA节。


3.4 为类类型属性赋值

引用方式:在一个类中使用另外一个类并且实例化对象是常有的事,当我们把对象交给了容器管理后,如果在对象中声明另外一个类呢,这时候就需要使用到bean标签的ref属性了。

级联方式:不适用ref来引用,直接通过name属性以.的形式来定位也是可以的,但这种方式并不好用,因为它要求class必须已经实例化后才能通过.的方式通过name属性赋值。

内部bean方式:通过在property标签中再一次使用bean标签也可以达到我们的目标。

步骤演示

image-20220929114139127

一、编写学生类

package di;

public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;
    private Clazz clazz;

    public Student(Integer id, String name, Integer age, String sex, Clazz clazz) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.clazz = clazz;
    }

    public Student(){}

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Clazz getClazz() {
        return clazz;
    }

    public void setClazz(Clazz clazz) {
        this.clazz = clazz;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", clazz=" + clazz +
                '}';
    }
}

二、编写班级类

package di;

public class Clazz {
    private Integer cid;
    private String cname;

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Clazz{" +
                "cid=" + cid +
                ", cname='" + cname + '\'' +
                '}';
    }
}

三、配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="Student" class="di.Student">
        <property name="id" value="001"></property>
        <property name="name" value="ArimaMisaki"></property>
        <property name="age" value="18"></property>
        <property name="sex" value="男"></property>
        <property name="clazz" ref="Class"></property>
    </bean>

    <bean id="Class" class="di.Clazz">
        <property name="cid" value="201916"></property>
        <property name="cname" value="终极一班"></property>
    </bean>
</beans>

四、编写测试类

import di.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class locTest {
    @Test
    public void locTestMethod() {
        ClassPathXmlApplicationContext loc = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = loc.getBean(Student.class);
        System.out.println(student);
    }
}


3.5 为容器类型属性赋值

数组:为数组类型的属性赋值只需通过property的子标签array,array标签中使用value或ref标签来为属性赋值。

list

  1. 为list类型的属性赋值只需通过property的子标签list,list标签中使用value或ref标签来为属性赋值
  2. 如果想要配置一个list集合类型的bean,则需要使用util的约束,list的成员为ref标签,ref标签使用bean属性来选择相应的bean

map

  1. 为map类型的属性赋值只需通过property的子标签map,map标签中使用enrty标签,并指定相应的key和value即可。
  2. 当然也可以采用utill的约束写法。


3.6 P命名空间

说明:前面的依赖注入似乎过于繁琐,我们可以通过p:的约束来使用p:命名空间,这样的话,命名空间中拥有所有可操作的属性。


3.7 数据源对象管理

说明:有些第三方库并非我们书写,故将其交给容器管理时,类的路径不能向传统一样书写,这个时候我们需要找到他们在Maven中类的存放路径。

image-20221001221019671

步骤

  1. 导入druid和mysql坐标;这里有个坑,druid别导入错误了,要导入阿里巴巴的而不是apache的。

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.6</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.28</version>
            </dependency>
  2. 新建一个spring-datasource配置文件;这里最好采用setter注入,因为我们不清楚构造器的参数顺序;一切结束后,可以试着运行一下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql://localhost:3306/"></property>
            <property name="username" value="root"></property>
            <property name="password" value="123456"></property>
        </bean>
    </beans>
  3. 新建一个DataSourceTest测试类

    import com.alibaba.druid.pool.DruidDataSource;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.sql.SQLException;
    
    public class DataSourceTest {
        public void testDataSource() throws SQLException {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-datasource.xml");
            DruidDataSource druidDataSource = ioc.getBean(DruidDataSource.class);
            System.out.println(druidDataSource.getConnection());
        }
    }
  4. 也可以结合Mybatis的使用方式,将连接属性写到配置文件中;使用Resource Bundle创建一个jdbc配置文件,回车后书写内容。

    image-20221001222852009

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/
    username=root
    password=123456
  5. 修改配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    <!--    访问配置文件需要使用context约束 -->
        <context:property-placeholder location="jdbc.properties"></context:property-placeholder>
    
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driver}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
    </beans>
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7月前
|
Java Spring
Spring5深入浅出篇:Spring中ioc(控制反转)与DI(依赖注入)
Spring5深入浅出篇:Spring中ioc(控制反转)与DI(依赖注入)
|
7月前
|
Java API Spring
Spring6-IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入,手动实现IOC
Spring6-IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入,手动实现IOC
|
7月前
|
XML Java 数据格式
Spring框架入门:IoC与DI
【5月更文挑战第15天】本文介绍了Spring框架的核心特性——IoC(控制反转)和DI(依赖注入)。IoC通过将对象的创建和依赖关系管理交给容器,实现解耦。DI作为IoC的实现方式,允许外部注入依赖对象。文章讨论了过度依赖容器、配置复杂度等常见问题,并提出通过合理划分配置、使用注解简化管理等解决策略。同时,提醒开发者注意过度依赖注入和循环依赖,建议适度使用构造器注入和避免循环引用。通过代码示例展示了注解实现DI和配置类的使用。掌握IoC和DI能提升应用的灵活性和可维护性,实践中的反思和优化至关重要。
403 4
|
2月前
|
存储 Java 程序员
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
本文详细讲解了Spring框架中IOC容器如何存储和取出Bean对象,包括五大类注解(@Controller、@Service、@Repository、@Component、@Configuration)和方法注解@Bean的用法,以及DI(依赖注入)的三种注入方式:属性注入、构造方法注入和Setter注入,并分析了它们的优缺点。
37 0
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
|
2月前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
35 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
3月前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
3月前
|
Java 数据库连接 Maven
Spring基础1——Spring(配置开发版),IOC和DI
spring介绍、入门案例、控制反转IOC、IOC容器、Bean、依赖注入DI
Spring基础1——Spring(配置开发版),IOC和DI
|
6月前
|
存储 Java 测试技术
Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性
Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性
42 1
|
6月前
|
存储 Java 程序员
Spring IoC&DI(2)—IoC详解
Spring IoC&DI(2)—IoC详解
49 2
|
6月前
|
存储 Java C++
理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory
理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory