Spring 中存取 Bean 的相关注解

 

目录

 一、五大类注解

1、五大类注解存储Bean对象

1.1@Controller(控制器储存)

1.2@Service(服务存储)

1.3@Repository(仓库存储)

1.4@Component(组件存储)

1.5@Configuration(配置存储)

 2、五大类注解小结

2.1为什么要这么多类注解

2.2 五大类注解之间的关系 

二、方法注解

1.方法注解的存储

1.1 @Bean注解的使用

1.2 @Bean方法的重命名 

2.方法注解的获取

2.1 属性注入

2.2 Setter注入

2.3 构造方法注入

三、总结 

1.三种注⼊优缺点分析 

2.Resource和@Autowired的区别

 一、五大类注解

在Spring中,想要将Bean存储到Spring中,一共有两种注解类型可以实现:

一种是类注解,其包括@Controller,@Service,@Repository,@Component,@Configuration;

另一种则是方法注解,其仅有@Bean

1、五大类注解存储Bean对象

1.1@Controller(控制器储存)

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

package com.java.demo;
import org.springframework.stereotype.Controller;@Controller
public class User {public void sayHi(){System.out.println("hi User");}
}

我们再在启动类中,简单读取一下存入的对象

import com.java.demo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {ApplicationContext context = newClassPathXmlApplicationContext("srping-config.xml");User user = context.getBean("user", User.class);user.sayHi();}
}

运行结果如下: 

1.2@Service(服务存储)

使⽤ @Service 存储 Bean 的代码如下所示:

@Service
public class UserService {public int add(){System.out.println("hi UserService add");}
}

 读取 bean 的代码:

public class Test {public static void main(String[] args) {ApplicationContext context = newClassPathXmlApplicationContext("spring-config.xml");UserService userService =context.getBean("userService", UserService.class);userService.add();}
}

 运行结果如下:

1.3@Repository(仓库存储)

使用@Repository存储Bean的代码如下:

@Repository
public class UserRepository {public void add(){System.out.println("hi UserRepository add");}
}

 读取Bean的代码:

public class Test {public static void main(String[] args) {ApplicationContext context = newClassPathXmlApplicationContext("spring-config.xml");UserRepository userRepository =context.getBean("userRepository", UserRepository.class);userRepository.add();}
}

 运行结果如下:

1.4@Component(组件存储)

使用@Component组件存储Bean的代码如下:

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

 读取Bean的代码:

public class Test {public static void main(String[] args) {ApplicationContext context = newClassPathXmlApplicationContext("spring-config.xml");UserComponent userComponent =context.getBean("userComponent", UserComponent.class);userComponent.add();}
}

运行结果如下:

1.5@Configuration(配置存储)

使用@Configuration存储Bean的代码如下:

@Configurable
public class UserConfiguration {public void add(){System.out.println("Hi Configuration add");}
}

  读取Bean的代码:

public class Test {public static void main(String[] args) {ApplicationContext context = newClassPathXmlApplicationContext("spring-config.xml");UserConfiguration userConfiguration =context.getBean("userConfiguration", UserConfiguration.class);userConfiguration.add();}
}

运行结果如下:

 2、五大类注解小结

2.1为什么要这么多类注解

让代码的可读性更高,让程序员能直观的判断当前类的用途

Spring框架中有很多类注解,每个注解都有其特定的作用。这些注解使得开发人员能够更加方便地配置和管理应用程序。以下是其中一些注解的用途:

- @Component:用于将某个类标记为组件,方便自动扫描和注册为Bean。

- @Controller:用于标记控制器类,处理HTTP请求,并返回相应结果。

- @Service:用于标记服务类,对业务逻辑进行封装,通常被Controller层调用。

- @Repository:用于标记仓库类,封装对数据的访问和操作,通常被Service层调用。

- @Configuration:表明该类是Spring配置类,在其中定义Bean的创建和配置规则。

这些注解使得Spring框架变得更加灵活、可扩展、易用。开发人员可以根据需要选择合适的注解来达到自己的目的。

2.2 五大类注解之间的关系 

Spring框架中,常用注解可以归为五大类,分别是:

  1. @Component注解及其衍生注解:包括@Controller、@Service、@Repository等。这些注解用于在Spring容器中注册Bean。
  2. @Configuration注解及其衍生注解:包括@Bean注解。这些注解用于在Spring容器中声明和配置Bean。
  3. @Autowired注解及其衍生注解:包括@Qualifier、@Resource、@Inject等。这些注解用于进行Bean的自动注入。
  4. @Value注解及其衍生注解:包括@PropertySource、@ConfigurationProperties等。这些注解用于进行配置属性的注入和读取。
  5. @Transactional及其衍生注解:包括@Transactional、@TransactionalEventListener等。这些注解用于声明事务和监听事务事件。

这些注解之间的关系可以总结为:

  1. @Component及其衍生注解是用于定义Bean的注解,可通过自动扫描或手动配置的方式注册Bean。
  2. @Configuration及其衍生注解用于声明和配置Bean。
  3. @Autowired及其衍生注解用于进行Bean的自动注入,可以与@Component和@Configuration注解一起使用。
  4. @Value及其衍生注解用于进行配置属性的注入和读取。
  5.  @Transactional及其衍生注解用于声明事务和监听事务事件,通常用于@Service和@Repository注解的类。

 总的来说,这些注解是相互关联的,可以结合使用,达到更加灵活和高效的开发效果。 

二、方法注解

1.方法注解的存储

1.1 @Bean注解的使用

我们先创建一个用户类

public class User {public int Id;private String name;@Overridepublic String toString() {return "User{" +"Id=" + Id +", name='" + name + '\'' +'}';}public int getId() {return Id;}public void setId(int id) {Id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

与类注解不同,类注解是添加到某个类上的;而方法注解自然就是添加到某个方法上的

之后再创建一个方法类,我们要注意在定义方法Bean的时候也要定义五大类注解,因为@Bean要配合类注解才能将对象正常的存储到Spring容器中才能获取到

@Component
public class Users {@Bean()public User getUser(){User user = new User();user.setId(66);user.setName("竹筒子");return user;}
}
public class test {public static void main(String[] args) {ApplicationContext context = newClassPathXmlApplicationContext("spring-config.xml");User user = (User) context.getBean("getUser");System.out.println(user.toString());}
}

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

1.2 @Bean方法的重命名 

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

Bean命名规则,当没有设置name属性时,那么bean默认的名称就是方法名,当设置了name属性后,只能通过重命名的name属性对应的值获取,也就是说重命名后,再使用方法名就获取不到Bean对象了. 此外要注意Bean name是区分大小写的

2.方法注解的获取

在Spring中获取Bean对象也叫做对象装配或者对象注入

从Spring中获取Bean对象的实现方法有以下三种:

属性注入,Setter方法注入,以及构造方法注入

2.1 属性注入

属性注⼊是使⽤ @Autowired 实现的,将 Service 类注⼊到 Controller 类中。
Service 类的实现代码如下:


@Controller
public class UserController {@Autowiredprivate UserService userService;public User getUser(){return userService.getUser();}
}
public class Test {public static void main(String[] args) {ApplicationContext context = newClassPathXmlApplicationContext("spring-config.xml");UserController userController=context.getBean("userController", UserController.class);userController.Hi();}
}

属性注入的优缺点:

属性注入的优点在于,足够的简单以及简洁

缺点在于只能用于IOC容器同时无法注入被final修饰的对象,而且较容易违背单一性原则

2.2 Setter注入

Setter注入的实现也需要依赖@Autowired进行实现,不过其主要针对setter方法进行

@Controller
public class UserController {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public User getUser(){return userService.getUser();}
}

Setter注入的优缺点:

Setter注入的优点在于,其较不容易违背单一性原则

缺点在于,不如属性注入来的简介,同时无法注入被final修饰的对象

2.3 构造方法注入

与前面类似,构造方法注入从名字上看,其实就是在构造器上添加@Autowired注解

 
@Controller
public class StuController {private Stu stu;@Autowiredpublic StuController(Stu stu) {this.stu = stu;}public void sayHi(){System.out.println(stu);}
}

由于构造器注入是比较后面出的,其实它也有一定的智能性:当我们只存在一个构造器的时候,我们可以选择不添加@Autowired,但是当有多个构造器的时候我们必须手动添加@Autowired来指定构造器来进行注入 

构造方法注入优缺点:

优点:构造器是Spring推荐的注入方式,同时构造器注入的通用性较强,能够注入被final修饰的对象

缺点在于不如属性注入来的简介及方便

三、总结 

1.三种注⼊优缺点分析 

  • 属性注⼊的优点是简洁,使⽤⽅便;缺点是只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常)
  • Setter ⽅式是 Spring 前期版本推荐的注⼊⽅式,但通⽤性不如构造⽅法,所有 Spring 现版本已经推荐使⽤构造⽅法注⼊的⽅式来进⾏类注⼊了
  • 构造⽅法注⼊是 Spring 推荐的注⼊⽅式,它的缺点是如果有多个注⼊会显得⽐较臃肿,但出现这种情况你应该考虑⼀下当前类是否符合程序的单⼀职责的设计模式了,它的优点是通⽤性,官方推荐,在使⽤之前⼀定能把保证注⼊的类不为空

2.Resource和@Autowired的区别

当我们在进行类注入的时候,除了使用@Autowired的时候,我们也可以使用@Resource进行注入

@Resource的用法与@Autowired相同

  1.  @Autowired来自Spring,而@Resource来自JDK的注解
  2. @Resource支持更多的参数设置,可以添加name设置来根据名称获取Bean
  3. @Resource不能用于构造函数注入

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux编程第一部分总结

C多线程安全原则 对象析构很复杂&#xff0c;我们采用shared_ptr和weak_ptr来做 enable_shared_from_this<>是用来做回调的&#xff0c;因为多线程中可能对象的生命周期比传出去的this指针短&#xff0c;同时为了不延长对象的生命周期&#xff0c;我们把shared_ptr转成we…

c++ vs2019 cpp20规范的STL库的map与multimap源码分析

map就是一个红黑树。 标准平衡二叉树&#xff0c;要求左右子树的高度差不超过1 。红黑树只要求左右子树的高度差不超过一倍即可。兼顾了树平衡与效率。避免了AVL树的频繁调整树平衡。 b站 的“可雷曼土”大师&#xff0c;讲红黑树的理论讲的很透彻&#xff0c;再结合看代码&…

Linux-安装redis6.2.1及主备复制模式(replication)

Linux-安装redis6.2.1 下载redis6.2.1资源上传至安装目录解压及编译解压修改名称编译 修改配置文件主节点从节点 启动及测试启动主节点从节点 测试 下载redis6.2.1资源 地址》https://redis.io/download/ 上传至安装目录 例&#xff1a;/data/replication/ 解压及编译 解…

二进制安全虚拟机Protostar靶场 安装,基础知识讲解,破解STACK ZERO

简介 pwn是ctf比赛的方向之一&#xff0c;也是门槛最高的&#xff0c;学pwn前需要很多知识&#xff0c;这里建议先去在某宝上买一本汇编语言第四版&#xff0c;看完之后学一下python和c语言&#xff0c;python推荐看油管FreeCodeCamp的教程&#xff0c;c语言也是 pwn题目大部…

Jupyter lab 配置

切换jupyterlab的默认工作目录 在终端中输入以下命令 PS C:\Users\Administrator> jupyter-lab --generate-config Writing default config to: C:\Users\Administrator\.jupyter\jupyter_lab_config.py它就会生成JupyterLab的配置文件&#xff08;如果之前有这个文件的话…

(笔记五)利用opencv进行图像几何转换

参考网站&#xff1a;https://docs.opencv.org/4.1.1/da/d6e/tutorial_py_geometric_transformations.html &#xff08;1&#xff09;读取原始图像和标记图像 import cv2 as cv import numpy as np from matplotlib import pyplot as pltpath r"D:\data\flower.jpg&qu…

【数据结构】 二叉树面试题讲解->叁

文章目录 &#x1f30f;引言&#x1f332;[根据二叉树创建字符串](https://leetcode.cn/problems/construct-string-from-binary-tree/submissions/)&#x1f431;‍&#x1f464;题目描述&#xff1a;&#x1f431;‍&#x1f409;示例&#xff1a;&#x1f4cc;示例一&#x…

Flutter小功能实现-咖啡店

1 导航栏实现 效果图&#xff1a; 1.Package google_nav_bar: ^5.0.6 使用文档&#xff1a; google_nav_bar | Flutter Package 2.Code //MyBottomNavBar class MyBottomNavBar extends StatelessWidget {void Function(int)? onTabChange;MyBottomNavBar({super.key, …

iOS swift5 扫描二维码

文章目录 1.生成二维码图片2.扫描二维码&#xff08;含上下扫描动画&#xff09;2.1 记得在info.plist中添加相机权限描述 1.生成二维码图片 import UIKit import CoreImagefunc generateQRCode(from string: String) -> UIImage? {let data string.data(using: String.En…

若依 vue中el-radio无法默认选中

网上看了很多方法都不管用, 即便是element官方示例方法也不行 解决方法: html <el-form-item label"是否公开" prop"isOpen"><el-radio-group v-model"form.isOpen"><el-radio :label"0">不公开</el-radio>…

跳出Lambda表达式forEach()循环解决思路

背景 在一次需求开发时&#xff0c;发现使用Lambda的forEach()跳不出循环。如下示例代码&#xff0c;想在遍历满足条件时跳出循环。 public static void main(String[] args) {List<Integer> list Arrays.asList(1, 4, 5, 7, 9, 11);list.forEach(e -> {if (e % 2 …

Leetcode Top 100 Liked Questions(序号236~347)

236. Lowest Common Ancestor of a Binary Tree 题意&#xff1a;二叉树&#xff0c;求最近公共祖先&#xff0c;All Node.val are unique. 我的思路 首先把每个节点的深度得到&#xff0c;之后不停向上&#xff0c;直到val相同&#xff0c;存深度就用map存吧 但是它没有向…

1分钟实现 CLIP + Annoy + Gradio 文搜图+图搜图 系统

多模态图文搜索系统 CLIP 进行 Text 和 Image 的语义EmbeddingAnnoy 向量数据库实现树状结构索引来加速最近邻搜索Gradio 轻量级的机器学习 Web 前端搭建 文搜图 图搜图 CLIP图像语义提取功能&#xff01;

ip route get ip地址 应用案例

应用场景 在做虚拟化实验用的虚拟机和实际的ECS云主机一般都会有多个网卡&#xff0c;网络的联通性是经常碰到的问题。比如在一个VM上有3个网卡&#xff0c;分别为ens160(和寄主机进行桥接的网卡10.0.0.128)、ens224&#xff08;连接仅主机网络10.0.0.0/24的网卡10.0.0.128&…

react17:生命周期函数

挂载时更新时 setState触发更新、父组件重新渲染时触发更新forceUpdate触发更新卸载时 react&#xff08;v17.0.2&#xff09;的生命周期图谱如下。 相较于16版本&#xff0c;17版本生命周期函数有如下变化&#xff1a; componentWillMount() componentWillUpdate() compone…

【C++】学习STL中的stack和queue

❤️前言 今天这篇博客的内容主要关于STL中的stack、queue和priority_queue三种容器。 正文 stack和queue的使用方式非常简单&#xff0c;我们只要根据之前学习数据结构的经验和文档介绍就可以轻松上手。于是我们直接开始对它们的模拟实现。 stack和queue的模拟实现 stack和q…

内部类总结

内部类 1、内部类介绍&#xff1a; 外 2、成员内部类&#xff1a; 3、静态内部类 4、局部内部类&#xff1a; 5、匿名内部类&#xff1a;

【高效编程技巧】编程菜鸟和编程大佬的差距究竟在哪里?

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《高效编程技巧》《C语言进阶》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 &#x1f4cb; 前言1.如何写出好的代码&#xff1f;1.2 如何分析一个函数写的怎么样 2. 代码板式的重要性2.1 代码…

基于Open3D的点云处理16-特征点匹配

点云配准 将点云数据统一到一个世界坐标系的过程称之为点云配准或者点云拼接。&#xff08;registration/align&#xff09; 点云配准的过程其实就是找到同名点对&#xff1b;即找到在点云中处在真实世界同一位置的点。 常见的点云配准算法: ICP、Color ICP、Trimed-ICP 算法…

普通制造型企业,如何成就“链主品牌

“链主品牌”通常掌握产业链主导地位&#xff0c;对于普通制造型企业看起来是遥不可及的事情&#xff0c;事实上并非如此。从洞察穿越周期的“链主品牌”规律来看&#xff0c;做螺丝起家的伍尔特、做宠物牵引绳的福莱希等小企业也可以成为“链主品牌”。另外&#xff0c;由于新…