【Spring】之注解存取Bean对象

在本系列的上一篇文章中,我们已经了解了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等等。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kubenetes-服务发现和负载均衡

一、服务发布 kubenetes把服务发布至集群内部或者外部&#xff0c;服务的三种不同类型&#xff1a; ClusterlPNodePortLoadBalancer ClusterIP是发布至集群内部的一个虚拟IP,通过负载均衡技术转发到不同的pod中。 NodePort解决的是集群外部访问的问题&#xff0c;用户可能不…

FL Studio2024免费编曲音乐制作软件

用FL Studio编曲&#xff0c;让音乐成为你的翅膀&#xff0c;飞翔在无尽的创作海洋中吧&#xff01; FL Studio作为一款功能强大且备受赞誉的音乐制作软件&#xff0c;为你提供了一个独特的创作平台。通过FL Studio&#xff0c;你可以自由地创作、编曲&#xff0c;制作属于自己…

IDEA 搭建 SpringCloud 项目【超详细步骤】

文章目录 一、前言二、项目搭建1. 数据库准备2. 创建父工程3. 创建注册中心4. 服务注册5. 编写业务代码6. 服务拉取 一、前言 所谓微服务&#xff0c;就是要把整个业务模块拆分成多个各司其职的小模块&#xff0c;做到单一职责原则&#xff0c;不会重复开发相同的业务代码&…

Jenkins测完通知到人很麻烦?一个设置配置钉钉消息提醒!

Jenkins 作为最流行的开源持续集成平台&#xff0c;其强大的拓展功能一直备受测试人员及开发人员的青睐。大家都知道我们可以在 Jenkins 中安装 Email 插件支持构建之后通过邮件将结果及时通知到相关人员。但其实 Jenkins 还可以支持钉钉消息通知&#xff0c;其主要通过 DingTa…

【Linux】动静态库的使用与软链接的结合

文章目录 前言一、静态库1.静态库的创建2.静态库的链接3.将库进行打包4.链接方法&#xff1a;1.直接链接2.拷贝到系统路径里面3.采用软链接方法 二、动态库1.解决加载找不到动态库的方法1.直接拷贝2.建立软链接3.建立自己的动态路径配置文件 2.为什么动态库权限需可执行而静态库…

【WSL/WSL2-Ubuntu】突破界限:不使用服务器在一台Windows搭建Nginx+FastDFS

打造超级开发环境&#xff1a;Nginx和FastDFS在WSL中的完美结合 前言 随着软件开发领域的快速发展&#xff0c;跨平台的开发环境变得日益重要。Windows Subsystem for Linux&#xff08;WSL&#xff09;和WSL 2为开发者提供了在Windows操作系统上体验Linux环境的便捷途径。本…

javaspringbootmysql学生社团管理系统26281-计算机毕业设计项目选题推荐(附源码)

目录 摘要 Abstract 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2 学生社团管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析…

用户增长模型:3A3R策略模型

一、概述 A - A - A - R - R - R 增长模型&#xff0c;即3A3R策略模型&#xff0c;由海盗模型演变而来&#xff0c;是目前使用最多、适用范围最广的增长策略模型。原始的海盗模型由 Acquisition &#xff08;获客&#xff09;、 Activation &#xff08;活跃&#xff09;、 Re…

【选题推荐】软件工程毕设选题可以选什么

文章目录 0 简介1 如何选题2 最新软件工程毕设选题3 最后 0 简介 学长搜集分享最新的软件工程业专业毕设选题&#xff0c;难度适中&#xff0c;适合作为毕业设计&#xff0c;大家参考。 学长整理的题目标准&#xff1a; 相对容易工作量达标题目新颖 1 如何选题 最近非常多的…

C语言选择结构 if 语句

if语句 程序运行结构if语句常见三种形式单行格式if语句多行格式if语句多条件的if语句 嵌套if语句if语句案例三只鸡那只重 if语句注意事项 程序运行结构 C语言支持最基本的三种程序运行结构&#xff1a;顺序结构、选择结构&#xff08;分支结构)、循环结构 顺序结构&#xff1…

2023年高压电工证考试题库及高压电工试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年高压电工证考试题库及高压电工试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲随机出的高压…

《洛谷深入浅出基础篇》 P5250 木材仓库————集合应用实例

上链接&#xff1a; P5250 【深基17.例5】木材仓库 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P5250上题干&#xff1a; 题目描述 博艾市有一个木材仓库&#xff0c;里面可以存储各种长度的木材&#xff0c;但是保证没有两个木材的长度是…

Java面向对象(高级)-- 类的成员之四:代码块

文章目录 一、回顾&#xff08;1&#xff09;三条主线&#xff08;2&#xff09;类中可以声明的结构及作用1.结构2.作用 二、代码块&#xff08;1&#xff09;代码块的修饰与分类1. 代码块的修饰2. 代码块的分类3. 举例 &#xff08;2&#xff09; 静态代码块1. 语法格式2. 静态…

两栏布局:左侧固定,右侧自适应

左侧宽度固定&#xff0c;右侧宽度自适应剩余空间 方法一&#xff1a;float margin 方法二&#xff1a;flex布局 相关HTML代码 <div class"container"><div class"left"></div><div class"main"></div> </d…

BGP基本配置

配置逻辑 完成所有路由器的IGP配置使用直连接口建立EBGP对等体关系使用环回接口建立IBGP对等体关系使用connect-interface命令修改IBGP建邻源IP地址使用next-hop-local命令修改路由传递时的下一跳属性若存在使用环回接口建立EBGP对等体关系&#xff0c;则需要建立通讯条件&…

CentOS 7 安装CMake指定版本3.21.2

背景&#xff1a;今天在CentOS 7 电脑上安装C 日志框架SpdLog-1.12.0&#xff0c;提示如下错误信息&#xff1a; [rootlocalhost build]# cmake .. && make -j CMake Error at CMakeLists.txt:3 (cmake_minimum_required):CMake 3.10...3.21 or higher is required. …

Mysql-索引

1.介绍 索引是数据库管理系统中用于提高查询速度的一种数据结构。在MySQL中&#xff0c;索引可以看作是一种特殊的表&#xff0c;其中包含了对数据表中特定列的值及其在数据表中的位置信息。通过使用索引&#xff0c;MySQL可以在不需要扫描整个表的情况下快速找到与查询条件匹…

三栏布局,中间自适应

方法一&#xff1a;两边使用float 中间使用margin 方法二&#xff1a;两边使用absolute 中间使用margin 方法三&#xff1a;flex 布局 方法四&#xff1a;grid 布局 方法一&#xff1a;相关HTML代码【两边使用float 中间使用margin】 <div class"container"…

类和对象(8):explicit,static成员,友元,内部类

一、explicit class Date { public:Date(int year 2023, int month 1, int day 1):_year(year),_month(month),_day(day){}private:int _year;int _month;int _day; };int main() {// Date d1(1); // 这是正常初始化Date d1 1;return 0; }不妨猜测一下&#xff0c;d1的初始…