【框架篇】使用注解存储对象

news2024/11/15 17:33:52

在这里插入图片描述

使用注解存储对象


之前我们存储Bean时,需要在spring-config 中添加一行 bean注册内容才行,如下图所示:

问题引入:如果想在Spring 中能够更简单的进行对象的存储和读取,该怎么办呢?

问题解答:实现在Spring中更简单地进行对象的存储和读取操作的核心是使用注解来实现。

也就是我们接下来要学习Spring 中的相关注解,来进行存储和读取Bean对象。


一,五大类注解

1.1,类注解介绍及使用

1)类注解使用前置工作

类注解使用时的前置工作为配置扫描路径,这一步至关重要。该步需要在spring-config.xml文件中添加如下配置:

<?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">
    <content:component-scan base-package="com.java.example"></content:component-scan>
</beans>

如果想成功地将对象存储到Spring 中,这时我们需要配置一下存储对象的扫描包路径。

只有处于被配置的扫描包路径下的所有类对象,添加类注解之后才能被正确的识别并保存到Spring中。

也就是说,即使类对象添加了类注解,但该类对象不处于被配置的扫描包路径下,也是不能被正确的识别并保存到Spring中。

其中标红的一行为注册扫描的包,如下图所示:

image-20230708192854468

2) @Controller(控制存储)

使用 @Controller 存储 bean对象 操作流程代码:

import org.springframework.stereotype.Controller;
@Controller
public class StudentController {
    public void sayHi(){
        System.out.println("do student controller sayHi()");
    }
}

读取Bean对象并使用的总操作流程代码:

import com.java.example.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
        public static void main1(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext = 
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentController studentController =
                applicationContext.getBean("studentController",StudentController.class);
        //3,使用Bean对象
        studentController.sayHi();
    }
}

读取Bean对象并使用的总操作流程代码执行结果:

image-20230708201007881

3)@Service(服务存储)

使用 @Service 存储 bean对象 操作流程代码:

import org.springframework.stereotype.Service;
@Service
public class StudentService {
    public void sayHi(){
        System.out.println("do student service sayHi()");
    }
}

读取Bean对象并使用的总操作流程代码:

import com.java.example.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
        public static void main2(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentService studentService =
                applicationContext.getBean("studentService",StudentService.class);
        //3,使用Bean对象
        studentService.sayHi();
    }
}

读取Bean对象并使用的总操作流程代码执行结果:

image-20230708200934766

4)@Repository(仓库存储)

使用 @Repository 存储 bean对象 操作流程代码:

import org.springframework.stereotype.Repository;
@Repository
public class StudentRepository {
    public void sayHi(){
        System.out.println("do student repository sayHi()");
    }
}

读取Bean对象并使用的总操作流程代码:

import com.java.example.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
        public static void main(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentRepository studentRepository =
                applicationContext.getBean("studentRepository",StudentRepository.class);
        //3,使用Bean对象
        studentRepository.sayHi();
    }
}

读取Bean对象并使用的总操作流程代码执行结果:

image-20230708200837802

5)@Component(组件存储)

使用 @Component 存储 bean对象 操作流程代码:

import org.springframework.stereotype.Component;
@Component
public class StudentComponent {
    public void sayHi(){
        System.out.println("do student component sayHi()");
    }
}

读取Bean对象并使用的总操作流程代码:

import com.java.example.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
        public static void main4(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentComponent studentComponent =
                applicationContext.getBean("studentComponent",StudentComponent.class);
        //3,使用Bean对象
        studentComponent.sayHi();
    }
}

读取Bean对象并使用的总操作流程代码执行结果:

image-20230708201046813

6)@Configuration(配置存储)

使用 @Controller 存储 bean对象 操作流程代码:

import org.springframework.context.annotation.Configuration;
@Configuration
public class StudentConfiguration {
    public void sayHi(){
        System.out.println("do student configuration sayHi()");
    }
}

读取Bean对象并使用的总操作流程代码:

import com.java.example.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
    public static void main5(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext = 
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentConfiguration studentConfiguration = 
                applicationContext.getBean("studentConfiguration",StudentConfiguration.class);
        //3,使用Bean对象
        studentConfiguration.sayHi();
    }
}

读取Bean对象并使用的总操作流程代码执行结果:

image-20230708201154639

思考:配置信息为何不直接写在配置文件里,而要专门使用配置注解呢?

配置文件是用于提供全局性的配置,可以集中管理和调整各种应用程序的属性和行为。 配置文件具有灵活性,可以在部署环境或实际运行时进行修改,而无需重新编译代码。通过配置文件,可以实现对整个应用程序的配置和调整。

配置注解则更多地用于代码层面的配置和定制。 通过在代码中添加特定的注解,可以实现更精确和定制化的配置。配置注解可以用于声明、配置和管理各种类、组件、服务、Bean等,以实现各种不同的行为和功能,以及使得代码更具可维护性和可读性。

总结:配置文件和注解在Spring Boot项目中是相互补充的。配置文件用于整体性的配置外部化,而注解用于在代码层面进行具体的配置和定义。


1.2,类注解存在的原因

这五大类注解的功能:处于被配置的扫描包路径下的所有的类对象,经添加类注解之后就能被正确的识别并保存到Spring 容器中。

既然这五大类注解的功能是⼀样的,为什么需要这么多的类注解呢?

之所以需要这么多的类注解,是因为想起到程序员看到类注解之后,就能直接知道当前类的作用和功能的效果。

  1. @Controller:表示控制层,用于验证用户参数的正确性,相当于安保系统。
  2. @Service:表示服务层,用于编排和调度具体执行方法,相当于客服中心。
  3. @Repository:表示持久层,用于和数据库进行交互操作,相当于执行者。
  4. @Component:表示组件,用于标识工具类。
  5. @Configuration:表示配置层,用于标识配置类。

1.3,类注解之间的关系

1)@Controller 底层实现

image-20230708204157804

2)@Service 底层实现

image-20230708204331173

3)@Repository 底层实现

image-20230708204302395

4)@Configuration 底层实现

image-20230708204115246

5)五大类注解之间关系总结

从上述查看@Controller /@Service /@Repository /@Configuration 这些类注解的源代码不难发现:

这些类注解里面都有一个注解@Component,说明它们本身就是属于@Component 的子类。


1.4,类注解Bean命名规则

查看Bean命名规则的源代码方式流程:

1,在搜索框中输入BeanName,点击标记的方法

image-20230708210220490

2,点击标记的方法,就可以查看到对应的命名规则源代码

image-20230708210309036

3,对Bean命名规则的源代码进行分析image-20230708210942815

4,根据上述源代码可以总结出Bean对象命名规则为:

在默认情况下,Bean名称为首字母小写的类名,但如果类名首字母和第二个字母都为大写,Bean名称为原类名。

1.5,类注解使用注意问题

1)<bean> 标签 能否和<content:component-scan> 标签一起使用?

解答:<bean> 标签 能和<content:component-scan> 标签一起使用,<bean>可以是对<content:component-scan> 的补充。

  1. 使用<context:component-scan>标签扫描指定的包,并自动注册相应注解标识的类作为Bean
  2. 使用<bean>标签定义和配置一些需要详细控制的特定Bean

2)五大类注解可以不在<content:component-scan> 标签内设置的指定包路径下使用吗?

解答:五大类注解不可以在<content:component-scan> 标签内设置的指定包路径以外的路径下使用。

理由:五大类注解(@Component@Controller@Service@Repository等)需要在<context:component-scan>标签内设置的指定包路径下使用,以便Spring能够正确扫描并注册这些类。

3)在<content:component-scan> 标签内设置的包路径下,如果没有添加五大类注解,能将Bean对象存储到Spring中吗?

解答:即使类在<content:component-scan> 标签内设置的包路径下,若没有添加五大类注解,也是不能把当前类对象存储到Spring。

4)如果存在相同的类对象在<content:component-scan> 标签内设置的扫描包的不同子包路径下,会发生异常么?

解答:若没有对相同的类对象添加别名,会发生BeanDefinitionStoreException异常。

image-20230709094608793

解决上述情况的方法:通过导入指定的包进行区分或者添加别名的方式进行区分,推荐使用后者(导包容易出现导错的情况)。

image-20230709095157206

上述问题核心总结:为了确保Spring能够正确使用这些注解,需要将相关注解的使用限定在<context:component-scan>标签内设置的指定包路径下的类中。若在其他包路径下的类中使用这些注解,需要通过显式的<bean>标签进行定义和配置,进行手动注册。


二,方法注解@Bean

2.1,方法注解介绍及使用

类注解是添加到某个类上的,而方法注解是放到某个方法上的,方法注解@Bean的使用流程:

1)创建一个Student实体类

创建一个Student实体类操作代码:

public class Student {
    private int studentId;
    private String StudentName;
    
    public int getStudentId() {
        return studentId;
    }
    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }
    public String getStudentName() {
        return StudentName;
    }
    public void setStudentName(String studentName) {
        StudentName = studentName;
    }
}

2)在其它类中使用@Bean存储对象

在其它类中使用@Bean存储对象操作代码:

import com.java.example.org.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
@Controller
public class StudentBeans {
    @Bean
    public Student student(){
        Student student1 = new Student();
        student1.setStudentId(1);
        student1.setStudentName("小样");
        return student1;
    } 
}

3)在启动类中检测是否成功存储对象

在启动类中检测是否成功存储对象操作代码:

import com.java.example.*;
import com.java.example.org.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
    public static void main(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        Student student =
                applicationContext.getBean("student",Student.class);
        //3,使用Bean对象
        System.out.println(student.getStudentName());
    }
}

注意:@Bean命名规则和五大类注解的命名规则不同,默认情况下,@Bean存储的对象名称就是方法名。

在启动类中检测是否成功存储对象操作代码执行结果:

image-20230709101815353


2.2,方法注解Bean重命名

方法注解Bean重命名可以使用两种字段进行,分别为 name 属性和 value 属性。

@Bean重命名的两种方式分别为:

image-20230709103003212

注意: namevalue 的本质是⼀个数组,可以存放多个值,也就是说⼀个 bean 可以有多个名字,并且 name={} 可以省略。


2.3,方法注解使用注意问题

1)@Bean 注解必须要与五大类注解配合使用,如果不搭配五大类注解使用会抛出如下异常:

image-20230709104719402

2)当@Bean对象进行重命名之后,默认地使用方法名获取对象的方式就不能使用了,若使用,则会抛出如下异常:

image-20230709105112999


核心总结

类注解的使用相关介绍?

1,类注解存在的原因:起到程序员看到类注解之后,就能直接知道当前类的作用和功能的效果。

2,@Controller /@Service /@Repository /@Configuration这四个类注解都属于@Component的子类。

3,Bean命名规则:在默认情况下,Bean名称为首字母小写的类名,但如果类名首字母和第二个字母都为大写,Bean名称为原类名。

4,类注解的功能:处于被配置的扫描包路径下的所有的对象方法,经添加注解之后就能被正确的识别并保存到Spring 容器中。

类注解的使用注意事项?

1,<bean> 标签 能和<content:component-scan> 标签一起使用,<bean>可以是对<content:component-scan> 的补充。

2,五大类注解不可以在<content:component-scan> 标签内设置的指定包路径以外的路径下使用。

3,即使类在<content:component-scan> 标签内设置的包路径下,若没有添加五大类注解,也是不能把当前类对象存储到Spring。

4,若没有对相同的类对象添加别名,会发生BeanDefinitionStoreException异常。

方法注解的使用相关介绍?

1,方法注解使用的核心流程:在其它类中使用@Bean注解存储对象。

2,@Bean命名规则和五大类注解的命名规则不同,默认情况下,@Bean存储的对象名称就是方法名。

3,方法注解Bean重命名可以使用两种字段进行,分别为name属性和value属性,本质是⼀个数组,可以存放多个值。

方法注解的使用注意事项?

1,@Bean 注解必须要与五大类注解配合使用,如果不搭配五大类注解使用会抛出异常。

2,当@Bean对象进行重命名之后,默认地使用方法名获取对象的方式就不能使用了,若使用,则会抛出异常。


结语

这就是本期博客的全部内容啦!如果有什么其他的问题无法自己解决,可以在评论区留言哦!

最后,如果你觉得这篇文章写的还不错的话或者有所收获的话,麻烦小伙伴们动动你们的小手,给个三连呗(点赞👍,评论✍,收藏📖),多多支持一下!各位的支持是我最大的动力,后期不断更新优质的内容来帮助大家,一起进步。那我们下期见!

在这里插入图片描述

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

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

相关文章

Python应用实例(一)外星人入侵(十)

外星人入侵&#xff08;十&#xff09; 1.记分1.1 显示得分1.2 创建记分牌1.3 在外星人被消灭时更新得分1.4 重置得分1.5 将消灭的每个外星人都计入得分1.6 提高分数1.7 舍入得分1.8 最高得分1.9 显示等级1.10 显示余下的飞船数 1.记分 下面来实现一个记分系统&#xff0c;以实…

动态规划01背包之1049 最后一块石头的重量 II(第11道)

题目&#xff1a; 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 。那么粉碎的可能结果如下&#xff1a; …

4029: 网格行走

题目内容 在一个 n n n \times n nn 的网格上行走&#xff0c;从 ( 1 , 1 ) (1, 1) (1,1) 走到 ( n , n ) (n, n) (n,n)。每次只能向下走一步或向右走一步。 每个点 ( i , j ) (i, j) (i,j) 有权值 a i , j a_{i, j} ai,j​&#xff0c;给定一个数 x x x&#xff0c;求…

电机驱动系列(1)--例程下载演示

电机驱动系列&#xff08;1&#xff09; 使用设备连线实操感想 使用设备 硬件&#xff1a;野火骄阳板–STM32F407IGT6&#xff0c;野火无刷电机驱动板&#xff0c;PMSM电机软件&#xff1a;MCSDK&#xff0c;STM32CubeMX&#xff0c;Keil5软件安装注意事项&#xff1a;MCSDK-F…

SOF-SLAM论文翻译

SOF-SLAM:面向动态环境的语义可视化SLAM 摘要-同时定位与绘图(SLAM)在计算机视觉和机器人领域中占有重要地位。为了便于分析&#xff0c;传统的SLAM框架采用了强静态世界假设。如何应对动态环境是一个非常重要的问题&#xff0c;越来越受到人们的关注。现有的动态场景SLAM系统…

MySQL不适合创建索引的7种情况

1. 在where中使用不到的字段&#xff0c;不要设置索引 WHERE条件&#xff08;包括order by &#xff0c;group by&#xff09; 2. 数据量小的表最好不要使用索引 表记录太少&#xff0c;比如少于1000个&#xff0c;创建索引会先查索引&#xff0c;再回表&#xff0c;查询花费…

虚拟机安装及使用

无论下载什么软件&#xff0c;最好都要单独设置个文件夹 文章目录 VMware下载CentOS下载Xshell 7下载WinSCP下载linux命令 VMware下载 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; VMware Workstation Pro安装 一直傻瓜式安装 可以上网找许可证秘钥 …

asm: 实现打印“Hello, world!“

使用汇编打印“Hello, world!“ 实现打印"Hello, world!"的汇编代码代码详细剖析 实现打印"Hello, world!"的汇编代码 我们来直接贴代码 section .textglobal _start _start:mov edx,lenmov ecx,msgmov ebx,1mov eax,4 int 0x80mov …

pytest 通过装饰器获取测试case的断言失败结果

test11.py import logging from functools import wrapsdef log_exceptions(func):wraps(func)def wrapper(*args, **kwargs):# 创建日志记录器logger logging.getLogger(func.__name__)logger.setLevel(logging.ERROR)# 创建文件处理器file_handler logging.FileHandler(er…

MySQL(五)缓存策略

MySQL系列文章 MySQL&#xff08;一&#xff09;基本架构、SQL语句操作、试图 MySQL&#xff08;二&#xff09;索引原理以及优化 MySQL&#xff08;三&#xff09;SQL优化、Buffer pool、Change buffer MySQL&#xff08;四&#xff09;事务原理及分析 MySQL&#xff08;五&a…

利用pgloader工具将MySQL数据迁移至PostgreSQL数据库

一、简介 pgloader是一款开源软件,可以将各种来源的数据加载到PostgreSQL数据库中&#xff0c;支持动态读取数据&#xff0c;使用 COPY 流式传输协议将数据加载到 PostgreSQL 数据库中&#xff0c;并使用单独的线程读取和写入数据&#xff0c;由于能够直接从源数据库加载数据。…

1771_Windows下格式化Linux硬盘

全部学习汇总&#xff1a; GreyZhang/little_bits_of_linux: My notes on the trip of learning linux. (github.com) 我自己使用Linux系统多年&#xff0c;但是对于很多操作系统相关的知识我其实并不是很了解。我当初之所以使用Linux一是因为这个系统能够提供给我所有想要的工…

Unity游戏源码分享-Unity手游射击横版游戏

Unity游戏源码分享-Unity手游射击横版游戏 战斗场景 项目地址&#xff1a; https://download.csdn.net/download/Highning0007/88050256

Deployment:让应用永不宕机

“Deployment”&#xff0c;顾名思义&#xff0c;它是专门用来部署应用程序的&#xff0c;能够让应用永不宕机&#xff0c;多用来发布无状态的应用&#xff0c;是 Kubernetes 里最常用也是最有用的一个对象。 Deployment 的关键字段&#xff1a;先看 replicas 字段。它的含义比…

在Vitis IDE中使用第三方库 libtiff 保存 tiff 文件

目的和思路 一个Vitis IDE 裸机项目&#xff0c;需要将视频帧无损地保存下来 由于每帧的像素数据是 16bit 1通道的 bayer 格式&#xff0c;满足这一需求的图像格式似乎只有 tiff 格式 开源的tiff 库是 libtiff&#xff0c;而在 Vitis IDE 裸机项目中要使用的话就需要交叉编译…

AD22软件系统参数的一些基本设置

AD22软件系统参数设置 SystemData managementSchematicPCB Editor System Data management Schematic PCB Editor

集群基础5——keepalived对apache高可用

文章目录 一、基本了解二、配置文件参数释义2.1 默认配置文件2.2 定制配置文件2.2.1 vrrp_instance段配置参数2.2.2 vrrp_script段配置参数2.2.3 real_server段配置参数2.2.4 tcp_check段配置参数 三、keepalived对apache高可用3.1 环境说明3.2 安装服务3.3 配置主服务器3.4 配…

前端编码规范

prettier 配置 1. vscode 安装prettier 的 插件 2. 新建 .prettierrc 文件 {"semi": false, // 不尾随分号"singleQuote": true, // 使用单引号"trailingComma": "none" // 多行逗号分隔的语法&#xff0c;最后一行不加逗号 }eslin…

orbslam3 生成标定板rosrun kalibr kalibr_create_target_pdf --type

rosrun kalibr kalibr_create_target_pdf --type apriltag --nx 6 --ny 6 --tsize 0.08 --tspace 0.3小师妹要做相机视觉标定&#xff0c;需要制作棋盘格&#xff0c;无奈其电脑有些卡&#xff0c;对此毫无经验的博主从头开始安装&#xff08;此前博主已经安装了ROS环境&#x…

精品个人或团队引导页网站HTML源码_好看大气

2023全新宽屏大气好看团队个人指导页网站HTML源码&#xff0c;带音乐视频mv&#xff0c;源码比较小&#xff0c;只有七兆&#xff0c;就因为一个MV占了十几兆。源码也很漂亮&#xff0c;但是有个缺点就是没有手机适配&#xff0c;只能PC浏览器正常显示&#xff0c;手机不能完全…