Bean的作用域:
一般情况下,对于变量的可用范围叫做作用域,或者说是定义某个变量的区域叫做作用域。
而Bean的作用域指的是Bean在Spring容器中的行为模式。
Bean有六大行为模式
1、singleton:单例模式(默认)
singleton是Bean在Spring中默认的行为,这个默认的行为模式就是说一个类只有一个Bean对象,所有的用户都使用的同一个对象,如果有一个用户对这个对象进行了修改,那么所有的结果都会发生改变。
如:这样一个User类:
package com.demo.spring.beans;
public class User {
private int Id;
private String name;
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"Id=" + Id +
", name='" + name + '\'' +
'}';
}
}
我们先使用@Bean注解给Spring中注入一个User对象
package com.demo.spring.beans.Controller.Bean;
import com.demo.spring.beans.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
@Controller
public class UserBean {
@Bean(name = "user")
//使用getUser方法返回Bean对象
public User getUser(){
User user=new User();
user.setId(1);
user.setName("张三");
return user;
}
}
然后使用@Autowired从Spring中获取到该Bean对象并进行修改:
package com.demo.spring.beans.Controller;
import com.demo.spring.beans.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
private User user1;
@Autowired
public User getUser1(){
User user=user1;
user.setId(1);
user.setName("李四");
return user;
}
}
然后再使用@Autowired直接从Spring中获取Bean对象:
package com.demo.spring.beans.Controller;
import com.demo.spring.beans.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController2 {
@Autowired
private User user3;
public User getUser3() {
return user3;
}
}
然后我们在App启动类中分别获取一下UserController和UserController2的Bean对象:
import com.demo.spring.beans.Controller.UserController;
import com.demo.spring.beans.Controller.UserController2;
import com.demo.spring.beans.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context=new
ClassPathXmlApplicationContext("spring-config.xml");
UserController userController= context.getBean("userController", UserController.class);
User user=userController.getUser1();
System.out.println("修改后的bean:"+ user);
UserController2 userController2=context.getBean("userController2",UserController2.class);
User user1=userController2.getUser3();
System.out.println("最后获取的bean:"+user1);
}
}
结果如图:
也就是说,开始的时候我们的name是张三,经过第一次修改后,变成了李四,最后一个人在没有修改的前提下依然获得的是李四 。所以我们可以断定这个bean是同一个。也就是说Bean的作用域默认是Singleton(单例模式)单例可以节省内存开销,适合Bean对象不被随意更改的场景。
2、prototype: 原型模式(多例模式)
原型模式需要在注入Bean的时候就进行指定,需要在@Bean注解下或者五大类注解的下面指定注解:@Scope,并且在注解中指定一个值为prototype。这样其他地方获取Bean的时候,就不是同一个了,而是一个新的Bean实例。(通常有状态的Bean使用该作用域)
Bean的内容容易被修改的场景中适合使用该种作用域。
3、request: 请求作用域(Spring MVC)
每次http请求会创建新的Bean实例,类似于prototype
场景:⼀次http的请求和响应的共享Bean
备注:限定SpringMVC中使⽤
4、session: 会话作用域(Spring MVC)
在⼀个http session中,定义⼀个Bean实例
**
场景:
**⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息
**
备注:
**限定SpringMVC中使⽤
5、application: 全局作用域(Spring MVC)
在⼀个http servlet Context中,定义⼀个Bean实例(这个Bean也是单例的)
**
场景:
**Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息
**
备注:
**限定SpringMVC中使⽤
6、websocket: HTTP WebSocket 作用域(Spring WebSocket)
在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bea实例
**
场景:
**WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,直WebSocket结束都是同⼀个Bean。
**
备注:
**限定Spring WebSocket中使⽤
applicationContext和singleton的区别
1、作用域不一样:singleton是Spring Core的作用域,而application是Spring Web中的作用域。
2、作用的容器不一样:singleton是作用于Spring IOC的容器,而application是作用于Servlet的容器。
Bean的生命周期
1、实例化(给Bean分配内存空间)
2、设置属性(对象注入)
3、Bean的初始化
①执行各种通知(执行各种 Aware)
②执行初始化的前置方法(BeanPostProcessor)
③ 执行构造方法,两种执行方式,一种是执行 @PostConstruct,另一种实质性 init-method
④ 执行初始化的后置方法(BeanPostProcessor)
4、使用Bean
5、销毁Bean
执行销毁容器的各种方法,例如**@PreDestroy、DisposableBean方法、destroy-method方法**。
总结:
版权归原作者 渴望力量的土狗 所有, 如有侵权,请联系我们删除。