企业网站内容建设,网站开发小程序开发,室内设计学校全国排名,网站的大小关于Bean对象#xff0c;在将其存储到spring中以后#xff0c;在使用或读取该Bean对象时#xff0c;如果该对象是公有的#xff0c;难免就会出现被一方修改#xff0c;从而影响另外一方读取到的对象准确性的情况。因此了解Bean的作用域和生命周期就是十分必要的了。
首先…关于Bean对象在将其存储到spring中以后在使用或读取该Bean对象时如果该对象是公有的难免就会出现被一方修改从而影响另外一方读取到的对象准确性的情况。因此了解Bean的作用域和生命周期就是十分必要的了。
首先还是具体使用一个例子来理解上面提到的这种情况 文章目录 示例Bean的6种作用域singletonprototyperequestsessionapplicationwebsocket Bean作用域的设置Spring的执行流程Bean生命周期 示例
首先新建一个Student实体类为其设置属性并提供其相关的get/set方法
package com.yun.model;public class Student {private int id;private String name;private double score;public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public double getScore() {return score;}public void setScore(double score) {this.score score;}Overridepublic String toString() {return Student{ id id , name name \ , score score };}
}
创建一个Bean对象使用方法注解存储到Spring;
package com.yun.controller;import com.yun.model.Student;
import com.yun.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;Component
public class StudentBean {Beanpublic Student stu(){Student studentnew Student();student.setId(5);student.setName(李大锤);student.setScore(99.6);return student;}
}
A首先读取并且使用bean同时进行一定的操作
package com.yun.controller;import com.yun.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;/*
* A 1.获取bean
* 2.创建了新的对象对新创建的对象进行修改
* */
Controller
public class StuController1 {Autowiredprivate Student student1;public Student getStu1(){Student studentstudent1;System.out.println(student1 idstudent.getId() namestudent.getName());student.setId(10);student.setName(安慕希);return student;}
}
B 读取bean
package com.yun.controller;import com.yun.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;/*
* B 读取bean获取bean的具体值
* */
Controller
public class StuController2 {Autowiredprivate Student student1;public Student getStud2(){Student studentstudent1;return student;}
}
获取原始bean的值以及A读取到的值和B读取到的值 通过运行结果可以得到结论尽管看起来A是在自己新创建的Bean对象上进行了修改但最终还是会影响到原始公共Bean的值
而究其出现这种结果的原因其实就是因为Bean在默认情况下是单例模式即只有一份对象这份对象供所有访问者使用。因此A进行的修改操作自然也就会影响到B的读取结果。而使用单例状态的原因就是提高性能。
Bean的6种作用域
作用域顾名思义就是“作用到的区域或范围”实际就是程序中变量的一个可用的范围。而Bean的作用域其实就是Bean在Spring框架中的某种行为模式具体共有6种
singleton单例作⽤域prototype原型作⽤域多例作⽤域request请求作⽤域session会话作⽤域application全局作⽤域websocketHTTP WebSocket 作⽤域
singleton 是Spring默认选择的作用域 在此作用域下的Bean在IoC容器中只有一个实例即只有一个全局对象 通常当Bean对象的属性状态不需要更新时即Bean无状态的情况下会使用该作用域 prototype 多例模式下使用的作用域 在此作用域下的Bean每被访问一次就会创建出一个实例 通常当Bean对象的属性状态需要更新时即Bean有状态的情况下会使用该作用域 在普通的Spring项目中一般只有前面两种作用域而后面提到的作用域则是只能在SpringMVC中使用或只能在Spring WebSocket中使⽤
request 在每次http请求时都会创建一个新的Bean的实例 只能在SpringMVC中使用 session 每次会话都会定义一个Bean的实例 只能在SpringMVC中使用 application 在一个http servlet Context中共享一个Bean实例 只能在SpringMVC中使用 websocket 在一个HTTP WebSocket中定义一个Bean实例同时共享这个实例 只能在Spring WebSocket中使⽤ Bean作用域的设置
由于我们这里主要介绍的是Spring项目因此关于Bean作用域的设置也只涉及到两种
singleton是Spring默认的作用域因此一个新创建的bean对象在不进行特别设置的情况下其作用域就是singleton
下面具体演示prototype的设置 prototype的设置有上面图片中所示的两种方式我们也可以从相关类中找到该作用域的定义信息 在为其设置了全局作用域后我们再次执行文章开始的实例得到的结果如下 此时A的修改操作不再影响到B的读取
Spring的执行流程
启动容器 首先启动容器去加载相关的配置文件
进行Bean初始化 对配置了加载组件路径下的类进行扫描即扫描该路径下的文件查看是否有相关的类注解
注册Bean对象到容器
将在加载组件路径下的类中添加了相关注解的类注册到容器中
装配或使用Bean 即将需要使用的Bean注入到需要的类中去
Spring销毁
相关使用操作完毕最终Spring销毁
Bean生命周期
生命周期实际就是一个对象从产生到被销毁的全过程关于Bean生命周期主要有5步
实例化Bean
即为Bean对象分配内存空间
设置属性 对Bean对象进行依赖注入进行Bean初始化 3.1 执行各种通知
3.2 初始化的前置方法
3.3 初始化方法 3.4 初始化的后置方法
使用Bean销毁Bean;
简单使用代码来观察这个过程
package com.yun.controller;import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;public class BeanLife implements BeanNameAware {Overridepublic void setBeanName(String s) {System.out.println(执行 setBeanName 通知 s);}PostConstructpublic void myPostConstruct(){System.out.println(执行 myPostConstruct() 方法);}public void init(){System.out.println(执行 init());}public void use(){System.out.println(执行 use 方法);}PreDestroypublic void myPreDestroy(){System.out.println(执行 myPreDestroy() 销毁);}
}
使用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 iduserService classcom.bit.service.UserService/bean--!-- 配置存储 Bean 对象的扫描根路径 --content:component-scan base-packagecom.yun/content:component-scanbean idbeanlife classcom.yun.controller.BeanLifeinit-methodinit/bean/beans
设置一个启动类
import com.yun.controller.BeanLife;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanLifeApp {public static void main(String[] args) {/** 必须使用ClassPathXmlApplicationContext类ApplicationContext无方法destroy()方法* */ClassPathXmlApplicationContext contextnew ClassPathXmlApplicationContext(spring-config.xml);BeanLife beanLifecontext.getBean(beanlife,BeanLife.class);beanLife.use();System.out.println(执行 main方法);context.destroy();}
}
运行结果 over!