Bean 的作用域和生命周期

简介: Bean 的作用域和生命周期

什么是 Bean 的作用域 ?


Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个⼈读取到的就是被修改的值。


它的概念与我们之前学的作用域不一样,之前是指变量的可⽤范围叫做作⽤域。


Bean 的六种作用域


1.singleton:单例作用域(默认的作用域,线程不安全)

说明:该作⽤域下的 Bean 在 IoC 容器中只存在⼀个实例:获取 Bean 及装配 Bean 都是同⼀个对

场景:通常⽆状态的 Bean 使⽤该作⽤域。⽆状态表示 Bean 对象的属性状态不需要更新

(无状态的 bean:只有普通的对数据的操作方法,没有存储功能)


2.prototype:原型(多例)作用域 (线程安全)

说明:每次对该作⽤域下的 Bean 的请求都会创建新的实例:获取 Bean 及装配 Bean 都是新的对象

实例

场景:通常有状态的Bean使⽤该作⽤域


3.request:请求作用域

说明:每次http请求会创建新的Bean实例,类似于prototype

场景:⼀次http的请求和响应的共享Bean

备注:限定SpringMVC中使⽤


4.session:会话作用域

说明:在⼀个http session中,定义⼀个Bean实例

场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息

备注:限定SpringMVC中使⽤


5.application:应用作用域(了解)

说明:在⼀个http servlet Context中,定义⼀个Bean实例

场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息

备注:限定SpringMVC中使⽤


6.websocket(了解)

说明:在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例

场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀

次初始化后,直到WebSocket结束都是同⼀个Bean

备注:限定Spring WebSocket中使⽤

注意:普通的 Spring 项⽬中只有前两种,后 4 种状态是 Spring MVC 中的。


两种设置多例作用域方法:

@Scope(“prototype”)

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)


检验默认作用域是否为单例作用域:


User 类:


public class User {
    private String name;
    private int id;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
}


Users 类(存储公共对象):


@Service
public class Users {
    @Bean
    public User getUser(){
        User user = new User();
        user.setId(888);
        user.setName("张三");
        return user;
    }
}


取对象的两大类:


@Controller
public class UserController1 {
    @Autowired
    private User user;
    public void doMethod() {
        System.out.println("修改前的名字: " + user.getName());
        user.setName("王五");
        System.out.println("修改后的名字: " + user.getName());
    }
}


@Controller
public class UserController2 {
    @Autowired
    private User user;
    public void doMethod() {
        System.out.println("UserController2 拿到的名字: " + user.getName());
    }
}


启动类:


public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController1 userController1 =
                context.getBean("userController1",UserController1.class);
        userController1.doMethod();
        UserController2 userController2 =
                context.getBean("userController2",UserController2.class);
        userController2.doMethod();
    }
}


输出:

e3562168f3b04a79aa8e272cd4ac6078.png


可以看到张三这个名字被改后,后续再取这个 Bean 就拿不到张三了。


设置多例作用域:


@Service
public class Users {
    @Scope("prototype")
    @Bean
    public User getUser(){
        User user = new User();
        user.setId(888);
        user.setName("张三");
        return user;
    }
}

fe3edd70c279454f8ac4601a77e0da30.png


这里拿到的每个 Bean 对象都是 new 了一个新的,不是直接拿容器中原有的对象。


Spring 的执行流程


  1. 启动容器
  2. 读取配置进行 Bean 的实例化(分配内存空间,从无到有)
  3. 将 Bean 加入到容器中(存操作)
  4. 装配 Bean 属性(取操作)


Bean 的生命周期


⽣命周期指的是⼀个对象从诞⽣到销毁的整个⽣命过程,Bean 的生命周期分为下面五个部分:


  1. 实例化(内存空间分配)
  2. 设置 Bean 属性(进行依赖注入,将依赖的 Bean 赋值到当前类属性上)
  3. Bean 的初始化

3.1 执行各种通知

3.2 初始化的前置方法

3.3 初始化方法

3.4 初始化的后置方法

  1. 使用 Bean
  2. 销毁 Bean


实例化和初始化的区别:

实例化和属性设置是 Java 级别的系统“事件”,其操作过程不可⼈⼯⼲预和修改;⽽初始化是给开发者提供的,可以在实例化之后,类加载完成之前进⾏⾃定义“事件”处理


相关文章
|
6天前
|
前端开发 Java 开发者
Bean的生命周期和作用域
Bean的生命周期和作用域
|
6天前
|
Java 开发者 Spring
Bean 的生命周期了解么
Bean 的生命周期了解么
|
9月前
|
前端开发 Java C++
Bean的作用域
Bean 常见的 6 种作用域
|
10月前
|
Java 容器 Spring
Bean生命周期
Bean生命周期
|
5月前
|
Java Spring 容器
bean的生命周期
bean的生命周期
31 0
|
7月前
|
Java 容器 Spring
bean的作用域和生命周期和后置处理器以及作用域对生命周期的影响~
bean的作用域和生命周期和后置处理器以及作用域对生命周期的影响~
|
9月前
|
XML 安全 Java
Bean作用域和生命周期
Bean作用域和生命周期
|
10月前
|
Java Spring 容器
Bean的作用域和生命周期(上)
Bean的作用域和生命周期(上)
|
10月前
|
XML 存储 Java
Bean的作用域和生命周期(下)
Bean的作用域和生命周期(下)
|
9月前
Bean的生命周期
Bean的生命周期
36 0