Spring---Bean的作用域和生命周期

文章目录

  • Bean的作用域
    • Bean的六种作用域
    • 设置Bean的作用域
  • Bean的生命周期
    • Bean(Spring)的执行流程
    • Bean的生命周期

Bean的作用域

我们通过一个例子来认识 Bean 的作用域:
假设现在有一个公共的 Bean 对象提供给用户A和用户B使用,然后在使用的途中用户A却“悄悄”的修改了公共Bean的数据,导致用户B在使用时发送了意料之外的逻辑错误。

	//定义Bean对象
	@Data
	public class User {
  	   private int id;
   	   private String name;
   	   private String password;
	}

    //设置初始值
    @Bean
    public User user(){
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setPassword("123456");

        return user;
    }
//用户A使用并修改
@Controller
public class Use1 {
    @Autowired
    private User user;

    public User getUser() {
        System.out.println("原来的name:" + user.getName());
        //修改name
        user.setName("李四");
        System.out.println("现在的name:" + user.getName());

        return user;
    }
}

//用户B使用
@Controller
public class Use2 {
    @Autowired
    private User user;

    public User getUser() {
        System.out.println("Use2得到的name:" + user.getName());
        return user;
    }
}
//验证结果
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        Use1 use1 = context.getBean("use1",Use1.class);
        use1.getUser();
        //原来的name:张三  现在的name:李四

        Use2 use2 = context.getBean("use2",Use2.class);
        use2.getUser();
        //user2得到的name:李四
    }
}

原因分析:Bean 默认情况下是单例的,即Bean默认是单例作用域
Bean的作用域是指:Bean在Spring整个框架中的行为模式

Bean的六种作用域

  1. singleton:单例作用域,Bean在Ioc容器中只存在一个实例,每次获取Bean都获取到同一个对象
  2. prototype:原型作用域(多例作用域),每次注册Bean都会创建新的实例,获取到的Bean不是同一个对象
  3. request:请求作用域,每次HTTP请求会创建新的实例
  4. session:会话作用域,在一个httpSession中定义一个实例
  5. application:全局作用域,在一个http servlet context中定义一个实例,用来记录一个应用的共享信息
  6. websocket:websocket作用域,在一个WebSocket的生命周期中定义一个实例

注:

  1. 在普通的Spring项目中只有前两种作用域
  2. 后四种作用域存在于 SpringMVC中

设置Bean的作用域

    //@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Scope("prototype")
    @Bean
    public User user(){
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setPassword("123456");

        return user;
    }

注:

  1. @Scope注解既可以修饰方法又可以修饰类

  2. @Scope有两种设置方法:

    • 直接设置值:@Scope(“prototype”)
    • 使用枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Bean的生命周期

Bean(Spring)的执行流程

  1. 启动Spring容器:加载配置文件中的Bean注册路径
  2. 实例化Bean(分配内存空间,从无到有):读取注册路径下的注解
  3. 将Bean注册到Spring中:存操作
  4. 把Bean注入到需要它的类中:取操作

Bean的生命周期

  1. 实例化Bean:为Bean分配内存空间
  2. 设置属性:Bean注入和装配
  3. Bean初始化:
    • 实现了各种Aware通知的方法
    • 执行了 BeanPostProcessor 初始化前置方法
    • 执行了 PostConstruct 初始化方法
    • 执行自己指定的 init-method 方法
    • 执行 BeanPostProcessor 初始化后置方法
  4. 使用Bean
  5. 销毁Bean

实例化 VS 初始化
实例化:是Java级别的系统“事件”,其操作过程不可人工干预和修改
初始化:是给开发者提供的,可以在实例化之后、类加载完成之前进行自定义“事件”处理

为什么要先设置属性再进行初始化呢?
因为初始化中可能会用到设置好的相关属性

你可能感兴趣的:(JavaEE进阶,spring,java,后端)