【IoCDI】_@Autowired存在的问题及解决

ops/2025/2/11 1:24:27/

目录

1. @Autowired存在问题

2. 解决方法

2.1 方法1:属性名与需要使用的对象名保持一致

2.2 方法2:使用@Primary指定要使用的对象

2.3 方法3:使用@Qualifier指定要使用的对象

2.4 方法4:使用@Resource指定要使用的对象

3. 关于@Autowired和@Resource的区别


在上文中,已经介绍了依赖注入的三种方式:

【IoC&DI】_三种属性注入(DI)方式-CSDN博客文章浏览阅读245次,点赞14次,收藏6次。关于IoC与DI,相关的基本内容如下:官网对于Spring Web MVC的介绍如下:链接如下:即Spring Web MVC是基于Servlet API构建的原始的Web框架,它从一开始就包含在Spring框架中,通常被称为Spring MVC;三层架构强调对数据进行不同维度的处理,如表现层进行数据的校验与返回,业务逻辑层进行数据的处理,数据层进行数据的存储等等。将对象的控制权交给Spring的IoC容器,由IoC容器实现对依赖对象的创建及管理。https://blog.csdn.net/m0_63299495/article/details/145438710https://blog.csdn.net/m0_63299495/article/details/145438710其中,使用@Autowired进行属性注入的方式简单且使用率高;

但@Autowired在使用时存在一些问题。

本文对@Autowired存在的问题进行描述并给出解决方案。


创建Service包,并在其下创建UserService类:

java">package com.example.iocdemo1.Service;
import org.springframework.stereotype.Service;
@Service
public class UserService {public void doService(){System.out.println("doService...");}
}

创建Config包,并在其下创建BeanConfig类,并使用方法注解提供两个返回UserInfo类型对象的方法,两个方法不同名一个为userInfo1,一个为userInfo2:

java">package com.example.iocdemo1.Config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfo1(){UserInfo userInfo2=new UserInfo();userInfo2.setId(1);userInfo2.setName("zhangsan");userInfo2.setAge(20);return userInfo2;}@Beanpublic UserInfo userInfo2(){UserInfo userInfo2=new UserInfo();userInfo2.setId(2);userInfo2.setName("lisi");userInfo2.setAge(21);return userInfo2;}
}

并在同一个包下提供UserInfo对象:

java">package com.example.iocdemo1.Config;import lombok.Data;@Data
public class UserInfo {private int id;private String name;private int age;
}

1. @Autowired存在问题

现以向UserController中注入UserInfo1对象和UserService对象为例。

创建Controller包,并在其下创建UserController类:

java">package com.example.iocdemo1.Controller;import com.example.iocdemo1.Config.UserInfo;
import com.example.iocdemo1.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate UserInfo userInfo;public void doController(){userService.doService();System.out.println(userInfo);System.out.println("do Controller...");}
}

在UserController中,试图使用类型为UserInfo的名为userInfo的属性 接收 类型为UserInfo的名为userInfo1的对象(即类型一致、名称不一致),运行程序:

程序启动失败。表示UserController在根据UserInfo类型查找对象时,找到了两个类型为UserInfo的对象。再根据属性名userInfo进行匹配,两个对象一个名为userInfo1,一个名为userInfo2,均无法匹配,故程序启动失败。

当程序中同一个类型有多个对象时,使用@Autowired进行属性注入有一定概率会报错

2. 解决方法

2.1 方法1:属性名与需要使用的对象名保持一致

现将UserController中的属性名和方法使用的实例名修改为userInfo2,即可实现对userInfo2对象的成功获取:

java">package com.example.iocdemo1.Controller;import com.example.iocdemo1.Config.UserInfo;
import com.example.iocdemo1.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate UserInfo userInfo2;public void doController(){userService.doService();System.out.println(userInfo2);System.out.println("doController...");}
}

重新启动程序:

2.2 方法2:使用@Primary指定要使用的对象

在多个注入的同类型对象的文件中(BeanConfig),在需要使用的对象前使用@Primary注解:

java">package com.example.iocdemo1.Config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;@Configuration
public class BeanConfig {@Primary@Beanpublic UserInfo userInfo1(){UserInfo userInfo2=new UserInfo();userInfo2.setId(1);userInfo2.setName("zhangsan");userInfo2.setAge(20);return userInfo2;}@Beanpublic UserInfo userInfo2(){UserInfo userInfo2=new UserInfo();userInfo2.setId(2);userInfo2.setName("lisi");userInfo2.setAge(21);return userInfo2;}
}

启动程序,usrInfo1对象获取成功,日志如下:

2.3 方法3:使用@Qualifier指定要使用的对象

在要获取对象的文件中(UserController),使用@Qualifier注解选择该属性需要的某个对象:

java">package com.example.iocdemo1.Controller;import com.example.iocdemo1.Config.UserInfo;
import com.example.iocdemo1.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate UserService userService;@Qualifier("userInfo1")@Autowiredprivate UserInfo userInfo;public void doController(){userService.doService();System.out.println(userInfo);System.out.println("doController...");}
}

启动程序,usrInfo1对象获取成功,日志如下:

注:使用@Qualifier时,需和@Autowired搭配使用(区别@Resource)

2.4 方法4:使用@Resource指定要使用的对象

在要获取对象的文件中(UserController),使用@Resourcer注解使用name属性执行该属性需要的某个对象:

java">package com.example.iocdemo1.Controller;import com.example.iocdemo1.Config.UserInfo;
import com.example.iocdemo1.Service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {// 属性注入@Autowiredprivate UserService userService;@Resource(name="userInfo2")private UserInfo userInfo;public void doController(){userService.doService();System.out.println(userInfo);System.out.println("doController...");}
}

启动程序,usrInfo2对象获取成功,日志如下:

注:1、使用@Resource时,可单独使用,无需和@Autowired搭配使用(区别@Qualifer)

2、实际开发中,使用频率最高的是@Autowired,当出现@Autowired关于同类型多对象的问题时,使用率最高的方法是使用@Qualifer搭配使用 或 改换为使用@Resource注解。

3. 关于@Autowired和@Resource的区别

(1)@Autowired 是spring框架提供的注解,只能在Spring框架中使用;

而@Resource是JDK提供的注解,并不被使用框架限制;

(2)@Autowired 默认是按照类型注入,如果有多个类型的对象,则按照名称匹配,若没有与属性同名的对象则报错;

@Resource是按照名称注入,相比于@Autowired,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean;


http://www.ppmy.cn/ops/157406.html

相关文章

Java 读取 PDF 模板文档并替换内容重新生成 PDF

朋友们!在实际开发里,经常会遇到需要根据 PDF 模板文档生成特定 PDF 的需求,比如合同、证书等。咱们可以借助 iText 库来实现读取 PDF 模板文档、替换指定内容,最后重新生成新 PDF 的功能。下面我就详细给大家讲讲具体怎么做。 1.…

全志A133 android10 thermal温控策略配置调试

一,功能介绍 Thermal简称热控制系统,其功能是通过temperature sensor(温度传感器)测量当前CPU、GPU等设备的温度值,然后根据此温度值,影响CPU、GPU等设备的调频策略,对CPU、GPU等设备的最大频率…

网络安全警示录:.wex勒索病毒的独特特性与应对之道

在数字化时代,网络安全威胁层出不穷,其中勒索病毒已成为企业和个人用户面临的一大挑战。近年来,.wex勒索病毒以其独特的加密方式和广泛的传播手段,给全球网络安全带来了严重威胁。本文将深入探讨.wex勒索病毒的独特特性&#xff0…

graylog初体验

最近graylog比较火,部署了一个来测试下,看下后续能不能代替目前占用资源比较多的elk,目前未对graylog性能进行深入测试,只是简单体验了下,graylog的UI比较简陋,但是在报警以及权限方面优于ELK,整…

信息安全、网络安全和数据安全的区别和联系

一、区别 1.信息安全 定义 信息安全是指为数据处理系统建立和采用的技术和管理的安全保护,保护计算机硬件、软件和数据不因偶然和恶意的原因而遭到破坏、更改和泄露。它的范围比较广泛,涵盖了信息的保密性、完整性和可用性等多个方面。 侧重点 更强…

瑞芯微 Rockchip 系列 RK3588 主流深度学习框架模型转成 rknn 模型教程

前言 在瑞芯微 Rockchip 芯片上进行 NPU 推理,需要先将模型文件转换成 rknn 模型文件,才能执行各种推理任务。本文将介绍如何安装各种工具,并最终实现将各种深度学习框架的模型文件转换成 rknn 文件。 本教程不仅适合 RK3588 平台&#xff…

windows phpstudy python cgi配置

修改apache配置文件:httpd.conf 搜索’Define SRVROOT’, 查看cgi根目录,python脚本需要放在该 Define SRVROOT "D:/Program/phpstudy_pro/Extensions/Apache2.4.39解决中文乱码 文件最后添加AddDefaultCharset gbk 重启apache python脚本: #!py…

SickOs 1.2靶机(超详细教学)

靶机地址:https://www.vulnhub.com/entry/sickos-12,144/ 一、主机发现 使用 arp-scan -l查找靶机ip地址 靶机ip地址为192.168.55.146 攻击机的ip地址为192.168.55.129 二、进行端口扫描、目录枚举、指纹识别 1.端口扫描 nmap 192.168.55.146发现靶机只有22和…