【Spring】之注解存取Bean对象

news2024/12/25 9:56:51

在本系列的上一篇文章中,我们已经了解了Spring的一些核心概念,并且还学习了Spring存取。但是我们发现在存取的过程中还是比较复杂,接下来我们将学习更为简单的Spring存取,其中涉及到的主要内容就是注解。并且在Spring家族的学习过程中,基本上注解是无处不在。

Spring项目的创建

a. 创建maven项目

b. 添加Spring框架依赖

将依赖放置于pom.xml中即可。

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
    </dependencies>

c. 创建一个启动类

我创建的启动类是App类,其实本质上启动类没啥意义,就是为了测试写的代码是否正确。

Spring对象的存取

a. 配置扫描路径

想要成功的将对象存储在Spring中,我们就必须配置存储对象的扫描路径,只有扫描路径下的包,添加注解之后才可以被正确的识别并保存在Spring中。

扫描路径需要配置在resources下的xml中,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">

</beans>

b. 注解

在Spring存取的过程中,需要用到注解,因此先来写一下需要哪几个注解,为啥要有这么多的注解,每个注解的含义是啥。

在Spring存对象的过程中,有两种注解可以实现其功能,分别是五大类注解和方法注解

五大类注解

@Controller、@Service、@Repository、@Component、@Configuration。

@Controller

控制器,归属的是逻辑业务层,用户控制用户的行为,用来检查参数的有效性;通俗的讲,就是判断前端请求的合理性。

@Service

服务,归属的是服务层,调用持久化类来实现响应的功能,不直接和数据库交互,也不直接和前端请求交互,类似于控制中心;通俗的来说,就是中控,对前端的请求功能负责,然后来调配合适的数据库表。

@Repository

仓库,归属的是持久层,直接和数据库进行交互,通常每个表对应一个仓库;通俗的讲,就是一个库负责一个表的增删查改。

@Configuration

配置,归属的是配置层,用来配置当前项目的一些信息;通俗的说,对项目的全局配置负责。

@Component

组件,归属的是公共工具类,提供一些公共方法。

方法注解

@Bean,将当前修饰方法的方法对象存入到Spring中。

需要注意的一点就是@Bean注解必须要配合类注解来使用,否则就是无效的方法注解。

为啥要有这么多注解?

从本质上来说,五大注解的作用是一样的,都是将对象存入Spring中,那为啥还要有这么多的注解呢?从五大类注解的含义上来说,其作用就是分层,而不是一个类就将从前端接收过来的内容进行判断,改写最后给到数据库更改,而是一层一层,一层负责一件事,这样效率即提高了不少,还能增强代码的可更改性,减少“屎山代码”的出现。

对于上述注解的分层,大概是这样来区分的:首先前端接收到内容,将内容以一定的方式传给后端,后端在@Controller层接收内容,并在Controller层判断前端内容的合理性,然后将内容传给@Service层,此层作为一个中转层,接收@Controller层传过来的东西,再将东西传给@Repository,此层负责和数据库进行对接。这就是大致内容,然后另外两个注解就是负责其他的内容,等到碰见的时候做了解即可。

c. 添加注解存对象

使用五大注解

先简单的写一个内容来熟悉一下注解的作用,并且用启动类来看一下能否获取到结果。

首先就是将创建的包写入到扫描路径中,直接将下述代码置于配置文件中即可,必须要写配置文件,否则写了注解也无用。

<content:component-scan base-package="org.example.controller"></content:component-scan>

将配置文件写好之后,就可以开始写主要内容了,还是实现一个简单的hello world吧,毕竟学习一个新的编程,最先开始学的就是如何输出hell world了。

package org.example.controller;

import org.springframework.stereotype.Controller;

@Controller
public class ArticleController {
    public String sayHello() {
        return "hello world";
    }
}

当有了配置文件并且也加了注解之后,其实内容就已经存储到Spring容器之中了,然后咋们来用启动类看一下结果吧。

package org.example;

import org.example.controller.ArticleController;
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对象
        ArticleController articleController = context.getBean("articleController", ArticleController.class);

        //输出查看结果
        System.out.println(articleController.sayHello());
    }
}

到这里,大家已经会用注解来存储对象了。

如下图有一个问题就是我明明没写Bean对象的名称,为啥我使用了Bean对象的名称还不会报错?

这是因为在Spring中,默认Bean对象的名称就是将其类名的第一个字母小写。前提是类名书写规范的情况下,那么书写不规范呢?如果类名都是小写字母,那么就是使用类名就可以,如果第一个字母和第二个字母都是大写字母的话,那么也是使用类名获取。

使用方法注解

使用方法注解和使用类注解大致操作方法几乎一样,但是需要注意的就是使用方法注解时也必须要把类注解加上去,否则的话方法注解也没法使用。

也写一个简单的内容来看一下@Bean注解的作用吧,首先肯定是将类写入扫描路径中,但是我和类注解是在一个包下,因此不用配置,大家看一下自己的是否需要配置。

创建一个User类

在这里我使用了一个@Data注解,它的意思就是不用写set和get等各种方法,减少代码的冗余度,接下来有可能会写一个文章来专门介绍一个它,大家可以这样用,也可以写set和get方法。

package org.example.enity;

import lombok.Data;

@Data
public class User {

    private Integer id;
    private String username;
    private String password;

}

然后的话就是使用Bean注解了。

如下代码,搭配上了Controller注解来用,这些代码没啥真正的含义,就只是表示一下Bean注解的用处。

package org.example.controller;

import org.example.enity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {

    @Bean
    public User user() {
        User user = new User();
        user.setId(1);
        user.setUsername("王五");
        user.setPassword("123");
        return user;
    }

}

使用一个启动类来看一下结果。

public static void main(String[] args) {
        //获取Spring
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        //获取Bean对象
        User user = context.getBean("user", User.class);

        //输出查看结果
        System.out.println(user);
    }

上述的Bean注解中,也可也给它一个名字,但是如果自己给了名字之后,就不能使用默认的名字了,并且好像默认的名字是和方法名一致,当然我不能太确定,只是自己做了一个简单实验验证了一小下。

@Bean(name = "user")

上述大致就是使用注解来存Bean对象的内容了。

d. 获取Bean对象

在上篇文章中,我们已经了解了先获取Spring对象再获取Bean对象的方法。接下来我们了解的不是使用注解来获取Bean对象,一般我们不会使用ApplicationContext和BeanFactory这两种方式,这虽然也能获取,但是使用注解是更好的方式,使用的注解是@Autowired和@Resource。

获取对象也叫做对象装配,意思是把对象取出来放到某个类中,有时候也叫做对象注入。

三大注入方式

属性注入、set注入、构造方法注入。

在注入方式的介绍中,要用到简单的分层,不然的话没办法演示这个注入效果。

如上图所示,三个类是咋们需要用到的类,两个类分层,然后App充当启动类,如果是在标准Web开发中,其本质就是前端,发送请求和接收请求;创建好之后,首先在spring-config.xml中将包名加上去,不然的话加上注解也毫无意义。

首先创建一个Service层。

package org.example.service;

import org.springframework.stereotype.Service;

@Service
public class CatService {
    public String sayHello() {
        return "hello 小猫!";
    }
}

然后创建一个Controller层。

这个就是简单的基本代码,只需要加入注入方式即可。

package org.example.controller;

import org.springframework.stereotype.Controller;

@Controller
public class CatController {
    
    public String sayHello() {
        return catService.sayHello();
    }
    
}

最后就是启动类了。

启动类的代码永远不用变,一直都是这个样子,只需要把这个controller层的代码写好即可。

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        CatController controller = context.getBean("catController", CatController.class);

        System.out.println(controller.sayHello());
    }
属性注入
@Autowired
private CatService catService;

属性注入的缺点:

功能性问题:无法注入一个不可变对象(final修饰的对象);

通用性问题:只能适用于IoC容器;

设计原则问题:更容易违背单一设计原则(针对对象是类)。

set注入
    @Autowired
    private CatService catService;
    public void setCatService(CatService catService) {
        this.catService = catService;
    }

和第一种方法相比,只是上述代码发生了改变。

它的优点就是更加符合单一设计原则(针对对象是方法级别);但是它的缺点也很明显:

不能注入不可变对象(即final修饰的对象);

注入的对象可被修改(由于setStudentService是普通方法,因此可以被重复调用,在重复调用的时候就存在被修改的风险)。

构造方法注入
    @Autowired
    private CatService catService;
    public CatController(CatService catService) {
        this.catService = catService;
    }

Spring推荐构造方法注入,使用构造方法注入@Autowired可以省略;适用于一个构造方法,如果有多个构造方法,那么不能省略。

其优点是:

可以注入不可变对象;

注入对象不会被修改(可以加上final修饰符;构造方法只是在类加载时执行一次,不像set,调用一次就执行一次,存在被修改的风险);

注入的对象会被完全初始化(使用构造方法带来的优点);

通用性更好。

两大注入注解

@Autowired、@Resource

相同点:都是用来进行获取Bean对象的,或者称为对象注入、或者也可也称为为依赖注入。

不同点:
Autowired是Spring提供的,而Resource则是JDK提供的;

Autowired可以实现三种注入方法,而Resource则不可以实现构造方法注入;

Autowired先根据名称获取,如果名称获取不到,才根据类型获取;Resource则是先根据类型获取,如果获取不到再根据名称获取;

Autowired支持required参数,而Resource则支持更多的参数,例如在一个典型的问题中:多个Bean对象类型相同获取报错,由于其没有按照规范写名称所致,如果使用Autowired注解的话,则需要多写一个@Qualifier(value = "")注解解决,但是在Resource注解中只需要加一个括号写入name即可。

总结

五大类注解和方法注解的了解;

三大注入方式和两大注入注解的了解。

更到这里,对于Spring的存取也就差不多了,最重要的也就是注解了,以后Spring中会一直使用,需要真正的理解其的作用接下来更的应该就是Bean对象的一些内容,然后就是SpringBoot等等。

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

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

相关文章

Virtual安装centos后,xshell连接centos

1. 网络使用Host-Only模式动态分配IP&#xff0c;运行 system restart network 后&#xff0c;使用ifconfig查看新的ip&#xff0c;XShell可以直接连上centos&#xff0c; 但是由于使用的是Host-Only模式&#xff0c;centos不能访问网络&#xff0c;只能与宿主机相互通信 2. 网…

【C语言基础】分享近期学习到的volatile关键字、__NOP__()函数以及# #if 1 #endif

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

【算法每日一练]-分块(保姆级教程 篇1)POJ3648

插讲一下分块 题目&#xff1a;&#xff08;POJ 3648&#xff09; 一个简单的整数问题 前缀和往往用于静态的不会修改的区间和。遇到经常修改的区间问题&#xff0c;就要用分块或线段树来维护了。 分块算法是优化后的暴力&#xff0c;分块算法有时可以维护一些线段树维护不了的…

【JavaEE初阶】计算机是如何工作的

一、计算机发展史 计算的需求在⼈类的历史中是广泛存在的&#xff0c;发展大体经历了从⼀般计算⼯具到机械计算机到目前的电子计算机的发展历程。 人类对计算的需求&#xff0c;驱动我们不断的发明、改善计算机。目前这个时代是“电子计算机”的时代&#xff0c;发展的潮流是…

【算法挨揍日记】day21——64. 最小路径和、174. 地下城游戏

64. 最小路径和 64. 最小路径和 题目描述&#xff1a; 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 解题思路&#xff1a; 状态表示&…

数据结构与算法之美学习笔记:21 | 哈希算法(上):如何防止数据库中的用户信息被脱库?

目录 前言什么是哈希算法&#xff1f;应用一&#xff1a;安全加密应用二&#xff1a;唯一标识应用三&#xff1a;数据校验散列函数解答开篇内容小节 前言 本节课程思维导图 如果你是 一名工程师&#xff0c;你会如何存储用户密码这么重要的数据吗&#xff1f;仅仅 MD5 加密一下…

Java拼图

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 创建一个代码类 和一个运行类 代码如下&#xff1a; package heima;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import jav…

YOLOv8改进 | 2023 | InnerIoU、InnerSIoU、InnerWIoU、FoucsIoU等损失函数

论文地址&#xff1a;官方Inner-IoU论文地址点击即可跳转 官方代码地址&#xff1a;官方代码地址-官方只放出了两种结合方式CIoU、SIoU 本位改进地址&#xff1a; 文末提供完整代码块-包括InnerEIoU、InnerCIoU、InnerDIoU等七种结合方式和其Focus变种 一、本文介绍 本文给…

拼图小游戏

运行出的游戏界面如下&#xff1a; User类 package domain;/*** ClassName: User* Author: Kox* Data: 2023/2/2* Sketch:*/ public class User {private String username;private String password;public User() {}public User(String username, String password) {this.user…

【C语言基础】分享近期学习到的volatile关键字、__NOP()以及# #if 1 #endif

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

记录基于scapy构造ClientHello报文的尝试

最近有个需求就是用scapy构造https的client hello报文&#xff0c;由用户指定servername构造对应的报文。网上对于此的资料甚少&#xff0c;有的也是怎么去解析https报文&#xff0c;但是对于如果构造基本上没有找到相关的资料。 一直觉得最好的老师就是Python的help功能和dir功…

分组交换技术

目录 一、新型计算机网络的基本特点 二、电路交换 1、回顾电路交换的原理 2、使用交换机连接许多部电话 3、电路交换举例 4、电路交换的三个阶段 5、电路交换的特点 三、分组交换 1、因特网有边缘部分与核心部分组成 2、分组交换的原理 3、分组交换的优点 4、存储转…

如何使用贝锐花生壳内网穿透远程访问JupyterNotebook?

在数据科学领域&#xff0c;Jupyter Notebook 已成为处理数据的必备工具。 其用途包括数据清理和探索、可视化、机器学习和大数据分析。Jupyter Notebook的安装非常简单&#xff0c;如果你是小白&#xff0c;那么建议你通过安装Anaconda来解决Jupyter Notebook的安装问题&#…

YOLOv8改进 | EIoU、SIoU、WIoU、DIoU、FoucsIOU等二十余种损失函数

一、本文介绍 这篇文章介绍了YOLOv8的重大改进&#xff0c;特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体&#xff0c;如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU&#xff0c;还融合了“Focus”思想&#xff0c;创造了一系列新的损失函数。这些组合形式的…

java--俄罗斯方块

一、先看一下游戏运行时的画面 二、代码部分 1. Cell.java Cell.java&#xff1a; package demo1;import java.awt.image.BufferedImage; import java.util.Objects;/* 编写小方块类属性&#xff1a;行、列、每个小方格的图片方法&#xff1a;左移一格、右移一格、下落一格 编…

快速支持客户知识库的核心优势是什么?

快速支持客户知识库是一个集中存储和组织企业知识的平台&#xff0c;包含了丰富的信息和解决方案&#xff0c;以帮助客户快速解决问题&#xff0c;帮助企业提高客户支持效率和满意度。那么&#xff0c;快速支持客户知识库的核心优势是什么呢&#xff1f; | 1、提高客户自助支持…

gitlab环境准备

1.准备环境 gitlab只支持linux系统&#xff0c;本人在虚拟机下使用Ubuntu作为操作系统&#xff0c;gitlab镜像要使用和操作系统版本对应的版本&#xff0c;(ubuntu18.04,gitlab-ce_13.2.3-ce.0_amd64 .deb) book100ask:/$ lsb_release -a No LSB modules are available. Dist…

2018年计网408

第33题 下列 TCP/P应用层协议中, 可以使用传输层无连接服务的是()A. FTPB. DNSC. SMTPD. HTTP 本题考察TCP/IP体系结构中&#xff0c;应用层常用协议所使用的运输层服务。 如图所示。这是TCP/IP体系结构中常见应用层协议各自所使用的运输层端口,。在这些应用层协议中&#x…

基于51单片机水位监测控制报警仿真设计( proteus仿真+程序+设计报告+讲解视频)

这里写目录标题 &#x1f4a5;1. 主要功能&#xff1a;&#x1f4a5;2. 讲解视频&#xff1a;&#x1f4a5;3. 仿真&#x1f4a5;4. 程序代码&#x1f4a5;5. 设计报告&#x1f4a5;6. 设计资料内容清单&&下载链接&#x1f4a5;[资料下载链接&#xff1a;](https://doc…

苹果签名应用掉签频繁原因排查,以及如何避免

作为一个对iOS生态有着深厚理解的实用技术博主&#xff0c;我明白苹果签名应用掉签对我们的开发和使用带来的困扰。签名在苹果设备中扮演着至关重要的角色&#xff0c;它不仅确保了应用来源的合法性&#xff0c;也影响着应用的顺畅运行。 今天&#xff0c;我将和您一同探讨苹果…