常用的网站开发设计语言,广州网页设计公司,做期货的的都喜欢去什么网站,自适应网站功能Bean 作用域与生命周期
对于 Spring 来说#xff0c;核心操作对象就是存和取 Bean #xff0c;接下来就 Bean 的作用域与生命周期进行探讨。 文章目录 Bean 作用域与生命周期一、作用域的定义1.1、Bean 的6种作用域1.2、Bean作用域设置方法 二、Bean 的生命周期2.1、Bean…Bean 作用域与生命周期
对于 Spring 来说核心操作对象就是存和取 Bean 接下来就 Bean 的作用域与生命周期进行探讨。 文章目录 Bean 作用域与生命周期一、作用域的定义1.1、Bean 的6种作用域1.2、Bean作用域设置方法 二、Bean 的生命周期2.1、Bean 的执行流程2.2、Bean 的生命周期分为5大部分 ☆ 通过例子看作用域 1、先在Spring IoC 容器中存放一个 Bean公共 Bean
Component
public class StudentComponent {Beanpublic Student studentNum1() {Student student new Student();student.setId(1);student.setName(java); //student.setPassword(123);return student;}
} 这段代码表示在 Spring IoC 容器中已经存上了一个 Bean 对象 并且 对象的 id 设置成 1对象的 name 设置成了 java对象的 password 设置成了 123.
2、A用户来取出 Spring IoC 容器中的这个 Bean 对像进行了修改操作
Controller
public class StuedntControllerA {Autowiredprivate Student student;public Student getStudent() {System.out.println(修改 student 信息);student.setPassword(456);student.setName(python);student.setId(2);return student;}
} 这段代码表示A用户取出容器中的 Bean 对象之后又再次基础上修改了 Bean对象里面的信息password 改成为456name改成了 python。
3、B用户什么也不操作只是在 Spring IoC 容器中取出 Bean 对象。
Controller
public class StudentControllerB {Resourceprivate Student student;public Student getStudent() {return student;}
} 平常我们会认为 A 用户在 Spring IoC 容器中里面取出的对象做出了修改可以修改成功变成修改之后的样子而 B 用户他没有任何操作只是从 Spring IoC 里面取出了 Bean 对象故里面的数据还是原来 Bean 对象的数据。
但是我们还是要运行程序看结果 最后的结果是 A 用户确实修改了信息但是 B 用户的信息取得是 A 用户的信息。
原因分析 因为在默认情况下 Bean 是单例模式singleton也就是所有人使用的都是同一个对象使用单例模式好处之一就是可以很大程度的提高性能 所以在 Spring 中 Bean 的作用域默认是 singleton 单例模式。 都是同一个对象 Bean。而 Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种行为模式比如 上面singleton 单例作⽤域就表 示 Bean 在整个 Spring 中只有⼀份它是全局共享的那么当其他⼈修改了这个值之后那么另⼀个 ⼈读取到的就是被修改的值。
一、作用域的定义
限定程序中变量的可用范围叫做作用域或者说在源代码中定义变量的某个区域就叫做作用域。
1.1、Bean 的6种作用域
Spring 容器在初始化一个 Bean 的实例时同时会指定该实例的作用域。
singleton单例作用域Spring 支持prototype原型作用域多例作用域Spring 支持request请求作用域Spring MVC 生效session会话作用域Spring MVC 生效application全局作用域Spring MVC 生效websocketHttp WebSocket 作用域Spring MVC 生效了解
这篇的后面四个都是用在 Spring MVC 里面的Spring MVC 在 Spring 中也是一个非常重要的框架后面也会了解到这篇主要看看 Spring 支持的其中 singleton 已经了解到了接下来就是 prototype。 prototype 描述每次对该作用域下的 Bean 请求都会创建新的实例获取 BeangetBean方法及装配 Bean 通过Autowired注入都是新的对象实例。 所以说适用上面的情况创建出新的实例不会影响 A 用户修改了Bean 之后B 用户再去拿就是原先 Bean 对象里面的数据不会改变。
1.2、Bean作用域设置方法
使用 Scope 标签 可以用来声明 Bean 的作用域比如设置 Bean 的作用域。
1、直接写 String 类行的作用域
Scope(prototype)2、使用全局的参数
Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)代码如下
Component
public class StudentComponent {
// Scope(prototype) 方式一Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 方式二Beanpublic Student studentNum1() {Student student new Student();student.setId(1);student.setName(java);student.setPassword(123);return student;}
}这样使用多列模式 prototype B 用户就不会受到影响
二、Bean 的生命周期
2.1、Bean 的执行流程
Bean 的执行流程Spring 的执行流程启动 Spring 容器 —— 实例化 Bean 创建 Bean 分配内存空间—— Bean 注册到 Spring 中存—— 将 Bean 装配到需要的类中取。 Spring Core 执行流程
1、启动 Spring 容器main方法
2、加载 XML实例化并申请内存
3、将添加了5大注解的对象存储到容器中。
4、将存储的 Bean 中的注入的对象属性进行初始化。
2.2、Bean 的生命周期分为5大部分 ☆
Bean 的生命周期从 Bean 诞生到销毁的整个过程☆☆☆☆☆
1、实例化 Bean 对象只是申请内存空间
2、先设置 Bean 属性 依赖注入和装配
3、再对 Bean 初始化
各种 Aware 感知BeanNameAware、BeanFactoryAware…的接口方法初始化前置方法BeanPostProcessor构造器方法 PostConstruct 初始化方法 依赖注入操作之后被执行☆init-method 初始化方法 xml初始化后置方法BeanPostProcessor 实力化 和 初始化的区别 实例化和属性设置是 Java 级别的系统“事件”其操作过程不可人工干预和修改而初始化是给 开发者提供的可以在实例化之后类加载完成之前进⾏⾃定义“事件”处理。 4、使用 Bean
5、销毁 Bean
PreDestroydestroy-method 再对 Bean 初始化里面的东西进行解释 1、Aware 这个就是一个感知通知映射关系比如说在方法注解Bean“pwd”上面使用了别名 Aware需要找对应关系通知映射 2、为什么设置 Bean 属性在初始化前面因为只有被类注入初始化的时候不会因为需要类的其他属性报错。 3、初始化方法 PostConstruct 和 init-method 本质上上一样的是不同时期的产物程序员PostConstruct 可以根据业务配置初始化条件属于是注解Spring 时期的init-method 是 xml 时期的比较远古。 4、这也对应了销毁 Bean 里面的PreDestroy和destroy-method 生命周期演示代码
Component
public class BeanLife implements BeanNameAware {Overridepublic void setBeanName(String s) {System.out.println(执行BeanNameAware setBeanName 方法s);}// 初始化方式一PostConstructPostConstructpublic void postConstruct() {System.out.println(执行了PostConstruct);}// 初始化方式二init-methodpublic void init(){System.out.println(执行了init-method); //要是用 xml 配置 Beans里面的标签}// 销毁方法一PreDestroypublic void preDestroy(){System.out.println(执行了preDestroy);}//销毁方式二public void myDestroy(){System.out.println(执行了myDestroy); //要是用 xml 配置 Beans里面的标签}}xml配置如下
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contenthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://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!-- 配置一下bean注解扫描的根路径方面后面更简单存储对象到spring容器--content:component-scan base-packagecom.yuanye.beans/content:component-scanbeansbean idbeanLife classcom.yuanye.beans.Component.BeanLife init-methodinitdestroy-methodmyDestroy/bean/beans
/beans特别注意 Beans 里面的配置
调用类方法
public class App {public static void main(String[] args) {// 是ApplicationContext的子类获得 spring 上下文对象ClassPathXmlApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);BeanLife beanLife context.getBean(beanLife,BeanLife.class);System.out.println(使用 Bean);System.out.println(销毁 Bean);context.destroy();}
}流程图如下 总结
本篇文章介绍了 Bean 的6种作用域和 Bean 的执行流程还有重要的 Bean 的生命周期生命周期里面的实例化和初始化是不一样的一个是不能人控制一个是可以人为控制Bean 的生命周期里面特别是初始化环节很重要。