源代码中限定程序中变量的可用范围,叫作作用域
Bean的作用域是指Bean在Spring整个框架中的某种行为模式,比如singleton单例作用域,就表示Bean在整个Spring中只有一份,它是全局共享的,一个人修改了Bean的属性,另一个人读取到的就是修改了的Bean
model包中创建一个普通类
package com.model;
public class Student {
private String name;
private String Address;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", Address='" + Address + '\'' +
'}';
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
Address = address;
}
}
Component包中创建一个“实体类”
package com.bit.component;
@Component
public class StudentComponent {
@Bean
public Student getStudent(){
Student student = new Student();
student.setName("刘文");
student.setAddress("郑州路");
return student;
}
}
在Controller包中,创建两个不同的“ *** 作者”
StudentControllerA
修改Bean的属性,“郑州路” —> “松岭路”
package com.bit.controller;
@Controller
public class StudentControllerA {
@Autowired
private Student student;
public Student update(){
System.out.println("student对象修改前: " + student);
System.out.println("修改student");
student.setAddress("松岭路");
return student;
}
}
StudentControllerB
获取Bean对象
package com.bit.controller;
@Controller
public class StudentControllerB {
@Autowired
private Student student;
public Student getStudent(){
return student;
}
}
启动类 App
// 启动类
public class App {
public static void main(String[] args) {
// 获取 Spring 上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
StudentControllerA studentControllerA = context.getBean("studentControllerA", StudentControllerA.class);
System.out.println(studentControllerA.update());
StudentControllerB studentControllerB = context.getBean("studentControllerB", StudentControllerB.class);
System.out.println(studentControllerB.getStudent());
// 打印
// 刘文 松岭路
// 刘文 松岭路
}
}
3、Bean的六种作用域此处的Bean(Student)就是单例作用域(Singleton作用域),StudentControllerA和StudentController获取、修改的都是同一个对象
- singleton:单例作用域,Spring所有生态都支持
Bean在默认情况下是单例作用域
Bean在IoC容器中只有一个实例,每次获取(getBean())、装配(@Autowired)的Bean都是同一个对象(就可着一个人造)
- prototype:多例作用域(原型作用域),Spring所有生态支持
每次获取(getBean())、装配(@Autowired)Bean时,都要创建新的实例,所以每一次得到的都是新的对象(你玩你的,我玩我的,互不影响)
即使是在同一个类中,得到的也是不同的对象
- request:请求作用域,仅Spring MVC(Spring Web)支持
每次HTTP请求都会创建新的Bean的实例
- session:会话作用域,仅Spring MVC支持
在一个 http session 中,定义一个Bean实例
- application:全局作用域,仅Spring MVC支持
在一个 http application context中,定义一个Bean实例
- websocket:HTTP WebSocket作用域,仅Spring MVC支持
将 Student 类在存储到 Spring容器时,设置为全局作用域,解决上述问题
package com.bit.component;
@Component
public class StudentComponent {
// @Scope("prototype")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public Student getStudent(){
Student student = new Student();
student.setName("刘文");
student.setAddress("郑州路");
return student;
}
}
启动类
// 启动类
public class App {
public static void main(String[] args) {
// 获取 Spring 上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
StudentControllerA studentControllerA = context.getBean("studentControllerA", StudentControllerA.class);
System.out.println(studentControllerA.update());
StudentControllerB studentControllerB = context.getBean("studentControllerB", StudentControllerB.class);
System.out.println(studentControllerB.getStudent());
// 打印
// 刘文 松岭路
// 刘文 郑州路
}
}
二、Spring的执行流程
- 启动Spring容器(main启动时)
- 加载Spring的配置文件(xml),实例化并分配内存空间
- 扫描指定包路径,将添加注解(类注解、方法注解)的类注册到Spring容器中
- 装配Bean的属性(Bean中有些属性需要注入对象(@Autowired、@Resource))
Bean从创建到销毁的过程就叫做Bean的生命周期
- 实例化Bean,申请内存
- 设置Bean的属性(对象注入(@Autowired、@Resource))
- 初始化Bean
- 调用各种Aware通知的方法,如BeanNameAware、BeanFactoryAware、ApplicationContextAware(均为接口)的方法
- 执行BeanPostProcessor初始化前置方法
- 执行@PostConstructor修饰的初始化方法
- 执行InitialzingBean接口的afterPropertiesSet方法
- 执行自己指定的init-method方法(在配置文件中(xml)中指定,没有指定就不调用)
- 执行BeanPostProcessor初始化后置方法
- 使用Bean
- 销毁Bean
- 调用@PreDestroy销毁前方法
- 调用DisposableBean接口的destroy方法
- 调用destroy-method方法
设置配置文件
指定init-method方法 和 destroy-method方法
<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.bit">content:component-scan>
<beans>
<bean id="beanLife" class="com.bit.component.BeanLife" init-method="init" destroy-method="Mydestroy">bean>
beans>
beans>
Component包中创建一个“实体类”
package com.bit.component;
@Component
public class BeanLife implements BeanNameAware, InitializingBean, DisposableBean {
/*
* 初始化方法2
* 方法名无所谓,只要是配置到 配置文件 中即可
* */
public void init(){
System.out.println("执行了 init_method 方法");
}
/*
* 初始化方法1
* 只认这个注解,方法名无所谓的
* */
@PostConstruct
public void postConstruct(){
System.out.println("执行了 @PostConstrucet 注解修饰的方法");
}
// 构造方法
public BeanLife(){
System.out.println("执行构造方法");
}
/**
* Aware通知的方法,此处实现了BeanNameAware接口,重写了setBeanName方法
*
*/
// 实现 BeanNameAware接口,重写setBeanName() 方法
@Override
public void setBeanName(String s) {
System.out.println("执行 BeanNameAware setBeanName() 方法");
}
/*
* 销毁前的方法1
* 只认这个注解,方法名无所谓的
*/
@PreDestroy
public void preDestroy(){
System.out.println("执行了 @PreDestory 注释修饰的方法");
}
/**
* 销毁前的方法2
*/
public void Mydestroy(){
System.out.println("执行了 destroy_method 方法");
}
/**
* InitialzingBean接口的afterPropertieSet方法
*
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("执行了InitializingBean接口的 afterPropertiesSet方法");
}
/**
* DisposableBean接口的destroy方法
*
*/
@Override
public void destroy() throws Exception {
System.out.println("执行了 DisposableBean 接口的destory方法");
}
}
启动类
import com.bit.*;
// 启动类
public class App {
public static void main(String[] args) {
ClassPathXmlApplicationContext context1 = new ClassPathXmlApplicationContext("spring-config.xml");
BeanLife beanLife = context1.getBean("beanLife", BeanLife.class);
System.out.println(beanLife);
context1.destroy();
}
}
打印结果
整个项目的目录结构
aware - 意识到
processor - 处理器
construct - 建设
initialzing - 初始化
properties - 性能
disposable - 一次性
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)