欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > Spring控制反转思想的实现依赖注入

Spring控制反转思想的实现依赖注入

2025/5/4 6:19:43 来源:https://blog.csdn.net/m0_73302939/article/details/143475292  浏览:    关键词:Spring控制反转思想的实现依赖注入

1. 依赖注入概述

依赖注入(DIDependency Injection

控制 反转 指的是将对象 (Bean) 交给 Spring 容器创建
依赖 注入 通过 Spring 容器 动态地为 对象 (Bean ) 属性 赋值,也 可理解 属性注入
控制 反转的 实现方式有多种,依赖注入是其中之一
Spring容器支持如下 两种属性 注入方式
基于 XML 配置的注入
基于注解的注入

 2.基于XML配置的注入

通常有两种注入方式

一种是使用属性的 setter 方法 注入
另一种是使用 构造方法 注入

案例1:在Spring容器中配置Bean,利用setter方法,完成该对象属性的初始化注入

setter方法注入Spring框架中最主流的注入方式灵活且可读性高。通过<property>标签来完成注入配置

打开上节的项目spring6,新增模块spring-di-xml

 

修改模块spring-di-xmlpom.xml,导入以下依赖 

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.flowerfog</groupId><artifactId>Spring6</artifactId><version>1.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath> <!-- 确认父项目路径 --></parent><artifactId>spring-di-xml</artifactId><packaging>war</packaging><name>spring-di-xml Maven Webapp</name><url>http://maven.apache.org</url><dependencies><!--spring context依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.2</version></dependency><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.3.1</version></dependency><!--log4j2的依赖--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.19.0</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.19.0</version></dependency></dependencies><build><finalName>spring-di-xml</finalName></build><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties>
</project>

实体类的属性如下 :

利用自动代码生成机制,编写全部属性的 getter setter 方法
利用自动代码生成机制,编写 toString 方法
package org.flowerfog.pojo;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Customer {private String id; // 主键private String name; // 姓名private List<String> addrList; // 收货地址private Map<String, String> collectGoodsMap; //收藏商品private Set<String> contactInfoSet; // 联系方式private String[] hisQryGoodsTypeArray; // 历史搜索商品类型public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<String> getAddrList() {return addrList;}public void setAddrList(List<String> addrList) {this.addrList = addrList;}public Map<String, String> getCollectGoodsMap() {return collectGoodsMap;}public void setCollectGoodsMap(Map<String, String> collectGoodsMap) {this.collectGoodsMap = collectGoodsMap;}public Set<String> getContactInfoSet() {return contactInfoSet;}public void setContactInfoSet(Set<String> contactInfoSet) {this.contactInfoSet = contactInfoSet;}public String[] getHisQryGoodsTypeArray() {return hisQryGoodsTypeArray;}public void setHisQryGoodsTypeArray(String[] hisQryGoodsTypeArray) {this.hisQryGoodsTypeArray = hisQryGoodsTypeArray;}@Override    public String toString() {return "Customer{" +"id='" + id + '\'' +", name='" + name + '\'' +", addrList=" + addrList +", collectGoodsMap=" + collectGoodsMap +", contactInfoSet=" + contactInfoSet +", hisQryGoodsTypeArray=" + Arrays.toString(hisQryGoodsTypeArray) +'}';}}

 添加Spring核心配置文件

注册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="customerBean" class="org.flowerfog.pojo.Customer"><property name="id" value="1" /><property name="name" value="张三" /><property name="addrList"><list><value>重庆市xxxx</value><value>重庆市xxxxx</value>
</list>
</property><property name="collectGoodsMap"><map><entry key="c1" value="G002" /><entry key="c2" value="G006" /></map></property><property name="contactInfoSet"><set><value>15223025311</value><value>023-62846626</value></set></property><property name="hisQryGoodsTypeArray"><array><value>电子书</value><value>笔记本电脑</value></array></property>
</bean></beans>

测试属性注入效果 

import org.flowerfog.pojo.Customer;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class CustomerTest {@Testpublic void getEntity(){// 加载Spring核心配置文件ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");// 获取bean对象Customer customerBean = (Customer) ctx.getBean("customerBean");// 输出System.out.println(customerBean);}
}

运行结果:

2.2、使用构造方法注入 

Spring 框架可以采用 Java 反射机制,通过 构造方法 完成依赖注入
构造方法注入是通过 <constructor- arg > 标签 来完成注入配置

修改Customer类,新增构造方法 

public Customer(String id, String name, List<String> addrList, Map<String, String> collectGoodsMap, Set<String> contactInfoSet, String[] hisQryGoodsTypeArray) {this.id = id;this.name = name;this.addrList = addrList;this.collectGoodsMap = collectGoodsMap;this.contactInfoSet = contactInfoSet;this.hisQryGoodsTypeArray = hisQryGoodsTypeArray;}

配置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="customerBean" class="org.flowerfog.pojo.Customer"><property name="id" value="1" /><property name="name" value="张三" /><property name="addrList"><list><value>重庆市xxxxx</value><value>重庆市xxxxx</value></list></property><property name="collectGoodsMap"><map><entry key="c1" value="G002" /><entry key="c2" value="G006" /></map></property><property name="contactInfoSet"><set><value>15223025311</value><value>023-62846626</value></set></property><property name="hisQryGoodsTypeArray"><array><value>电子书</value><value>笔记本电脑</value></array></property></bean><bean id="customerBean2" class="org.flowerfog.pojo.Customer"><constructor-arg index="0" value="1"/><constructor-arg index="1" value="张三" /><constructor-arg index="2"><list><value>重庆市xxxxxx</value><value>重庆市xxxxxx</value></list></constructor-arg><constructor-arg index="3"><map><entry key="c1" value="G002" /><entry key="c2" value="G006" /></map></constructor-arg><constructor-arg index="4"><set><value>15223025311</value><value>023-62846626</value></set></constructor-arg><constructor-arg index="5"><array><value>电子书</value><value>笔记本电脑</value></array></constructor-arg></bean>
</beans>

测试属性注入效果 

import org.flowerfog.pojo.Customer;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class CustomerTest {@Testpublic void getEntity(){// 加载Spring核心配置文件ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");// 获取bean对象Customer customerBean = (Customer) ctx.getBean("customerBean2");// 输出System.out.println(customerBean);}
}

 运行结果:

 

3、基于XML配置的注入

通过案例 1 ,我们了解了基于 XML 配置属性注入时如何将静态值的注入到属性
Spring 框架在属性注入时,还可引用 bean ,实现依赖注入

案例2某游戏程序中有三个类

Fighter(战士)

Weapon(武器)

Skill(技能)

每个战士有一个武器属性与一个技能列表属性

使用Spring IOC配置一名战士并完成属性注入 

根据题目要求,三个类的依赖关系如下:

编写武器类 

package org.flowerfog.pojo;public class Weapon {private String name; // 武器名称private int attack; // 攻击力public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAttack() {return attack;}public void setAttack(int attack) {this.attack = attack;}@Overridepublic String toString() {return "Weapon{" +"name='" + name + '\'' +", attack=" + attack +'}';}
}

 编写技能类

package org.flowerfog.pojo;public class Skill {private String name; // 技能名称private String desc; // 技能描述public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}@Overridepublic String toString() {return "Skill{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}
}

编写战士类

package org.flowerfog.pojo;import java.util.List;public class Fighter {private String name; // 战士名称private Weapon weapon; // 武器private List<Skill> skills; // 技能包public String getName() {return name;}public void setName(String name) {this.name = name;}public Weapon getWeapon() {return weapon;}public void setWeapon(Weapon weapon) {this.weapon = weapon;}public List<Skill> getSkills() {return skills;}public void setSkills(List<Skill> skills) {this.skills = skills;}@Overridepublic String toString() {return "Fighter{" +"name='" + name + '\'' +", weapon=" + weapon +", skills=" + skills +'}';}
}

配置Bean:武器对象、技能对象 

Spring.xml 文件中配置以下三个 bean

<bean id="weaponBean-GreenDragonCrescentBlade" class="org.flowerfog.pojo.Weapon"><property name="name" value="青龙偃月刀" /><property name="attack" value="1500" /></bean><bean id="skillBean-RidingFirst" class="org.flowerfog.pojo.Skill"><property name="name" value="一骑当先" /><property name=“desc" value="获得加速" /></bean><bean id="skillBean-StartASoloRun" class="org.flowerfog.pojo.Skill"><property name="name" value="单刀赴会" /><property name=“desc" value="获得攻击" /></bean>

步骤3 Spring容器中配置1名战士并完成属性注入 

 

<bean id="fighterBean" class="org.flowerfog.pojo.Fighter"><property name="name" value="青龙偃月刀" /><property name="weapon" ref="weaponBean-GreenDragonCrescentBlade" /><property name="skills"><list><ref bean="skillBean-RidingFirst" /><ref bean="skillBean-StartASoloRun" /></list></property></bean>

测试属性注入效果 

import org.flowerfog.pojo.Fighter;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class FighterTest {@Testpublic void getEntity(){// 加载Spring核心配置文件ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");// 获取bean对象Fighter fighterBean = (Fighter) ctx.getBean("fighterBean");// 输出System.out.println(fighterBean);}
}

 运行结果:

 

4.基于注解的配置

基于 XML 配置 的依赖注入 曾经 是最主要的配置方式
但是如果有大量的 Bean 需要装配,会导致 XML 配置文件过大,不便维护

 现在更青睐使用注解(annotation)的方式去装配Bean

Spring框架中定义了一系列注解

1.配置Bean的注解

  • @Component:可以作用在任何层次上
  • @Repository:用于数据访问层(DAO)
  • @Service:用于业务逻辑层(Service)
  • @Controller:用于控制器层(Controller)
  • @Configure:用于配置作用的类

以上注解的作用是一样的,都可以将加了注解的类配置到容器中,只是习惯性的应用于不同的层次中

2.完成依赖注入的注解

  • @Autowired:通过该注解可以消除setter和getter方法,默认按照Bean的类型进行装配
  • @Resource:和@Autowired功能是一样的,区别在于该注解默认是按照名称来装配注入的,通过name来指定Bean实例名称
  • @Qualifier:该注解与@Autowired注解配合使用,当@Autowired注解需要按照名称来装配注入时,使用该注解指定Bean实例名称

项目中有类 UserController UserService UserDao
UserController 定义属性 userService ,依赖 UserService
UserService定义属性 userDao , 依赖 UserDao

 文件架构:

UserDao

UserService 

 UserController

Spring.xml:

 

 步骤1:为每个类添加对应的注解

步骤2:配置注解自动扫描的范围

需要研究的内容 

经测试,jdk22环境下,无法正常运行,提示加载类异常

调整为jdk17后程序正常(演示调整jdk版本)

需研究jdk22下spring6的兼容性问题

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词