目录
一、Bean的作用域
🍅 先看示例(可以不看,只是帮助理解什么是作用域,作用域的具体内容往下):
创建里一个实体类User,
package com.java.demo.model;
public class User {
private int id;
private String name;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
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;
}
}
然就将对象存储到带有@Bean注解的方法中
/*
* 公共类
* */
@Component
public class Users {
/*
* 公共对象
* */
@Bean("user")
public User getUser(){
User user = new User();
user.setId(1);
user.setName("zhangsan");
return user;
}
}
创建两个Controller类,取出对象,注入对象到user中
@Controller
public class UserController2 {
@Autowired
private User user;
public void doMethod(){
User user2 = user;
System.out.println("UserController 修改之前:+"+user);
user2.setName("sandy");
System.out.println("User 修改之后:"+ user);
}
}
@Controller
public class UserController3 {
@Autowired
private User user;
public void doMethod(){
System.out.println("UserController3:"+user);
}
}
以上代码,目的是为了,首先UserController2中,先打印user修改之前的名字(“zhangsan”),然后在该类中设置新的名字("sandy");
然后再UserController中,拿到user本来的名字(“zhangsan”),然后运行代码main函数
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
UserController2 userController2 = context.getBean("userController2", UserController2.class);
userController2.doMethod();
UserController3 userController3 = context.getBean("userController3", UserController3.class);
userController3.doMethod();
}
发现userController3拿到的名字是修改以后的名字:
以上过程就和Bean的作用域有关,原因主要就是Bean对象默认是单例模式。
如果想要让userController3拿到的名字是修改前的名字,我们可以使用@Scope
@Component
public class Users {
/*
* 公共对象
* */
@Bean("user")
@Scope("prototype") //原型模式
public User getUser(){
User user = new User();
user.setId(1);
user.setName("zhangsan");
return user;
}
}
🎈 Bean的作用域
通过上面的例子,我们就能很好的理解Bean的作用域是什么了:
Bean的作用域指的是Bean在Spring容器中的某种行为(单例、原型等)。
🎈 Bean的6中作用域
Spring MVC中
1.singleton: 单例模式(默认作用域)(Spring core)
2.prototype: 原型模式 (Spring core)
3.request: 请求作用域,只适用于Spring MVC
4.session: 会话作用域,一个HTTP会话共享一个Bean,只适用于Spring MVC项目(Spring Web)
5.application: 全局作用域,表示的是一个Context容器共享一个作用域,只适用于Spring MVC项目(Spring Web)
6.websocket: HTTP WebSocket作用域,只适用于WebSocket作用域
🎈 设置Bean的作用域
1. 使用@Scope
@Component
public class Users {
/*
* 公共对象
* */
@Bean("user")
@Scope("prototype") //原型模式
public User getUser(){
User user = new User();
user.setId(1);
user.setName("zhangsan");
return user;
}
}
2.@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
public class Users {
/*
* 公共对象
* */
@Bean("user")
//@Scope("prototype") //原型模式
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public User getUser(){
User user = new User();
user.setId(1);
user.setName("zhangsan");
return user;
}
}
二、Spring的执行流程和Bean的生命周期
🎈 Spring的执行流程(生命周期)
启动Spring容器 -> 实例化Bean(分配内存空间,从无到有) -> Bean注册到Spring容器中(存操作) -> 将Bean装配到需要的类中(取操作)
🎈 Bean的生命周期
1.实例化Bean(为Bean分配内存空间)
2.设置Bean属性(进行依赖注入,将依赖的Bean赋值到当前类的属性上)
3.Bean的初始化
(1)执行各种通知
(2)初始化的前置方法
(3)初始化方法
(4)初始化的后置方法
4.使用Bean
5.销毁Bean
以下是Bean的初始化方法和销毁方法:
public class BeanLifeComponent implements BeanNameAware {
@Override
public void setBeanName(String s) {
System.out.println("执行了BeanNameAware -> "+s);
}
@PostConstruct //使用注解初始化方法
public void doPostConstruct(){
System.out.println("执行了@PostConstruct");
}
//使用xml初始化方法
public void myInit(){
System.out.println("执行了myinit");
}
//使用注解销毁Bean
@PreDestroy
public void doPreDestroy(){
System.out.println("执行了PreDestroy方法");
}
public void sayHi(){
System.out.println("使用bean");
}
}
执行测试类:
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("Spring-config.xml");
BeanLifeComponent beanLifeComponent = context.getBean("mybean",BeanLifeComponent.class);
beanLifeComponent.sayHi();
context.close();
}
以下是执行结果: