目录
  • 1. Bean 的作用域
    • 1.1 观看案例
    • 1.2 作用域的定义
    • 1.3 Bean 的 6 种作用域
    • 1.4 如何设置 Bean 的作用域
      • ① @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
      • ② @Scope(“prototype”)
      • 注意事项:
  • 2. Bean 的生命周期
    • 2.1 Bean 的执行流程
      • 2.2 Bean 生命周期
        • 2.3 生命周期演示代码
          • 主要代码
          • xml 的配置
          • 测试运行
          • 查看结果

      1. Bean 的作用域

      1.1 观看案例

      现在有一个公共 Bean

      @Component
      public class UserBean {
          @Bean
          public User user1() {
              User user = new User();
              user.setId(1);
              user.setName("张三");
              user.setAge(18);
              return user;
          }
      }
      

      现在有一个用户1, 进行了修改的操作

      @Controller
      public class UserControllerA {
          @Autowired
          private User user1;
          public User getUser1() {
              User user = user1;
              System.out.println("用户1修改之前: " + user1);
              user.setName("王五");
              return user;
          }
      }

      现在有用户2, 进行读取操作

      @Controller
      public class UserControllerB {
          @Autowired
          private User user1;
          public User getUser1() {
              User user = user1;
              return user;
          }
      }

      打印用户1和用户2公共Bean的值

          public static void main(String[] args) {
              ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
              UserControllerA userControllerA = context.getBean("userControllerA",UserControllerA.class);
              User user = userControllerA.getUser1();
              System.out.println("用户1修改之后: " + user);
              UserControllerB userControllerB = context.getBean("userControllerB",UserControllerB.class);
              User user1 = userControllerB.getUser1();
              System.out.println("用户2读取到的: " + user1);
          }
      

      运行结果

      Java深入讲解Bean作用域与生命周期

      原因:

      Spring 中 Bean 的作用域默认是 singleton 单例模式. 所有人使用的都是同一个对象.

      1.2 作用域的定义

      之前所说的作用域, 是在程序中定义的某个变量的某个区域就叫做作用域.这里的Bean作用域不同.

      Bean 的作用域指: Bean在 Spring 整个框架中的某种行为模式,

      比如 singleton 单例作用域, 就表示 Bean 在整个 Spring 中只有一份, 它是全局共享的, 那么当其他人修改了这个值之后, 那么另一个人读取到的就是被修改的值.

      1.3 Bean 的 6 种作用域

      Spring 容器在初始化一个 Bean 的示例时, 同时会指定该实例的作用域.

      Spring 有 6 种作用域.

      • singleton: 单例作用域
      • prototype: 原型作用域 (多例作用域)
      • request: 请求作用域
      • session: 回话作用域
      • application: 全局作用域
      • websocket: HTTP WebSocket 作用域

      3~6 这四种是 Spring MVC 中的值.

      1.4 如何设置 Bean 的作用域

      @Scope 既可以用于方法注解, 也可以用于类注解

      ① @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

      Java深入讲解Bean作用域与生命周期

      Java深入讲解Bean作用域与生命周期

      ② @Scope(“prototype”)

      Java深入讲解Bean作用域与生命周期

      Java深入讲解Bean作用域与生命周期

      注意事项:

      如果是 @Bean + @Scope , 这里的@Scope 就不能写成类注解的方式了.

      Java深入讲解Bean作用域与生命周期

      2. Bean 的生命周期

      2.1 Bean 的执行流程

      • 启动 Spring 容器
      • 加载 Spring 配置文件
      • 加载 Spring 配置文件中的 Bean, 或根据配置文件中的组件根路径, 进行 Bean 对象的扫描(扫描@Controller…)
      • Bean 注册到 Spring 中
      • 执行完毕,执行销毁操作

      Java深入讲解Bean作用域与生命周期

      2.2 Bean 生命周期

      Bean 的生命周期分为 5 大部分:

      实例化 Bean (为Bean分配内存空间)

      设置属性 (Bean 进行初始化注入)

      Bean 初始化 (一系列准备工作)

      ① 各种通知 (xxxAware)

      ② 执行初始化前置方法 BeanPostProcessor

      ③ 执行 @PostConstruct 初始化方法

      ④ 执行 init-mehtod 初始化方法

      ⑤ 执行初始化后置方法 BeanPostProcessor

      使用 Bean

      销毁 Bean

      • ① 执行销毁前方法 @PreDestory
      • ② 如果有接口 DisposableBean, 执行实现方法
      • ③ 执行销毁前的方法 destory-method

      Java深入讲解Bean作用域与生命周期

      2.3 生命周期演示代码

      主要代码

      package com.wwzz.util;
      import org.springframework.beans.factory.BeanNameAware;
      import org.springframework.stereotype.Component;
      import javax.annotation.PostConstruct;
      import javax.annotation.PreDestroy;
      @Component
      public class BeanLifeComponent implements BeanNameAware {
          @Override
          public void setBeanName(String s) {
              System.out.println("执行通知: BeanNameAware " + s);
          }
          @PostConstruct
          public void postConstruct(){
              System.out.println("执行 @PostConstruct");
          }
          public void init() {
              System.out.println("执行 init-method");
          }
          @PreDestroy
          public void preDestroy(){
              System.out.println("执行 @PreDestroy");
          }
          public void destroy() {
              System.out.println("执行 destroy");
          }
      }

      xml 的配置

      <?xml version="1.0" encoding="UTF-8"?><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"> <!-- 配置 Spring 扫描的根路径(此根路径下的所有 Spring 存对象的注解才能生效) --> <content:component-scan base-package="com.wwzz"></content:component-scan> <beans> <bean id="beanLifeComponent" class="com.wwzz.util.BeanLifeComponent" init-method="init" destroy-method="destroy"></bean> </beans></beans><?xml version="1.0" encoding="UTF-8"?>
      <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">
          <!-- 配置 Spring 扫描的根路径(此根路径下的所有 Spring 存对象的注解才能生效) -->
          <content:component-scan base-package="com.wwzz"></content:component-scan>
          <beans>
              <bean id="beanLifeComponent" class="com.wwzz.util.BeanLifeComponent" init-method="init" destroy-method="destroy"></bean>
          </beans>
      </beans>
      

      测试运行

          public static void main(String[] args) {
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
              BeanLifeComponent beanLifeComponent = context.getBean("beanLifeComponent",BeanLifeComponent.class);
              context.destroy();
          }
      

      查看结果

      Java深入讲解Bean作用域与生命周期

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。