Bean的作用域和声明周期

Bean的作用域和声明周期

  • Bean的作用域
    • Bean作用域的定义
    • Bean作用域的分类
      • 【singleton 单例作用域】
      • 【prototype 多例作用域】
      • 【request请求作用域】
      • 【session会话作用域】
      • 【application全局作用域(了解)】
      • 【websocket HTTP WebSocket 作⽤域(了解)】
    • 如何设置Bean对象中的作用域
  • Spring的主要执行流程
  • Bean对象的生命周期
    • 生命周期代码演示

Bean的作用域

Bean作用域的定义

Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就

表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个⼈读取到的就是被修改的值

Bean作用域的分类

  1. singleton:单例作⽤域

  2. prototype:原型作⽤域(多例作⽤域)

  3. request:请求作⽤域

  4. session:回话作⽤域

  5. application:全局作⽤域

  6. websocket:HTTP WebSocket 作⽤域

【singleton 单例作用域】

描述:该作⽤域下的Bean在***IoC容器***中只存在⼀个实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对象。

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

备注:Spring默认选择该作⽤域

【prototype 多例作用域】

描述:每次对该作⽤域下的Bean的请求都会创建新的实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是新的对象实例

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

【request请求作用域】

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

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

备注:限定SpringMVC中使⽤

【session会话作用域】

描述:在⼀个http session中,定义⼀个Bean实例

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

备注:限定SpringMVC中使⽤

【application全局作用域(了解)】

描述:在⼀个http servlet Context中,定义⼀个Bean实例

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

备注:限定SpringMVC中使⽤

【websocket HTTP WebSocket 作⽤域(了解)】

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

场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,直到WebSocket结束都是同⼀个Bean
备注:限定Spring WebSocket中使用

如何设置Bean对象中的作用域

使⽤ @Scope 标签就可以⽤来声明 Bean 的作⽤域, @Scope 标签既可以修饰⽅法也可以修饰类,@Scope设置方法:

1.直接设置作用域的具体值,如:@Scope(“prototype”);

2.设置 ConfigurableBeanFactory 和 WebApplicationContext 提供的 SCOPE_XXX 变量,如 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)。

注意:无论我们是使用类注解还是方法注解来将对象保存到Spring容器中,要改变该bean对象的作用域,只有在添加一个@Scope进行设置就行

使用方法注解:

@Component
public class UserBeans {
    @Scope("prototype")
    @Bean("userService_1")
    public UserService getUserService() {
        return new UserService();
    }
}

使用类注解:

@Controller
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserController {
    public void doUserController() {
        System.out.println("do UserController.");
    }
}

Spring的主要执行流程

  1. 启动容器

  2. Bean的初始化

  3. 将bean对象注册到Spring容器中(给bean对象开辟内存空间)

    配置文件中的bean、配置了加载文件路径的类的扫描(看看有没使用类注解或者方法注解)

  4. 装配bean对象的属性(对象注入)

  5. 使用bean对象

  6. Spring销毁

Bean对象的生命周期

所谓的生命周期就是,一个对象从创建到销毁的过程

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

  1. 实例化bean对象(不是初始化bean对象,就是给bean对象分配内存空间)

  2. 设置bean属性(对象注入)

  3. 初始化bean

    1. 执行各种通知,如 BeanNameAware、BeanFactoryAware、

      ApplicationContextAware 的接⼝⽅法;

    2. 初始化的前置方法(xml配置文件bean标签有init-method属性来设置前置方法,@PostConstruct注解也能解决这问题,只有在方法前加上这个注解就行)

    3. 初始化方法

    4. 初始化的后置方法

  4. 使用bean对象

  5. 销毁bean对象(xml配置文件bean标签里有destroy-method属性来指定bean对象在销毁时使用哪个方法,@PreDestroy注解也能解决这个问题,在哪个方法前加上这个就行了)

生命周期代码演示

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserController implements BeanNameAware {
    @Autowired
    public UserService userService;
    public UserController() {
        System.out.println("无参构造方法:UserController()");
    }

    public void init() {
        System.out.println("通过xml配置文件来设置前置方法:UserController.init()");
    }
    @PostConstruct
    public void before() {
        System.out.println("通过注解来设置化前置⽅法:UserController.before()");
    }
    public void doUserController() {
        System.out.println("bean对象的使用");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("Aware 通知:"+s);
    }
    @PreDestroy
    public void destroy() {
        System.out.println("bean对象的销毁:UserController.destroy()");
    }
}
@Service
public class UserService implements BeanNameAware {
    public UserService() {
        System.out.println("无参构造方法:UserService()");
    }

    @PostConstruct
    public void before() {
        System.out.println("通过注解来设置化前置⽅法:UserService.before()");
    }
    @PreDestroy
    public void destroy() {
        System.out.println("bean对象的销毁:UserService.destroy()");
    }
    public void doUserService() {
        System.out.println("do UserService.");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("Aware 通知:"+s);
    }
}

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">
    <!-- 配置扫描注解的路径   -->
    <content:component-scan base-package="com"></content:component-scan>
    <bean id="userController" class="com.wwj.controller.UserController" init-method="init"></bean>
</beans>

你可能感兴趣的:(笔记,java,spring)