外贸soho 怎么做网站,php怎么网站开发,宁波网站建设公司哪家口碑好,源码商城交易平台【JavaEE】Spring的开发要点总结#xff08;4#xff09; 文章目录 【JavaEE】Spring的开发要点总结#xff08;4#xff09;1. Bean的作用域1.1 一个例子感受作用域的存在1.2 通过例子说明作用域的定义1.3 六种不同的作用域1.3.1 singleton单例模式#xff08;默认作用域… 【JavaEE】Spring的开发要点总结4 文章目录 【JavaEE】Spring的开发要点总结41. Bean的作用域1.1 一个例子感受作用域的存在1.2 通过例子说明作用域的定义1.3 六种不同的作用域1.3.1 singleton单例模式默认作用域1.3.2 prototype原型模式1.3.3 request请求作用域1.3.4 session会话作用域1.3.5 application全局/应用作用域1.3.6 websocket HTTP WebSocket作用域 1.4 设置Bean的作用域 2. Bean的生命周期2.1 Spring的执行流程2.2 Spring 的生命周期2.3 Bean的生命周期2.3.1 Bean初始化2.3.2 Bean生命周期代码演示2.3.3 为什么属性设置比Bean初始化早 【JavaEE】Spring的开发要点总结4
在学习Spring中Bean是最核心的操作资源
使用学习Bean对象是一个重点我们已经知道如何存储它获取它现在我们要知道
它的作用域我们才可以知道怎么使用才能得心应手符合预期~它的生命周期我们才能更加清楚的了解它的“生与死”即程序执行的过程~
1. Bean的作用域
在学习C语言或者JavaSE的时候熟悉一个变量的作用域非常重要否则会出现很多错误并且违背一些设计上的初心~
C语言 全局变量整个源文件可以访问代码从上到下执行局部优先隔着源文件需要extern…局部变量在代码块中生效在方法中生效代码从上到下执行静态变量局部变量的作用域全局变量的生命周期~ Java 修饰访问限定符局部变量…成员变量静态成员变量…
知己知彼才能百战百胜~
1.1 一个例子感受作用域的存在
之前的代码我们只是一个简单的读操作没有涉及其他所以作用域感受不明显接下来一个例子说明一下~ 背景故事 一个公司开发了一个外卖平台这个公司打算将这个平台卖给别的公司赚收成和维护费但是每个公司都有特定的要求而员工三人小马、大马、老马负责这个项目小马负责公司原本的代码大马负责A公司的外卖平台的代码老马则负责B公司。 大马和老马的工作就是对一些功能进行删减添加个别的功能~ 三人各自完成各自的业务~ 所以就会如下的项目结构实际情况要比这复杂很多这个例子只是为了演示罢了 小马代表UserController大马代表UserController1老马代表UserController2
这个Users类就是一些原始的User的诞生和定义的地方~
这个类是一个公共类 这不代表这个里面诞生的对象就是公共的而是存储Bean对象的手段是公共的 那么可能就会有以下场景 再每次设置后都打印一次 System.out.println(user2);他们原本的意思就是他们从spring中获取一个Bean对象用户设置对应的属性为自己所用~
现在我们来测试一下
Component
public class Test {Autowiredprivate UserController userController;Autowiredprivate UserController1 userController1;Autowiredprivate UserController2 userController2;public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);Test test context.getBean(test, Test.class);test.userController.doMethod();test.userController1.doMethod();test.userController2.doMethod();}
}从结果可以看出下一次的更新是在前一次更新的基础上进行的
而小马大马老马三个人的操作都没有问题他们都不知道对方进行修改了 ~
所以可以说明他们用的Bean是同一个就像C语言全局变量那样~
这就是作用域中的一种单例Bean对象
这里的单例跟我们之前的单例不一样之前的单例是那个类的实例只有一个而这里的单例是这个Bean对象的实例只有一个 也就是说这个类型的Bean对象名字为这个名字的Bean对象有且只有一个~
改变Bean对象的作用域也很简单只需要一个注解Scope意思就是作用域~ 默认情况下就是singleton 我们如果要让小马大马老马获得的Bean对象都不一样可以设置为
prototype原型/多例
原型 每次获取该 Bean对象都是重新获取初始的那一个多例 这个类型这个名字的 Bean对象有多个存在 从结果可以看出作用域的改变
1.2 通过例子说明作用域的定义
Bean的作用域指的就是Bean对象在Spring整个框架中的某种行为模式
比如singleton单例模式就表示这个Bean对象在整个Spring容器中只有一份它是全局共享的那么当其他人修改这个值之后另一个人读取到的就是修改后的值再比如prototype原型模式就表示这个Bean对象在整个Spring中可以存在多份并且每次DI的时候都是崭新的一个Bean对象不同人获得的Bean是不一样的 所以prototype模式下的Bean对象的作用域就是需要注入这个Bean的那个类的一个实例内部类比两个不同的方法中定义的同一类型同一名字的变量~
1.3 六种不同的作用域
singleton单例作用域prototype原型作用域request请求作用域session会话作用域application全局作用域websocketHTTP WebSocket作用域
Spring普通项目 Spring Core其实就前面两种singleton 和 prototype
后四种值则是在 Spring MVC 项目中的值
1.3.1 singleton单例模式默认作用域
单例模式的效率比较高性能好
只有第一次去加载它
经典的面试题单例模式的Bean是线程安全的吗
不是线程安全的~
所有人共同操作的变量一定不是线程安全的
解决方案使用ThreadLocal本地线程变量
这是解决线程安全的其中一种方式
文章推荐ThreadLocal不好用那是你没用对 Java Debug 笔记 - 掘金 (juejin.cn)
ThreadLocal的基础方法
set方法get方法remove方法 可能存太多没有remove内存溢出的问题也会出现感兴趣的可以去了解一下 相比于使用锁来解决线程安全问题 使用ThreadLocal可能会导致结果与锁不一致的情况特别是在多个线程之间存在依赖关系的情况下。 因为每个线程都有自己的数据副本如果线程之间需要共享数据并进行协作那么就需要额外的协调机制来保证数据的一致性。否则可能会出现一个线程修改了数据但其他线程并不知道的情况导致结果不一致。 所以在使用ThreadLocal解决线程安全问题时**需要根据具体的业务场景来评估是否适合使用ThreadLocal**并确保线程之间的数据协作和一致性。 对于一些依赖全局状态的场景使用锁可能更适合。 1.3.2 prototype原型模式
每次获取DI的都是一个原型的对象 1.3.3 request请求作用域
顾名思义在每一次HTTP请求的时候创建一次原型与prototype类似
在一次HTTP请求和响应中共享Bean 注意限定在Spring MVC中使用 因为Spring Core项目不支持HTTP Spring MVC项目也叫作 Spring Web项目支持HTTP 1.3.4 session会话作用域
顾名思义一个HTTP Session中共享Bean
例如记录一个用户的登录信息同一个session每次获取Bean的时候不要原型 注意限定在Spring MVC中使用 后面四种可能会比较难理解这是因为我们还没有接触Spring MVC所以不太了解具体用法
之后的实践肯定会对这些知识更加清晰
1.3.5 application全局/应用作用域
在一个http servlet Context中共享Bean
即一个Context容器共享Bean
web应用的上下文信息例如记录一个应用的共享信息 注意限定在Spring MVC中使用 对于普通的Spring项目是不能用这个值的
但是对于singleton单例模式Bean的作用域不超过一个ApplicationContext对象一个context是一个容器不同context进行各自的注入… singleton和application有什么区别呢 前者是Spring Core的全局作用域作用于IoC容器后者是Spring MVCSpring Web的全局作用域作用于Servlet容器 了解即可 1.3.6 “websocket” HTTP WebSocket作用域
在一个HTTP WebSocket的生命周期中共享Bean
就是一个特殊项目里使用的特殊值罢了 注意限定在Spring WebSocket中使用 WebSocket的每次会话中保存了一个Map结构的头信息将用来包裹客户端消息头。第一次初始化后直到WebSocket结束都是同一个Bean。 如果对WebSocket项目感兴趣的同学可以去学习如果不感兴趣了解一下也可以 1.4 设置Bean的作用域
直接设置 scope(“prototype”) 利用全局变量 不用记忆单词借助题词
效果一致~ 对于 了解即可 2. Bean的生命周期
2.1 Spring的执行流程
笼统的流程
回答问题的时候不用讲太细致~
启动容器 加载配置文件根据参数 完成Bean的实例化根据提供的扫描路径找五大类注解 这样Bean对象就成型了但是是游离在内存中 注册Bean对象到容器中 装配Bean的属性DI 6.……
2.2 Spring 的生命周期
跟流程基本一致粗糙的了解
启动容器读取配置进行Bean实例化将Bean加入到容器中装配Bean属性给当前类的属性进行赋值DI运行业务代码销毁Bean关闭容器
2.3 Bean的生命周期
所谓的生命周期指的是一个对象从诞生到销毁的整个生命周期我们把这个过程叫做一个对象的生命周期
Spring的一生其实也差不多是Bean 的一生吧~
Bean的生命周期也是经典的面试题
这一部分讲的就比较细致但是也是了解为主~
Bean的生命周期分为以下5大部分
实例化Bean 只是分配内存空间现在Bean既没有初始化而且还是游离在内存中的 设置属性 进行依赖注入将需要的但没有初始化的Bean对象注入到属性中Bean不游离了 Bean初始化 流程较多大概就是对Bean进行一系列的操作然后Bean里面的值是有意义的其中就可能涉及Bean注入的属性 使用Bean销毁Bean
2.3.1 Bean初始化
进行各种通知如BeanNameAware、BeanFactoryAware…的接口方法 就是暴露一个判断而已就是告知你Bean的名字设置好了…至于你知道了这个通知后进行什么逻辑就看你了~而系统也会自动去干一些事情~ 初始化前置方法前戏准备执行初始化方法设置就一定会执行不设置就不会执行 注解的方式PostConstructxml的方式init-method方法 初始化后置方法 进行一些额外的操作和设置以确保Bean在使用之前处于正确的状态xml的方式destroy-method的值注解的方式PreDestroy
2.3.2 Bean生命周期代码演示 以这个实行了BeanNameAware接口的类为例
如图是注解的方式去定义初始化方法
如图是xml的方式去决定使用什么初始化方法
init-method的值对应的就是方法名并且必须存在
用注解设置多个初始化方法也更加方便~ 这是用注解的方式设置销毁Bean的方法 这是用xml的方式设置销毁Bean的方法
对于初始化和销毁方法的设置还有很多其他的方法
但是注解就是香xml的方式一次就一个
测试 用子类有更多的方法 获取Bean使用Bean 扫描路径不要删掉即使没用也要设置的 效果 注解的优先级比较高~
顺序正如我们所料~
2.3.3 为什么属性设置比Bean初始化早
其实这个很容易想例如一下操作 如果user这个没有指向一块内存空间只是null那么就会空指针异常~
而实例化和属性注入之后相当于在这里放了个箱子之后的操作有了对象 文章到此结束谢谢观看 可以叫我 小马我可能写的不好或者有错误但是一起加油鸭 Spring Core普通项目的讲解告一段落接下来是Spring Boot的学习敬请期待 代码位置SpringDemo4/src/main/java · 游离态/马拉圈2023年8月 - 码云 - 开源中国 (gitee.com)