当前位置: 首页 > news >正文

spring学习(spring-DI(setter注入、构造器注入、自动装配方式))

目录

前言

setter注入

使用步骤

demo(案例)

构造器注入

使用步骤

demo(案例)

自动装配

byName

byType


前言

在spring 框架中 loc 容器 帮助我们创建对象,dl 依赖注入主要则是帮助我们具体的使用 创建的对象。我们清楚 对象被使用的应用场景有:

  •  某类中作为成员变量

因此 我们知道 Dl  依赖注入 大体上 是解决 一个问题

1 当对象做为类中的成员变量时,我们应该如何为该成员变量 赋值 

因此 Dl 依赖注入 有如下图三种方式

setter注入

使用步骤

1 spring配置文件中 使用 property 标签 ,表示每一个 属性信息

2 在目标类中 提供 set 方法

核心标签<property name="?" ref="?">。

注意:

name属性值一定要与使用依赖注入的类的成员变量名相同

ref 属性值是真正传递的对象

demo(案例)

项目准备

整个项目结构

目的

UserServlet 测试类中 当 id=1,name="李华",age=18 ,打印 user 类对象

最终效果展示

spring配置文件

图片展示

spring配置文件代码

<?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 class="fs.service.lmpl.UserServiceImpl" id="userService">
    <property name="userDao" ref="UserDaoImpl"></property>
</bean>
    <bean id="UserDaoImpl" class="fs.Dao.lmpl.UserDaoImpl">
<!-- <constructor-arg name="user" ref="User"></constructor-arg>-->
        <property name="user" ref="User"></property>
    </bean>
    <bean id="User" class="fs.entity.User">
        <constructor-arg index="0" value="1"></constructor-arg>
        <constructor-arg index="1" value="李华"></constructor-arg>
        <constructor-arg index="2" value="18"></constructor-arg>
    </bean>

</beans>
UserDaoImpl 类

图片展示

UserDaoImpl 类代码

package fs.Dao.lmpl;

import fs.Dao.UserDao;
import fs.entity.User;
public class UserDaoImpl implements UserDao {
    private User user;

//    public UserDaoImpl(User user) {
//        this.user = user;
//    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public void add() {
        System.out.println(user);
    }

}
UserServiceImpl 类 
图片展示

UserServiceImpl 类 代码

package fs.service.lmpl;

import fs.Dao.UserDao;
import fs.Dao.lmpl.UserDaoImpl;
import fs.service.UserService;

public class UserServiceImpl  implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void add() {
        userDao.add();
    }


}
UserServlet 测试类
package fs.web;

import fs.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServlet {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
}

运行结果

构造器注入

使用步骤

1 在 spring 配置文件 使用 constructor-arg 标签 表示 构造方法 的参数,参数的传递 

2 在某类中 创建目标对象的构造方法

核心标签

<constructor-arg index/name=? value/ref=?></constructor-arg>

提示:value 一般用于 基本数据类型; ref 多用于对象

注意 

把之前spring配置文件里面的<property>标签换成<constructor-arg>标签即可。其中属性"ref"的值为依赖注入的类对应标签<bean>所绑定的id即可。

demo(案例)

  • 和之前相比需要修改的地方

1 spring配置文件

2 在目标类中,添加 构造方法

效果展示

自动装配

关于自动装配的介绍

  • 自动注入需要用到 autowire 属性 ,不需要我们手动在 spring 配置文件 里使用 标签去配置
  • autowire 的属性值有 byName 或 byType
  • 自动装配的底层逻辑 其实和 setter 注入的方式一样,只是自动装配省略了在 配置文件中专门给 属性添加 property 标签 

byName

当 autowire 的属性值 为 byName 时 ,spring 容器在创建对象后 为目标类中的属性 实现自动装配。如spring 容器查看 A 类的所有属性,将已经创建成功的bean【对象】和属性名要求匹配(spring 配置文件的 bean 标签 id 和 类中的属性名相同),并使用set 方法注入


案例演示

springConfig .xml 配置文件

<?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 class="fs.exerise04.A" id="a" autowire="byName"></bean>
    <bean class="fs.exerise04.B" id="b"></bean>
    <bean class="fs.exerise04.C" id="c"></bean>



</beans>

在 A 类提供属性b,c  和 set 方法 进行检验

package fs.exerise04;

public class A {
    private B b;
    private C c;

    public void setB(B b) {
        this.b = b;
    }

    public void setC(C c) {
        this.c = c;
    }

    public void test (){
        System.out.println("aaaaaaaa");
        b.print();
        c.test();
    }
}

效果展示

发现 : autowire 属性 已经成功和 目标类的属性 各自实现了注入

推论1 

bean 标签的 id的属性值 和 类中的 对应的set方法名对应 

如 id =a, 对应的setA()


改动的spring 配置文件 

  <bean class="fs.exerise04.B" id="b1"></bean>

效果展示(未修改前)

提示 NullPointerException表示没有通过set赋值,给目标类的属性


修改 目标类中的对应的set 方法名

    public void setB1(B b) {
        this.b = b;
    }

效果展示

结论1 :bean 标签的 id的属性值 和 类中的 对应的set方法名相对应

推论2

bean 标签中的 id 不能为大写,即使和 set方法名相对应也会报错

  <bean class="fs.exerise04.B" id="Bb"></bean>

目标类中的set方法

效果展示

提示:即使 b 类set方法和 b类bean 标签的id 相对应,也无法成功调用set 方法创建b 类对象

结论2 :bean 标签的 id 都应该小写


byType

当 autowire 的属性值 为 byType 时 ,spring 容器会检查当前 目标类中的属性的 数据类型 和配置文件的bean 标签 进行匹配。如spring 容器查看 A 类的所有属性,将已经创建成功的bean【对象】和各个属性的数据类型相同的一个或多个匹配起来

案例演示

springConfig .xml 配置文件

<?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 class="fs.exerise04.A" id="a" autowire="byType">

</bean>
    <bean class="fs.exerise04.B" id="Bbb"></bean>
    <bean class="fs.exerise04.C" id="cc"></bean>



</beans>

在 A 类提供属性b,c  和 set 方法 进行检验

package fs.exerise04;

public class A {
    private B b;
    private C c;

    public void setBb(B b) {
        this.b = b;
    }

    public void setC(C c) {
        this.c = c;
    }

    public void test (){
        System.out.println("aaaaaaaa");
        b.print();
        c.test();
    }
}

效果展示

发现:即使 id 和 目标类中的set 方法名不一致。但只要 数据类型保持一致


注意 :set 方法注入相同类型的对象在 spring 配置文件只能有一个bean 标签,否则会报错

    <bean class="fs.exerise04.B" id="Bbb"></bean>
    <bean class="fs.exerise04.B" id="bb"></bean>

相关文章:

  • 在 CentOS 系统中配置交换空间(Swap)解决内存不足
  • Android和DLT日志系统
  • 13.推荐系统的性能优化
  • Go语言协程Goroutine高级用法(一)
  • 分布式版本控制系统---git
  • 【openresty服务器】:源码编译openresty支持ssl,增加service系统服务,开机启动,自己本地签名证书,配置https访问
  • 基于巨控GRM552YW-CHE:西门子S7-1200 PLC远程程序上下载与实时调试方案
  • spring cloud 使用 webSocket
  • 怎麼使用靜態住宅IP進行多社媒帳號管理
  • A4988一款带转换器和过流保护的 DMOS 微步驱动器的使用方式
  • 探索高通骁龙游戏超分辨率技术:移动游戏的未来
  • 20240911 光迅科技 笔试
  • ProxySQL构建PolarDB-X标准版高可用路由服务三节点集群
  • 理解WebGPU 中的 GPUDevice :与 GPU 交互的核心接口
  • 【时时三省】(C语言基础)简单的算法举例
  • leetcode-495.提莫攻击
  • 或非门组成的SR锁存器真值表相关问题
  • LLM:GPT 系列
  • C#关于静态关键词static详解
  • vue 文件下载(导出)excel的方法
  • 澎湃读报丨央媒头版集中刊发社论,庆祝“五一”国际劳动节
  • 迎接八方来客:全国多地“五一”假期党政机关大院停车场免费开放
  • 住房和城乡建设部办公厅主任李晓龙已任部总工程师
  • 锦江酒店:第一季度营业收入约29.42亿元,境内酒店出租率同比增长
  • 国泰海通合并后首份业绩报告出炉:一季度净利润增逾391%
  • AI观察|算力饥渴与泡沫