认识Spring(下)
作者:~小明学编程
文章专栏:Spring框架
格言:热爱编程的,终将被编程所厚爱。
目录
Spring更加高效的读取和存储对象
存储bean对象
五大注解
关于五大类注解
对象的注入
属性注入
构造方法注入
Setter注入
三种注入方式的区别
@Resource 和 @Autowired 的区别
Bean的作用域和生命周期
Spring的执行流程
Bean的生命周期
Spring更加高效的读取和存储对象
存储bean对象
前面我们所介绍的方法过于的繁琐,我们可以通过注解来快速实现上述的功能。
<?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.beans"></content:component-scan>
</beans>
首先是我们所依赖的资源,其中com.beans是我们所要扫描的类的包。
五大注解
- Controller 控制器
- Service 服务
- Repository 仓库
- Configuration 配置
- Component 组件
利用上面这五大注解都可以完成我们对象的注入。
@Service
public class UserService {public void sayHi() {System.out.println("hi Service");}
}
@Repository
public class UserRepository {public void sayHi() {System.out.println("Hi Res");}
}
@Controller
public class UserController {public void sayHi() {System.out.println("hello");}
}
@Configuration
public class UserConfig {public void sayHi() {System.out.println("Hi Con");}
}
@Component
public class UserComponent {public void sayHi() {System.out.println("Hi Com");}
}
获取:
public static void main1(String[] args) {//1.获取上下文ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");//2.得到beanUserController userController = context.getBean("userController",UserController.class);userController.sayHi();UserService userService = context.getBean("userService",UserService.class);userService.sayHi();UserRepository userRepository = context.getBean("userRepository",UserRepository.class);userRepository.sayHi();UserConfig userConfig = context.getBean("userConfig",UserConfig.class);userConfig.sayHi();UserComponent userComponent = context.getBean("userComponent",UserComponent.class);userComponent.sayHi();}
获取的时候我们需要注意这个beanname,这个beanname是根据如下的逻辑。
关于五大类注解
既然我们五种注解的随便一种都能完成我们的对象的注入,那么我们为什么还是需要五种注解呢
因为我们一个软件是分为多个层面的,分为多层有助于我们的管理和控制。
Configuration 就是配置层:关于当前项目中的所有配置,都会写在这个文件夹里。
Controller 就是控制层:就是前端参数校验,主要就是校验前端数据的合理性和正确性。
Service 就是服务层,负责数据的组装和接口调用。更直白的说,服务器九四 “牵线搭桥” 让程序去调用对应的功能/接口/服务。
Repository 叫做仓库,但其实是 数据持久层,也叫做 Dao 层,就是对数据进行持久化操作(对数据库进行增删改查操作)。
我们使用不同的注解便于我们了解不同的代码的功能同时也方便我们对代码进行一个管理。
当然这五大类注解之间是有一定的关系的:
可以看到我们的configuration注解是调用了我们的component注解的,其它几个注解的实现方法也是如此,可以说我们的component注解是我们其它四大注解的一个父类。
对象的注入
前面我们了解了怎么样将对象给存储起来,也就是使用五大注解可以高效方便的将我们的对象给放在spring中,但是当我们想要使用的时候有没有什么方式可以比较高效的来使用呢,下面就介绍三种方式来实现我们对象的一个注入。
属性注入
通过 @Autowired 注入:
@Controller
public class UserController {@Autowiredprivate UserService userService;public void sayHi() {userService.sayHi();}
}
这里我们就通过关键字Autoeired的关键字来直接实现我们对象的一个注入,然在下面的方法之中我们就可以直接调用我们注入好的对象的方法了。
public static void main(String[] args) {//1.获取上下文ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");UserController userController = context.getBean(UserController.class);userController.sayHi();//hi Service}
构造方法注入
@Controller
public class UserController {
// @Autowiredprivate UserService userService;public UserController(UserService userService) {this.userService = userService;}public void sayHi() {userService.sayHi();}
}
这里我们可以直接通过构造方法的方式来进行对象的一个注入,但是值得我们注意的是,当我们的构造方法不止一个的时候就必须要使用Autowired关键字了,不然会报错。
@Controller
public class UserController {
// @Autowiredprivate UserService userService;@Autowiredpublic UserController(UserService userService) {this.userService = userService;}public UserController(UserService userService,int num) {this.userService = userService;}public void sayHi() {userService.sayHi();}
}
Setter注入
@Controller
public class UserController {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void sayHi() {userService.sayHi();}
}
同样我们也可以使用Setter这样一个方法来进行一个注入。
三种注入方式的区别
- 属性注入特点是写法简单,但是通用性不好,只能运行在 IoC 容器下,如果是 非 IoC 容器的话,就会出现问题。
- 构造方法注入,通用性更好。因为构造方法的优先级是最高的。确保使用注入对象之前,对象一定初始化过了。当构造方法注入参数太多时,就需要检查自己的代码是否符合单一设计原则的规范了。构造方法注入,也是 Spring 推荐的注入方法。
- Setter 注入是早期 Spring 版本推荐的写法,但是通用性没有构造方法注入通用,因为只有一个参数。
@Resource 和 @Autowired 的区别
相同点:都可以完成对象的注入。
不同点:
- 出身不同,@Resource 来自于 JDK,@Autowired 是由 Spring 框架提供的。
- @Autowired 支持属性注入,构造方法注入 和 Setter 注入,而 @Resource 不支持构造方法注入。
- 支持的参数不同:@Resource 支持更多的参数设置,比如 name、type 设置。而 @Autowired 只支持 required 参数设置。
Bean的作用域和生命周期
在我们使用bean的时候其实默认是用的同一个bean也就是说如果我们对其中的bean进行一个更改的话,那么当我们再次去使用这个bean此时依然是更改之后的bean。
@Component
public class UserBean {@Bean(name = {"user","user1"})
// @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)public User user2() {User user = new User(15,"lisi");return user;}@Bean(name = {"user2"})public User user1() {User user = new User(12,"zhangsan");return user;}
}
@Component
public class BeanScope1 {@Autowiredprivate User user2;public User getUser() {user2.setStr("aaa");return user2;}
}
@Component
public class BeanScope2 {@Autowiredprivate User user2;//user2必须事被注入过的public User getUser() {return user2;}
}
这个时候我们注入了两次bean对象,此时查看输入的结果:
public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");BeanScope1 beanScope1 = context.getBean(BeanScope1.class);System.out.println(beanScope1.getUser());BeanScope2 beanScope2 = context.getBean(BeanScope2.class);System.out.println(beanScope2.getUser());}
可以看到我们在对其进行更改之后,再次注入仍然是更改之后的User。
产生这样的原因是因为 Bean 在 Spring 中,默认情况下是单例状态,也就是所有人的使用都是同一个对像。这样可以很好的节约资源,避免资源的浪费。
Bean 的六种作用域
singleton:单例作用域(默认)在这种模式下的 Bean 在 IoC 容器里面,只存在一个实例。
prototype:原型作用域(多例模式)每次对作用域下的 Bean 请求,都会创建新的实例,然后再去获取 Bean。
request:请求作用域(Spring MVC)每次 Http 请求会创建新的 Bean 实例,类似于 prototype。
session:会话作用域(Spring MVC)在一个 http session 中,定义一个 Bean 实例。记录用户的登录信息。
application:全局作用域(Spring MVC)更多人使用的时候,就用 application。也是单例模式,应用在 Web 应用的上下文信息。
websocket:Http WebSocket 作用域(Spring WebSocket)在 WebSocket 会话中使用。
当我们想要改变其作用域的时候可以通过@Scope 的注解来进行改变
可以看到此时我们 所注入的对象就都是新的对象了。
设置作用域的时候,只需要通过 @Scope 注解就可以了:
- 直接设置值:@Scope(“prototype”)
- 使用枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Spring的执行流程
1.我们首先是要启动我们的容器,去加载我们的配置文件。
也就是我们上面的这段代码。
2.接着就是根据我们的配置来完成我们的bean初始化。
通过扫描包中的spring注解。
3.注册 Bean 对象到容器中,只有在包扫描的路径上的类,且使用 Spring 的注解才可以被注册到容器当中。
4.装配 Bean 属性,也就是把 Bean 注册到其他类当中:
Bean的生命周期
Bean的生命周期就是Baen从诞生到销毁的一个过程 。
- 实例化 Bean(为 Bean 分配内存空间)
- 设置属性(Bean 注入和装配)
- Bean 初始化 a)执行各种通知(各种Aware)如:BeanNameAware,BeanFactoryAware,ApplicationContextAware 的接口方法。
b)执行 BeanPostProcessor 初始化前置方法。
c)执行 @PostConstruct 初始化方法,依赖注入操作之后被执行。
d)执行自己指定的 init-method 方法(如果有指定的话
e)执行 BeanPostProcessor 初始化后置方法。 - 使用 Bean
- 销毁 Bean,通过方法来销毁容器:如 @PreDestroy、DisposableBean、destroy-method
其大概的流程图就是这样的。
<?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.beans"></content:component-scan><bean id="beanLife"class="com.beans.BeanLife" init-method="init"></bean>
</beans>
package com.beans;import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;/*** Created with IntelliJ IDEA.* Description:* User: 86184* Date: 2023-03-06* Time: 22:07*/
@Component
public class BeanLife implements BeanNameAware {@PostConstructpublic void Post() {System.out.println("PostConstruct");}@PreDestroypublic void Pre() {System.out.println("pre");}public void use() {System.out.println("use");}public void init() {System.out.println("init");}public void setBeanName(String s) {System.out.println("通知");}
}
执行流程如上。
相关文章:

认识Spring(下)
作者:~小明学编程 文章专栏:Spring框架 格言:热爱编程的,终将被编程所厚爱。 目录 Spring更加高效的读取和存储对象 存储bean对象 五大注解 关于五大类注解 对象的注入 属性注入 构造方法注入 Setter注入 三种注入方式的…...

Educational Codeforces Round 144 (Rated for Div. 2) C - Maximum Set
传送门 题意: 对于一个集合,如果它的任意两个元素都能 有 其中一个能整除另一个,那么它是好的。问在区间[L,R] 中由这个区间某些数内构成的好的集合的最长长度是多少,以及且满足这个长度的好集合有多少个。(懒得想就借…...

学python的第四天---基础(2)
一、三角形类型读入数组并排序的方法nlist(map(float,input().split())) c,b,asorted(n)list_1 list(map(float, input().split())) list_1.sort() list_1.reverse()lengthssorted(map(float,input().split(" ")),reverseTrue)二、动物写法一:d{" &…...

spring之refresh流程-Java八股面试(六)
系列文章目录 第一章 ArrayList-Java八股面试(一) 第二章 HashMap-Java八股面试(二) 第三章 单例模式-Java八股面试(三) 第四章 线程池和Volatile关键字-Java八股面试(四) 第五章ConcurrentHashMap-Java八股面试(五) 动态每日更新算法题,想要学习的可以关注一下…...

【C语言】刷题|链表|双指针|指针|多指针|数据结构
主页:114514的代码大冒 qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ ) Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 一、移除链表元素 二、反转链表 三,链表的中间结点 四&…...

糖化学类854262-01-4,Propargyl α-D-Mannopyranoside,炔丙基 α-D-吡喃甘露糖苷
外观以及性质:Propargyl α-D-Mannopyranoside一般为白色粉末状,糖化学类产品比较多,一般包括:葡萄糖衍生物、葡萄糖醛酸衍生物,氨基甘露糖衍生物、半乳糖衍生物、氨基半乳糖衍生物、核糖衍生物、阿拉伯糖衍生物、唾液…...

项目管理工具DHTMLX 在 G2 排名中再创新高
DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求,具备完善的甘特图图表库,功能强大,价格便宜,提供丰富而灵活的JavaScript API接口,与各种服务器端技术&am…...

28 位委员出席,龙蜥社区第 15 次运营委员会会议顺利召开
2 月 24 日,龙蜥社区在海光召开了第 15 次运营委员会会议,本次会议由统信软件运营委员会委员崔开主持。来自 Arm、阿里云、飞腾、红旗软件、海光、Intel、龙芯、联通软研院、浪潮信息、普华基础软件、统信软件、万里红、移动、中科方德等理事单位的 28 位…...

自然语言处理-基于预训练模型的方法-chapter3基础工具集与常用数据集
文章目录3.1NLTK工具集3.1.1常用语料库和词典资源3.1.2常见自然语言处理工具集3.2LTP工具集3.3pytorch基础3.3.1张量基本概念3.3.2张量基本运算3.3.3自动微分3.3.4调整张量形状3.3.5广播机制3.3.6索引与切片3.3.7降维与升维3.4大规模预训练模型3.1NLTK工具集 3.1.1常用语料库和…...

【SpringMVC】@RequestMapping
RequestMapping注解 1、RequestMapping注解的功能 从注解名称上我们可以看到,RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。 SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处…...

【深度学习】BERT变体—SpanBERT
SpanBERT出自Facebook,就是在BERT的基础上,针对预测spans of text的任务,在预训练阶段做了特定的优化,它可以用于span-based pretraining。这里的Span翻译为“片段”,表示一片连续的单词。SpanBERT最常用于需要预测文本…...

根据身高体重计算某个人的BMI值--课后程序(Python程序开发案例教程-黑马程序员编著-第3章-课后作业)
实例3:根据身高体重计算某个人的BMI值 BMI又称为身体质量指数,它是国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。我国制定的BMI的分类标准如表1所示。 表1 BMI的分类 BMI 分类 <18.5 过轻 18.5 < BMI < 23.9 正常 24 < BM…...

高并发编程JUC之进程与线程高并发编程JUC之进程与线程
1.准备 pom.xml 依赖如下: <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target&g…...

css基础
1-css引入方式内嵌式style(学习)<style>p {height: 200;}</style>外联式link(实际开发)<link rel"stylesheet" href"./2-my.css">2-选择器2.1标签选择器(标签名相同的都生效&am…...

Unity - 搬砖日志 - BRP 管线下的自定义阴影尺寸(脱离ProjectSettings/Quality/ShadowResolution设置)
文章目录环境原因解决CSharp 脚本效果预览 - Light.shadowCustomResolution效果预览 - Using Quality Settings应用ControlLightShadowResolution.cs ComponentTools Batching add the Component to all LightReferences环境 Unity : 2020.3.37f1 Pipeline : BRP 原因 (好久没…...

如何在SSMS中生成和保存估计或实际执行计划
在引擎数据库执行查询时执行的过程的步骤由称为查询计划的一组指令描述。查询计划在SQL Server中也称为SQL Server执行计划,我们可以通过以下步骤来生成和保存估计或实际执行计划。 估计执行计划和实际执行计划是两种执行计划: 实际执行计划:当执行查询时,实际执行计划出…...

mac 环境下安装MongoDB
目录 一、下载MongoDB数据库并进行安装 二. 解压放在/usr/local目录下 三. 配置环境变量 “无法验证开发者”的解决方法 mongodb可视化工具的安装与使用 一、下载MongoDB数据库并进行安装 下载地址:https://www.mongodb.com/try/download/community 二. 解压…...

RTOS中相对延时和绝对延时的区别
相信许多朋友都有过这么一个需求:固定一个时间(周期)去处理某一件事情。 比如:固定间隔10ms去采集传感器的数据,然后通过一种算法计算出一个结果,最后通过指令发送出去。 你会通过什么方式解决呢…...

Solon2 项目整合 Nacos 配置中心
网上关于 Nacos 的使用介绍已经很多了,尤其是与 SpringBoot 的整合使用。怎么安装也跳过了,主要就讲 Nacos 在 Solon 里的使用,这个网上几乎是没有的。 1、认识 Solon Solon 一个高效的应用开发框架:更快、更小、更简单…...

Linux 路由表说明
写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。 目录route 命令字段分…...

MIPI协议
MIPI调试指南Rev.0.1 June 18, 2019 © 2018 Horizon Robotics. All rights reserved.Revision HistoryThissection tracks the significant documentation changes that occur fromrelease-to-release. The following table lists the technical content changes foreach …...

第十届CCF大数据与计算智能大赛总决赛暨颁奖典礼在苏州吴江顺利举办
2月24日-25日,中国计算机学会(CCF)主办、苏州市吴江区人民政府支持,苏州市吴江区工信局、吴江区东太湖度假区管理办公室、苏州市吴江区科技局、CCF大数据专家委员会、CCF自然语言处理专业委员会、CCF高性能计算专业委员会、CCF计算…...

PMP高分上岸人士的备考心得,分享考试中你还不知道的小秘密
上岸其实也不是什么特别难的事情,考试一共就180道选择题,题目只要答对60.57%就可以通过考试,高分通过没在怕的,加油备考呀朋友们! 这里也提一嘴,大家备考的时候比较顾虑的一个问题就是考试究竟要不要报班…...

ubuntu下编译libpq和libpqxx库
ubuntu下编译libpq和libpqxx库,用于链接人大金仓 上篇文章验证了libpqxx可以链接人大金仓数据库,这篇文章尝试自己编译libpq和libpqxx库。 文章目录ubuntu下编译libpq和libpqxx库,用于链接人大金仓libpq下载libpq库看看有没有libpq库编译lib…...

ESP-C2系列模组开发板简介
C2是一个芯片采用4毫米x 4毫米封装,与272 kB内存。它运行框架,例如ESP-Jumpstart和ESP造雨者,同时它也运行ESP-IDF。ESP-IDF是Espressif面向嵌入式物联网设备的开源实时操作系统,受到了全球用户的信赖。它由支持Espressif以及所有…...

linux权限管理
权限管理 文件的权限针对三类对象进行定义: owner属主,缩写ugroup属组,缩写gother其他,缩写o 1、文件的一般权限 (1)r,w,x的作用及含义: 权限对文件影响对目录影响r(read…...

提高生活质量,增加学生对校园服务的需求,你知道有哪些?
随着电子商务平台利用移动互联网的趋势提高服务质量,越来越多的传统企业开始关注年轻大学生消费者的校园市场。 提高生活质量,增加学生对校园服务的需求 大学生越来越沉迷于用手机解决生活中的“吃、喝、玩、乐”等服务,如“吃、喝”——可…...

Antlr4:使用grun命令,触发NoClassDefFoundError
1. 意外的发现 在学习使用grun命令时,从未遇到过错误 最近使用grun命令,却遇到了NoClassDefFoundError的错误,使得grun测试工具无法成功启动 错误复现: 使用antlr4命令编译Hello.g4文件,并为指定package(…...

基于rootfs构建Docker镜像
1. 背景 在实际工作中,由于系统本身版本过低,在接受新项目时出现系统版本过低而无法开始工作的问题。 为了解决该问题,使用Docker构建基于ubuntu-18.04的Docker镜像,以解决版本兼容问题。 2. 构建rootfs 2.1. 下载ubuntu-18.0…...

电脑文件软件搬家迁移十大工具
10 大适用于 Windows 的数据迁移软件。 数据迁移至关重要,几乎所有组织都依赖于此。如果您认为数据传输不是一件容易的事,那么数据迁移软件可以帮上忙。 1、奇客电脑迁移 将现有操作系统、软件、文件迁移到 新电脑的最佳方法之一是使用名为奇客电脑迁移…...