2023.11.6 Spring 使用注解存储 Bean 对象

目录

前置工作

使用类注解

五大类注解 

@Controller(控制器)

@Service(服务)

@Repository(仓库)

@Component(组件)

@Configuration(配置)

使用方法注解 @Bean

重命名 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"xmlns:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--base-package 表示要扫描的路径--><content:component-scan base-package="com.java.demo"></content:component-scan>
</beans>

使用类注解

五大类注解 

@Controller(控制器)

  • 归属业务逻辑层
  • 验证用户请求的数据正确性(安保系统)

@Service(服务)

  • 归属服务层
  • 编排和调度具体的执行方法(客服中心)

@Repository(仓库)

  • 归属持久层
  • 和数据库交互(执行者)

@Component(组件)

  • 归属于公共工具类
  • 提供某些公共方法

@Configuration(配置)

  • 归属于配置层
  • 用来配置当前项目的一些信息(对项目的全局配置负责)

实例理解

  • 创建一个 StudentController 类,并使用 @Controller 注解将其注入到 Spring 容器中
  • 将该实例的 @Controller 注解换成 @Service、@Repository、@Component、@Configuration 均可实现将当前类注入到 Spring 容器中
package com.java.demo;import org.springframework.stereotype.Controller;// 使用 @Controller 注解将当前类存储到 spring 容器中
@Controller
public class StudentController {public void sayHi() {System.out.println("student controller say hi");}
}
  • 在启动类中获取 Bean 对象,并使用 Bean 对象
import com.java.demo.StudentController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {
//        得到 Spring 上下文对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//        获取 Bean 对象StudentController studentController = context.getBean("studentController",StudentController.class);studentController.sayHi();}
}
  • 此处我们并未在配置文件中使用 Bean 标签将 StudentController 对象注入到 Spring 容器中
  • 而是直接使用 @Controller 注解将其注入到 Spring 容器
  • 所以当我们要使用 getBean 方法获取该 Bean 对象的时候,其默认 id 为原类名的小驼峰形式

运行结果:

注意:

  • 此处的 Bean 对象的 id 命名还存在特殊情况 
  • 创建一个 SController 类
import org.springframework.stereotype.Controller;@Controller
public class SController {public void sayHi() {System.out.println("s controller say hi");}
}
  • 在启动类中获取 Bean 对象,并使用 Bean 对象
import com.java.demo.SController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {
//        得到 Spring 上下文对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//        获取 Bean 对象SController sController = context.getBean("sController",SController.class);sController.sayHi();}
}

运行结果:

结论1:

  • 默认情况 Bean 对象 id 为原类名的小驼峰形式
  • 但如果类名的第一个字母和第二个字母都是大写,则其 Bean 对象 id 应为 原类名

五大类注解 Bean 对象 id 命名规则原码


结论2:

  • 在配置文件中,<content:component-scan> 标签和 <bean> 标签可以同时使用
  • <bean> 标签可补充注入 不在扫描路径中的 Bean 对象

实例理解

  • 创建一个 UserService 类
public class UserService {public void sayHi() {System.out.println("user service say hi");}
}
  • 使用 <bean> 标签将 UserService 类的 Bean 对象注入到 Spring容器中

  • 在启动类中获取 Bean 对象并使用
import com.java.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {
//        得到 Spring 上下文对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//        获取 Bean 对象UserService userService = context.getBean("userService",UserService.class);userService.sayHi();}
}

运行结果:


结论3:

  • 不在 <component-scan> 中所设置的扫描路径下 且被五大类注解标识的类,不会注入到 Spring 容器中

结论4:

  • 在 <component-scan> 中所设置的扫描路径下 但未被五大类注解标识的类,不会注入到 Spring 容器中

结论5:

  • 在  <component-scan> 中所设置的扫描路径下的所有子包的类,只要加了五大类注解的类,会注入到 Spring 容器中

使用方法注解 @Bean

  •  相比较于五大类注解 添加到某个类上
  • 方法注解 @Bean ,顾名思义就是将其添加到方法上的

注意:

@Bean 注解 必须要配合 五大类注解一起使用

  • 只有加了 五大类注解的类,Spring 才会 扫描该类
  • 进而才会扫描当前类中的方法是否有加了 @Bean 注解的
  • 这是出于 Spring 性能设计所规定的策略

@Bean 注解 Bean 对象命名规则:

  • 默认情况下,@Bean 存储的 Bean 对象的 id 就是方法名

实例理解

  • 我们创建一个 实例类 User
// 普通的用户实体类
public class User {public Integer uid;public String username;public String password;public Integer age;public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}
}
  • 我们再创建一个 UserBeans 类
  • 在该类中写一个方法,来创建 实例类 User 的对象
  • 并使用 @Bean 注解将 User 的 Bean对象 注入到 Spring 容器中
  • 注意此处搭配了五大类注解中的 @Component 注解
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class UserBeans {@Beanpublic User user1() {User user = new User();user.setUid(1);user.setUsername("张三");user.setPassword("123456");user.setAge(18);return user;}
}
  • 在启动类中获取该 Bean 对象
  • 注意此处获取 Bean 对象时的 id 为 user1,即被 @Bean 注解所修饰方法的方法名
import com.java.demo.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {
//        得到 Spring 上下文对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//        获取 Bean 对象User user = context.getBean("user1",User.class);System.out.println(user.getUsername());}
}

运行结果:


重命名 Bean 

  • 默认情况下,@Bean 存储的 Bean 对象的 id 就是方法名
  • 但是我们还是可以自己手动设置 Bean 对象的 id

实例理解

  • 我们可以通过下图方式给 Bean 对象设置多个 id

  • 在启动类中获取该 Bean 对象
  • 此时我们任选一个 id 即可获取该 Bean 对象,此处选择 id 为 u1
import com.java.demo.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {
//        得到 Spring 上下文对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//        获取 Bean 对象User user = context.getBean("u1",User.class);System.out.println(user.getUsername());}
}

运行结果:

注意:

  • 当给 Bean 对象重命名之后,默认的使用方法名获取对象的方式就不能再使用了

补充问题

  • 我们创建一个 UserBeans 类,且未重命名 Bean 对象
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class UserBeans {@Beanpublic User getUser() {User user = new User();user.setUid(1);user.setUsername("张三");user.setPassword("123456");user.setAge(18);return user;}
}
  • 我们再创建一个 UserBeans2 类,且未重命名 Bean 对象
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class UserBeans2 {@Beanpublic User getUser() {User user = new User();user.setUid(2);user.setUsername("李四");user.setPassword("123456");user.setAge(20);return user;}
}
  • 在启动类中获取该 Bean 对象
import com.java.demo.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {
//        得到 Spring 上下文对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//        获取 Bean 对象User user = context.getBean("getUser",User.class);System.out.println(user.getUsername());}
}

运行结果:

  • 我们多次运行启动类,发现所获取到始终是 Username 为李四的 Bean 对象
  • 但是 Username 为张三的 Bean 对象,其 id 也为 getUser,但是为什么获取的不是它呢?
  • 此处涉及到数据覆盖
  • 因为 Username 为张三 且 id 为 getUser 的 Bean 对象,先被注入到 Spring 容器中
  • 此时 Username 为李四 且 id 为 getUser 的 Bean 对象,再被注入到 Spring 容器中
  • 正因为 Spring 容器中已经又了 id 为 getUser 的 Bean 对象,所以后注入到的 Username 为李四 的 Bean 对象 便将 Username 为张三 的 Bean 对象 给覆盖了
  • 所以此处启动类获取到的 Bean 对象其 Username 输出为 李四

我们可以通过 @Oder 注解来更清晰的观察该情况

  • @Oder 注解 是用来控制 Bean 对象注入顺序
  • 其参数值越小,其权重就越大,也就越先被注入到 Spring 容器中

类注解之间的关系

注意:

  • @Controller、@Service、@Repository、@Configuration 均是针对 @Component 的一个扩展
  • 这几个注解均能将当前类注入到 Spring 容器中,其功能基本一致
  • 之所以分这么多类注解,其原因就是:
  • 能让程序员看到注解之后便知道当前类的作用

上述类注解对应着 JavaEE 标准分层(至少三层)

  1. 控制层
  2. 服务层
  3. 数据持久层
  • 当一个类不合适放在上面三层中的任意一个时,可用 @Component 注解进行分层的扩展和补充

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

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

相关文章

531X304IBDASG1 F31X303MCPA002/00 发电用分布式控制系统

531X304IBDASG1 F31X303MCPA002/00 发电用分布式控制系统 2021年4月20日&#xff0c;马萨诸塞州戴德姆。-新的ARC咨询小组关于全球的研究发电用分布式控制系统(DCS)市场显示&#xff0c;全球燃煤发电能力的减少继续阻碍增长。老化的燃煤电厂越来越多地被淘汰&#xff0c;而不是…

在Ubuntu上安装Redis并学习使用get、set和keys命令

目录 安装Redis切换到root用户搜索redis相关软件包安装redis修改配置文件重启服务器使用redis客户端连接服务器 get与set命令keys 安装Redis 我们在Ubuntu20.04上进行Redis的安装 切换到root用户 使用su命令&#xff1a; 在终端中&#xff0c;输入su并按回车键。然后输入roo…

jenkins gitlab CI/CD

jenkins的安装教程就不说了&#xff1a;Jenkins docker 一键发布 (一)_jenkins 一键发布-CSDN博客 最近打算从svn切换到gitlab&#xff0c;所以配置了一下jenkins的git 很简单&#xff0c;直接上图 1 选择 Git 2 录入gitlab的http地址&#xff08;由于我的git地址不是22端口&…

WebSocket Day 01:入门案例

前言 欢迎来到WebSocket入门案例系列的第一天&#xff01;在今天的博客中&#xff0c;我们将一起探索WebSocket的基础知识和使用方法。本系列将以一个简单的入门案例为基础&#xff0c;带领您逐步了解WebSocket的原理和用法。 一、什么是 WebSocket ? WebSocket是一种在Web应…

java版直播商城免费搭建平台规划及常见的营销模式+电商源码+小程序+三级分销+二次开发

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

web —— html

Web —— css基础 1. HTML2. 基本HTML结构3. HTML常用标签3.1 文本相关标签3.2 HTML图像标签3.3 HTML超链接标签3.4 HTML表&#xff0c;单3.4.1 HTML表格3.4.2 HTML表单&#xff0c;输入框&#xff08;多选框&#xff0c;单选框&#xff09;下拉框 3.5 HTML分区标签3.5.1 div标…

【Midjourney入门教程3】写好prompt常用的参数

文章目录 1、图片描述词&#xff08;图片链接&#xff09;文字描述词后缀参数2、权重划分3、后缀参数版本选择&#xff1a;--v版本风格&#xff1a;--style长宽比&#xff1a;--ar多样性: --c二次元化&#xff1a;--niji排除内容&#xff1a;--no--stylize--seed--tile、--q 4、…

实战-edusrc漏洞挖掘

0x01系统初探 通过fofa对大学进行搜索 fofa:host"edu.cn" &amp;&amp; status_code"200"在随意的翻阅查看时&#xff0c;发现访问xxx.edu.cn登录页面会优先访问登录后的页面&#xff0c;再跳转至登录页面。盲猜应该是前端校验&#xff0c;可以通过…

C++项目的一些环境配置

今天学习下OpenCV&#xff0c;环境配置顺便理一下&#xff1a; 1.用到外部的C文件要在&#xff1a;项目的属性页->VC目录->包含目录&#xff0c;添加相应的路径 2.用到外部的库文件需要在&#xff1a;项目的属性页->VC目录->库目录&#xff0c;添加相应的路径&…

Ps:色彩范围

Ps菜单&#xff1a;选择/色彩范围 Select/Color Range 色彩范围 Color Range是一个功能强大选择命令&#xff0c;不仅可以基于颜色进行选择&#xff0c;而且可以基于影调进行选择。不仅可以用来检测人脸选择肤色&#xff0c;也可用来选择超出印刷色域范围的区域。 在图层蒙版的…

七种事务传播行为,核心只有Required默认和required_new

事务的概念&#xff1a;当一个事务方法被另一个事务方法调用时&#xff0c;这个事务方法应该如何进行事务控制。 结论&#xff1a;一般情况下&#xff0c;你就用默认的把两个事务合并成一个事务&#xff0c;只有当写日志&#xff08;事物之间不互相影响&#xff09;的时候用req…

光学仿真 | 仿真推动以人类视觉感知为本的汽车显示设计

如果产品设计无法使终端用户产生共鸣&#xff0c;就不会存在卓越的工程设计。您可以设计一种结构坚固的方向盘&#xff0c;但如果它被放在错误的位置&#xff0c;就无法实现其用于转向的主要目的。 同样&#xff0c;在围绕人类视觉进行设计时&#xff0c;显示器其实无需具备尽…

【C/C++笔试练习】内联函数、哪些运算符不能重载、拷贝构造函数、const类型、函数重载、构造函数、空类的大小、井字棋、密码强度等级

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;内联函数&#xff08;2&#xff09;哪些运算符不能重载&#xff08;3&#xff09;拷贝构造函数&#xff08;4&#xff09;const类型&#xff08;5&#xff09;函数重载&#xff08;6&#xff09;构造函数&#xff08;7&a…

Xilinx DDR3 MIG系列——内存基本概念及原理

本节目录 一、内存简介 (1)内存基本存储原理 (2)内存频率 (3)DDR数据预取技术(Prefetch) (4)DDR3工作流程 (5)DDR3控制器的特点 二、内存基本参数 (1)物理Bank (2)逻辑Bank (3)内存芯片容量 (4)行激活命令—tRCD (5)列选通—CL (6)写入延迟—tDQSS (7)行预充电有效周期—tRP (8…

css 图片好玩的一个属性,添加滤镜

鼠标经过效果对比&#xff1a; 上图是改变了图片的饱和度&#xff0c;代码如下&#xff1a; .img-box .v-image:hover {filter: saturate(1.75); }其他滤镜说明如下图&#xff1a;

数字人IP为何成家电品牌年轻化营销黑马?

伴随着数字人概念的出现&#xff0c;家电品牌逐渐通过3D虚拟数字人定制&#xff0c;让数字人成为内容、变现一体的IP&#xff0c;形成一定影响力的品牌效应&#xff0c;利用长线内容沉淀粉丝&#xff0c;使品牌实现年轻化营销。 *图片源于网络 如近日在海尔智家旗下品牌发布会上…

网上书店项目

源码下载地址 支持&#xff1a;远程部署/安装/调试、讲解、二次开发/修改/定制 程序运行视频查看 管理员 图书管理 添加图书 删除图书(可批量删除) 修改图书 查看图书(分页查看) 图书上下架(可批量处理) 图书推荐&#xff08;新品推荐、精品推荐&#xff0c;可批量处理&#…

灵活调整宣传策略,媒体发稿和新闻发布的优势所在

企业在当今信息爆炸的时代&#xff0c;要想在市场竞争中脱颖而出&#xff0c;提高公信力是至关重要的。而媒体发稿和新闻发布是提升企业公信力的重要手段之一。下面将从门户网站的权威展示、搜索引擎排名的提升、内容的持续稳定有效性、内容的可改性以及协助增加网站流量等方面…

【owt】p2p client mfc 工程梳理

1年前构建的,已经搞不清楚了。所以梳理下,争取能用较新的webrtc版本做测试。最早肯定用这个测试跑通过 【owt】p2p Signaling Server 运行、与OWT-P2P-MFC 交互过程及信令分析官方的mfc客户端 估计是构造了多个不同的webrc版本的客户端

Git介绍及使用

目录 一、Git 的基本概念 1. 仓库&#xff08;Repository&#xff09;: 仓库是存储代码的地方。可以通过 命令将本地文件夹初始化为 Git 仓库&#xff0c;并使用 命令从远程仓库克隆到本地 2. 分支&#xff08;Branch&#xff09;: 分支是指从主分支上创建出来的一个分支&…