【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) {//获取SpringApplicationContext 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 {@Beanpublic User user() {User user = new User();user.setId(1);user.setUsername("王五");user.setPassword("123");return user;}}

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

public static void main(String[] args) {//获取SpringApplicationContext 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注入
    @Autowiredprivate CatService catService;public void setCatService(CatService catService) {this.catService = catService;}

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

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

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

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

构造方法注入
    @Autowiredprivate 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.hqwc.cn/news/194510.html

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

相关文章

Frames X for figma 组件库设计系统 Local Variables下载

简而言之&#xff0c;Frames X 是最出色、易于使用且文档齐全的Figma 设计系统之一。 它包括经过深思熟虑的设计指南和现成的组件&#xff0c;并且还提供一本全面的电子书&#xff0c;其中将详细解释如何使用该套件中包含的所有内容。 事实上&#xff0c;电子书使Frames X 与…

2023年【G1工业锅炉司炉】报名考试及G1工业锅炉司炉理论考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 G1工业锅炉司炉报名考试是安全生产模拟考试一点通生成的&#xff0c;G1工业锅炉司炉证模拟考试题库是根据G1工业锅炉司炉最新版教材汇编出G1工业锅炉司炉仿真模拟考试。2023年【G1工业锅炉司炉】报名考试及G1工业锅炉…

Nginx(七) root和alias的区别及详细测试

本篇文章只讲root和alias的区别&#xff0c;配置文件详解请参考 Nginx(三) 配置文件详解&#xff0c;下面开始进行测试。 Nginx配置如下&#xff1a; server {listen 8688 default_server;server_name www.read******.cn;access_log logs/access.log format2;root pages;set …

大数据Doris(二十五):Stream Load数据导入演示和其他导入案例

文章目录 数据导入演示和其他导入案例 一、数据导入演示

【每日一题】689. 三个无重叠子数组的最大和-2023.11.19

题目&#xff1a; 689. 三个无重叠子数组的最大和 给你一个整数数组 nums 和一个整数 k &#xff0c;找出三个长度为 k 、互不重叠、且全部数字和&#xff08;3 * k 项&#xff09;最大的子数组&#xff0c;并返回这三个子数组。 以下标的数组形式返回结果&#xff0c;数组中…

Java多线程核心技术第一阶段-Java多线程基础 02

接上篇&#xff1a;Java多线程核心技术第一阶段-Java多线程基础 01 3.3 清除中断状态的使用场景 this.interrupted()方法具有清除状态标志值的功能&#xff0c;借用此特性可以实现一些效果。 【示例3.3.1】在MyThread4线程中向list1和list2存放数据&#xff0c;基于单一职责原…

笔记55:长短期记忆网络 LSTM

本地笔记地址&#xff1a;D:\work_file\DeepLearning_Learning\03_个人笔记\3.循环神经网络\第9章&#xff1a;动手学深度学习~现代循环神经网络 a a a a a a a a a

照片+制作照片书神器,效果太棒了!

随着数码相机的普及&#xff0c;越来越多的人喜欢用照片记录生活点滴。而制作一本精美的照片书&#xff0c;不仅可以保存珍贵的回忆&#xff0c;还能让照片更加美观。今天&#xff0c;就为大家推荐一款制作照片书神器&#xff0c;让您的回忆更加完美&#xff01; 一、产品介绍 …

HDFS、MapReduce原理--学习笔记

1.Hadoop框架 1.1框架与Hadoop架构简介 &#xff08;1&#xff09;广义解释 从广义上来说&#xff0c;随着大数据开发技术的快速发展与逐步成熟&#xff0c;在行业里&#xff0c;Hadoop可以泛指为&#xff1a;Hadoop生态圈。 也就是说&#xff0c;Hadoop指的是大数据生态圈整…

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

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

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 非功能性分析…

vscode c++ 报错identifier “string“ is undefined

vscode c 报identifier “string” is undefined 问题 新装了电脑, 装好vsc和g等, 发现报错 但开头并没问题 解决 shiftctrlp选择 C/C Edit:COnfigurations (JSON)自动生成打开 c_cpp_properties.json添加g路径等 "cStandard": "c11","cppStanda…