【JavaEE进阶】使用注解存储对象

news2024/12/23 10:37:13

在这里插入图片描述

使用注解存储对象


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

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

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

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


1,五大类注解

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>标签进行定义和配置,进行手动注册。


2,方法注解@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/745475.html

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

相关文章

【c++】std::move 所有权转移的使用

1. std::move用法详细梳理 ref_frames_ std::move(ref_frames);cur_frames_ cur_frames;使用std::move函数的好处是可以将资源的所有权从一个对象转移到另一个对象&#xff0c;而不需要进行深拷贝操作。对于智能指针类型的变量&#xff0c;使用std::move也是可以的&#xff0…

K8s(kubernetes)集群搭建及dashboard安装、基础应用部署

基础介绍 概念 本质是一组服务器集群&#xff0c;在集群每个节点上运行特定的程序&#xff0c;来对节点中的容器进行管理。实现资源管理的自动化。 功能 自我修复弹性伸缩服务发现负载均衡版本回退存储编排 组件 控制节点(master)-控制平面 APIserver&#xff1a;资源操作…

VMware ESXi 7.0 Update 3n - 领先的裸机 Hypervisor

VMware ESXi 7.0 Update 3n - 领先的裸机 Hypervisor VMware ESXi 7.0 Update 3n Standard & All Custom Image for ESXi 7.0 U3m Install CD 更新日期&#xff1a;Fri Jul 07 2023 10:50:00 GMT0800&#xff0c;阅读量: 4518 请访问原文链接&#xff1a;https://sysin.…

全网最细,Web自动化测试-数据驱动实战,直接通关...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 在Web自动化测试中…

智能照明控制系统在民用照明节能中的应用

摘 要 &#xff1a;通过智能照明控制系统在某宾馆电气工程中的应用实例&#xff0c;从照明控制的系统结构、设计及系统软件等方面&#xff0c;介绍了智能照明控制系统的功能及实现方式。探讨了智能照明控制系统在民用建筑中的适用范围和发展前景&#xff0c;并由此进一步推断智…

运维小知识(二)——Linux大容量磁盘分区及挂载

centos系统安装&#xff1a;链接 目录 1.&#x1f353;&#x1f353;命令格式化磁盘 2.&#x1f353;&#x1f353;大容量硬盘分区 3.&#x1f353;&#x1f353;自动挂载 整理不易&#xff0c;欢迎一键三连&#xff01;&#xff01;&#xff01; 新系统装完之后&#xff0…

基于appium的常用元素定位方法

目录 一、元素定位工具 1.uiautomatorviewer.bat 2.appium检查器 二、常用元素定位方法 1.id定位 2.class_name定位 3.accessibility_id定位 4.android_uiautomator定位 5.xpath定位 三、组合定位 四、父子定位 五、兄弟定位 一、元素定位工具 app应用的元素使用的是控…

前端实战(四):Nginx代理

Nginx的用处 Nginx的作用主要体现在作为 Web 服务器、负载均衡服务器、邮件代理服务器等方面&#xff0c;其特点是占有内存少&#xff0c;并发能力强&#xff0c;给使用者带来了很多的便利。Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&…

【UE4 C++】06-绑定运动输入(实现前后移动、鼠标转向)

目录 一、WS前后移动 二、鼠标转向 一、WS前后移动 为了让玩家控制的“PlayerCharacter”能够实现前后移动 在“SCharacter.cpp"中添加如下代码 在“SCharacter.h"中添加如下代码 添加轴映射 设置自动控制玩家 此时按下WS键就可以前进后退了。 二、鼠标转向 …

2023年9月DAMA-CDGA/CDGP认证考试报名开始啦!

据DAMA中国官方网站消息&#xff0c;2023年度第三期DAMA中国CDGA和CDGP认证考试定于2023年9月23日举行。 报名通道现已开启&#xff0c;相关事宜通知如下&#xff1a; 考试科目: 数据治理工程师(CertifiedDataGovernanceAssociate,CDGA) 数据治理专家(CertifiedDataGovernanc…

SQL计算出每年在校人数

以下是一个录取学生人数表的示例&#xff0c;记录了每年录取学生的人数和入学学制。 idyearnumstu_len12018101322019121432020912420211513520211412620221613 字段解释&#xff1a; id&#xff1a;记录的唯一标识符year&#xff1a;学生入学年度num&#xff1a;对应年度录取…

计算机网络——三次握⼿、四次挥手

TCP 三次握手 1、第⼀个SYN报⽂&#xff1a; 客户端随机初始化序列号client_isn&#xff0c;放进TCP⾸部序列号段&#xff0c; 然后把SYN置1。把SYN报⽂发送给服务端&#xff0c;表⽰发起连接&#xff0c; 之后客户端处于SYN-SENT状态。 2、第⼆个报⽂SYNACK报⽂&#xff1a; …

文件IO_打开和关闭文件(附Linux-5.15.10内核源码分析)

目录 1.打开文件 1.1 函数原型介绍 1.1.1 open函数 1.1.2 creat函数 1.1.2 openat函数 1.2 内核源码分析 1.3 函数原型区别 2.关闭文件 2.1 函数原型介绍 2.1.1 close函数 2.2 内核源码实现 1.打开文件 1.1 函数原型介绍 1.1.1 open函数 #include <sys/types.…

【DC系列07】DC-7靶机复盘

【DC系列07】DC-7靶机复盘 这个靶机同样是直接给ip的 这个靶机在进入shell前是没有破绽的&#xff0c;并且进入主页面以后也并没有什么漏洞。如果不搜索一下这个靶机的解法很难去下一步操作。 在github.com上搜索dc7user然后选择code&#xff0c;里面可以找到dc7一个远程登陆…

WPS/Office Excel 方向键无法切换表格

问题&#xff1a;WPS/Office Excel 方向键无法切换表格。 分析&#xff1a;键盘开启了Scroll Lock&#xff0c;导致Excel开启了滚动锁定。滚动锁定如图: 解决&#xff1a;再次按下Scroll Lock键解锁即可。&#xff08;Scroll Lock键在键盘右侧上方。&#xff09;

CSS实现底部弧度效果

效果图如下 说明&#xff1a; 使用伪类处理&#xff0c;先将元素自身定位为relative; 伪类设置content:‘’&#xff0c;并相对定位为absolute&#xff0c;通过设置left ,top 值&#xff0c;改变width和和left来调节弧度。宽度需大于100%&#xff0c;将left设为&#xff08;100…

AWS 中文入门开发教学 48- S3 - 静态网站之王, 快速建立网站之首选

知识点 使用 S3 快速搭建静态网页网站使用 Route 53 服务解析网站域名实战演习 设计域名 Name: blog.deeplearnaws.ml建立同名的 S3 存储桶 上传网页文件到存储桶当中 ACL设置为所有人可读 设置存储桶为静态网站公开 进入属性,

索引相关操作

1、建立一个utf8编码的数据库test1 create database test1;2、建立商品表goods和栏目表category 按如下表结构创建表&#xff1a;存储引擎engine myisam 字符集charset utf8 mysql> desc goods;-------------------------------------------------------------| Field …

【试用科研好物】GPT辅助科研神器?AI助力科研?ChatPDF、有道速读

前言 近期需要阅读的论文很多&#xff0c;偶然间在微博刷到许多人推荐科研利器ChatPDF和有道速读。使用后的结论是不推荐使用&#xff0c;下面分别给出理由。 使用&评价 网页版&#xff0c;无需安装任何东西&#xff0c;两款都支持中文。 ChatPDF有道速读 下面太长不看…

vue项目优化问题

文章目录 1、常见的系统优化方案2、非常见的优化手段(但同样是很有用的)1、组件懒加载2、组件代码分割3、函数编译4、组件通讯 1、常见的系统优化方案 图片懒加载、图片压缩、路由组件按需加载(异步加载)、减少console、if判断、cdn加速、axios统一管理请求、v-if与v-show依据…