Spring中存储Bean的常见注解

目录

IoC & DI

IOC(控制反转)详解

依赖注入的三种方式


IoC & DI

IoC: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器.

控制反转:也就是控制权反转. 什么的控制权发⽣了反转? 获得依赖对象的过程被反转了
也就是说, 当需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创
建, 把创建对象的任务交给容器
, 程序中只需要依赖注⼊ (Dependency Injection,DI)就可以了.
这个容器称为:IoC容器. Spring是⼀个IoC容器, 所以有时Spring 也称为Spring 容器。

DI: Dependency Injection(依赖注⼊)
容器在运⾏期间, 动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊

依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过
引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。


IOC(控制反转)详解

共有两类注解类型可以实现Bean的存储:
1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration.
2. ⽅法注解:@Bean.

类注解

1、@Controller(控制器存储)

使⽤ @Controller 存储 bean 的代码如下所⽰: 

@Controller // 将对象存储到 Spring 中
public class UserController {public void sayHi(){System.out.println("hi,UserController...");}
}

表示将这个类的对象存储到ioc容器当中,并表明这是一个controller类。负责 接收请求, 对请求进⾏处理, 并进⾏响应。

2、@Service(服务存储)

使⽤ @Service 存储 bean 的代码如下所⽰:

@Service
public class UserService {public void sayHi(String name) {System.out.println("Hi," + name);}
}

表示将这个类的对象存储到ioc容器当中,并表明这是一个service类。负责处理具体的业务逻辑。

3、@Repository(仓库存储)

使⽤ @Repository 存储 bean 的代码如下所⽰:

@Repository
public class UserRepository {public void sayHi() {System.out.println("Hi, UserRepository~");}
}

表示数据访问层,也称为持久层. 负责数据访问操作

4、@Component(组件存储)

使⽤ @Component 存储 bean 的代码如下所⽰:

@Component
public class UserComponent {public void sayHi() {System.out.println("Hi, UserComponent~");}
}

 单纯将这个类的对象加入到ioc容器中,没有其他含义。

5、@Configuration(配置存储)

使⽤ @Configuration 存储 bean 的代码如下所⽰:

@Configuration
public class UserConfiguration {public void sayHi() {System.out.println("Hi,UserConfiguration~");}
}

表示配置层. 处理项⽬中的⼀些配置信息。

方法注解

@Bean

@Bean注解可以将类中的方法注入到ioc容器当中,使一个类可以拥有多个对象。

使用@Bean注解存储bean代码如下:

@Component
public class BeanConfig {@Beanpublic User user(){User user = new User();user.setName("zhangsan");user.setAge(18);return user;}
}

@Bean注解必须搭配@Component注解使用才能生效。否则无效。

@Bean注解的优势在于同一个类可以定义多个对象

@Component
public class BeanConfig {@Beanpublic User user1(){User user = new User();user.setName("zhangsan");user.setAge(18);return user;}@Beanpublic User user2(){User user = new User();user.setName("lisi");user.setAge(19);return user;}
}

类中的两个Bean对象的名称如下: 

可以通过设置 name 属性给 Bean 对象进⾏重命名操作,如下代码所⽰:

@Bean(name = {"u1","user1"})
public User user1(){User user = new User();user.setName("zhangsan");user.setAge(18);return user;
}

 依赖注入的三种方式

关于依赖注⼊, Spring给我们提供了三种⽅式:

1. 属性注⼊(Field Injection)

属性注⼊是使⽤ @Autowired 实现的,如将 Service 类注⼊到 Controller 类中.

Service 类的实现代码如下:

@Service
public class UserService {public void sayHi() {System.out.println("Hi,UserService");}
}

Controller 类的实现代码如下:

@Controller
public class UserController {//注⼊⽅法1: 属性注⼊
@Autowired
private UserService userService;public void sayHi(){System.out.println("hi,UserController...");userService.sayHi();}
}

最终结果如下:


2. 构造方法注⼊(Constructor Injection)

构造⽅法注⼊是在类的构造⽅法中实现注⼊,如下代码所示:

@Controller
public class UserController2 {
//注⼊⽅法2: 构造⽅法private UserService userService;@Autowiredpublic UserController2(UserService userService) {this.userService = userService;}public void sayHi(){System.out.println("hi,UserController2...");userService.sayHi();}
}

注意事项:如果类只有⼀个构造⽅法,那么 @Autowired 注解可以省略;如果类中有多个构造⽅法,那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法。

3. Setter 注⼊(Setter Injection)

Setter 注⼊和属性的 Setter ⽅法实现类似,只不过在设置 set ⽅法的时候需要加上 @Autowired 注
解 ,如下代码所⽰:

@Controller
public class UserController3 {
//注⼊⽅法3: Setter⽅法注⼊
private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void sayHi(){System.out.println("hi,UserController3...");userService.sayHi();}
}

 特殊情况:当同一类型存在多个bean对象时,使用@Autowired会出现问题。

@Component
public class BeanConfig {@Bean("u1")public User user1(){User user = new User();user.setName("zhangsan");user.setAge(18);return user;}@Beanpublic User user2() {User user = new User();user.setName("lisi");user.setAge(19);return user;}
}
@Controller
public class UserController {
@Autowired
private UserService userService;
//注⼊user
@Autowired
private User user;public void sayHi(){System.out.println("hi,UserController...");userService.sayHi();System.out.println(user);}
}

spring提供了以下解决方案:

@Primary

使⽤@Primary注解:当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现.

@Component
public class BeanConfig {
@Primary //指定该bean为默认bean的实现@Bean("u1")public User user1(){User user = new User();user.setName("zhangsan");user.setAge(18);return user;}@Beanpublic User user2() {User user = new User();user.setName("lisi");user.setAge(19);return user;}
}

 @Qualifier

使⽤@Qualifier注解:指定当前要注⼊的bean对象。 在@Qualifier的value属性中,指定注⼊的bean的名称。
• @Qualifier注解不能单独使⽤,必须配合@Autowired使⽤

@Controller
public class UserController {
@Qualifier("user2") //指定bean名称
@Autowired
private User user;public void sayHi(){System.out.println("hi,UserController...");System.out.println(user);}
}

 @Resource

使⽤@Resource注解:是按照bean的名称进⾏注⼊。通过name属性指定要注⼊的bean的名称。

@Controller
public class UserController {
@Resource(name = "user2")
private User user;public void sayHi(){System.out.println("hi,UserController...");System.out.println(user);}
}

常⻅⾯试题:
@Autowird 与 @Resource的区别
• @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解
• @Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐于 @Autowired 来说,
@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean。

以上关于IOC与DI,希望对你有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/143753.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计污染物文献共享数据库管理系统网站开发与实现

计算机毕业设计:污染物文献共享数据库管理系统网站开发与实现 1. 项目背景 随着环境问题日益严峻,对污染物的研究变得尤为重要。然而,在学术界和工业界之间存在着信息孤岛现象,即大量的研究成果被分散在不同的数据…

每日OJ题_牛客_除2!(贪心+堆)

目录 牛客_除2!(贪心堆) 解析代码 牛客_除2!(贪心堆) 除2!_牛客题霸_牛客网 解析代码 弄一个堆模拟一下,用到贪心的思想,记得开long long,否则可能0分。 …

Python中的异步编程:从基础知识到高级应用

随着互联网应用的不断发展,高并发和高性能成为越来越多开发者关注的重点。Python 3.5引入了asyncio库和async/await语法,使得异步编程变得更加简洁和高效。本文将详细介绍Python中的异步编程,从基础知识到高级应用,帮助你掌握这一…

【AI大模型】LLM主流开源大模型介绍

目录 🍔 LLM主流大模型类别 🍔 ChatGLM-6B模型 2.1 训练目标 2.2 模型结构 2.3 模型配置(6B) 2.4 硬件要求 2.5 模型特点 2.6 衍生应用 🍔 LLaMA模型 3.1 训练目标 3.2 模型结构 3.3 模型配置(7B) 3.4 硬件…

ROS第四梯:ROS项目中添加自定义类

第一步,ROS项目结构介绍 工作空间中包含一个名为pcl_ros_test的功能包,其中main.cpp是原有项目自带的,接下来以CommonAlg自定义类添加为例进行介绍。 第二步:头文件CommonAlg.h创建和编写,并保存在include/pcl_ros_tes…

springcloud整合nacos、sentinal、springcloud-gateway,springboot security、oauth2总结

源码地址:下载地址 使用该架构的项目地址:下载地址 下面教大家整合nacos、sentinal、springcloud-gateway,springboot security、oauth2做一个分布式架构 1、第一步整合nacos 1、下载alibaba的nacos 下载地址,然后使用单机模式启动nacos sh startup.sh -m standalon…

828华为云征文 | 云服务器Flexus X实例,搭建上线前后端项目

828华为云征文 | 云服务器Flexus X实例,搭建上线前后端项目 项目搭建 演示使用华为云服务器Flexus X实例搭建上线前后端项目黑马vue电商后台管理系统 项目GitHub链接:https://github.com/Minori-ty/vue_shop.git 1、购买华为云 Flexus X 实例 Flexus云服…

搜索小车运动最短路径python代码实现

一、实验任务 场地中正方格代表障碍物,选取小车运动起点和终点。编程探究小车从起点运动到终点,总共有几种可行的路径(路径不含重叠部分),同时找出最短路径并可视化。 二、实验思路 把场地抽象化为69的平面矩阵&…

基于Linux系统离线安装oracle数据库

注意事项: 在安装的时候多次涉及root用户和oracle用户的切换,请注意区分,本文已明显 一、环境准备 1、关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld2、 禁用NetworkManager服务(非必须) [rootlocalhost …

4 路 4-20mA 电流/0-10V 电压转光纤

型号:MS-F155-AM 功能概述 MS-F155-AM 是将 4-20mA 电流转为光纤信号的模块,分发送和接收两个设备。发送模块将电流或者电压信号转变为光信号,通过光纤传输,接收端将光信号还原为电流或者电压信号。可以延长通信距离,最…

从零开始讲DDR(1)——DDR简介

一、DDR简介 DDR SDRAM(Double Data Rate Synchronous DYNAMIC RAM)中文名是:双倍数据速率同步动态随机存储器。 传统的SDRAM只在时钟信号的上升沿传输数据,而DDR可以同时在时钟的上升沿和下降沿传输数据,因此在同样的…

零信任安全架构--持续验证

随着网络安全威胁的不断演变,传统的“信任但验证”安全模式已无法应对现代复杂的攻击。零信任安全架构(Zero Trust Architecture, ZTA)应运而生,作为一种全新的安全理念,它彻底改变了企业的网络安全防护方式。核心思想…

windows查找端口号被占用

在很多开发的时候,可能端口号有被占用的情况,导致项目打不开。 用下面这个命令即可: 比如我的3000端口被占用,我找找哪个进程在占用我的3000端口号

JAVA惊喜连连无限可能沉浸式盲盒商城系统小程序源码

🎁惊喜连连,无限可能!沉浸式盲盒商城系统,等你来探索🔍 🎉【开篇:盲盒热潮,席卷而来】🎉 在这个充满未知与惊喜的时代,盲盒文化正以前所未有的速度席卷全球…

Vue学习记录之五(组件/生命周期)

一、组件 在每一个.vue文件可以看作是一个组件,组件是可以复用的,每个应用可以看作是一棵嵌套的组件树。 在Vue3中,组件导入以后即可直接使用。 二、组件的生命周期 生命周期就是从诞生(创建)到死亡(销毁) 的过程。 Vue3 组合式API中(se…

Rocky 8.7 操作系统 安装部署 MySQL 5.7.32 验证测试

一、安装部署 主从服务器都需提前安装部署MySQL 5.7.32 数据库软件,本次选择采用二进制安装。 配置主从,要注意调整主备库server_id不能保持一致。 主库修改/etc/my.cnf文件,添加 server-id1log-binmysql-binbinlog-do-dbmsdbbinlog-ign…

java se 快速入门

文章目录 java se 快速入门Java 简介Java的优点jdk 和 jre安装jdk配置环境变量Java 语法快速入门程序入口文件名类规范 基本语法注释变量和常量输入输出条件语句循环语句 基本数据类型Java字符串常用方法字符串拼接java字节数组和字符串相互转化java字符数组和字符串相互转换ja…

传输层协议 —— TCP协议(上篇)

目录 1.认识TCP 2.TCP协议段格式 3.可靠性保证的机制 确认应答机制 超时重传机制 连接管理机制 三次握手 四次挥手 1.认识TCP 在网络通信模型中,传输层有两个经典的协议,分别是UDP协议和TCP协议。其中TCP协议全称为传输控制协议(Tra…

torch.embedding 报错 IndexError: index out of range in self

文章目录 1. 报错2. 原因3. 解决方法 1. 报错 torch.embedding 报错: IndexError: index out of range in self2. 原因 首先看下正常情况: import torch import torch.nn.functional as Finputs torch.tensor([[1, 2, 4, 5], [4, 3, 2, 9]]) embedd…