Spring控制反转思想的实现依赖注入
1. 依赖注入概述
依赖注入(DI:Dependency Injection)
2.基于XML配置的注入
通常有两种注入方式
案例1:在Spring容器中配置Bean,利用setter方法,完成该对象属性的初始化注入
setter方法注入是Spring框架中最主流的注入方式灵活且可读性高。通过<property>标签来完成注入配置
打开上节的项目spring6,新增模块spring-di-xml
修改模块spring-di-xml的pom.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>
实体类的属性如下 :
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 {
@Test
public void getEntity(){
// 加载Spring核心配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");
// 获取bean对象
Customer customerBean = (Customer) ctx.getBean("customerBean");
// 输出
System.out.println(customerBean);
}
}
运行结果:
2.2、使用构造方法注入
修改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 {
@Test
public void getEntity(){
// 加载Spring核心配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");
// 获取bean对象
Customer customerBean = (Customer) ctx.getBean("customerBean2");
// 输出
System.out.println(customerBean);
}
}
运行结果:
3、基于XML配置的注入
案例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;
}
@Override
public 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;
}
@Override
public 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;
}
@Override
public String toString() {
return "Fighter{" +
"name='" + name + '\'' +
", weapon=" + weapon +
", skills=" + skills +
'}';
}
}
配置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 {
@Test
public void getEntity(){
// 加载Spring核心配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");
// 获取bean对象
Fighter fighterBean = (Fighter) ctx.getBean("fighterBean");
// 输出
System.out.println(fighterBean);
}
}
运行结果:
4.基于注解的配置
现在更青睐使用注解(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实例名称
文件架构:
UserDao
UserService
UserController
Spring.xml:
步骤1:为每个类添加对应的注解
步骤2:配置注解自动扫描的范围
需要研究的内容
经测试,jdk22环境下,无法正常运行,提示加载类异常
调整为jdk17后程序正常(演示调整jdk版本)
需研究jdk22下spring6的兼容性问题
原文地址:https://blog.csdn.net/m0_73302939/article/details/143475292
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!