Spring系列(三)之Bean的生命周期以及Bean的单例与多例模式

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Spring系列(三)之Bean的生命周期以及Bean的单例与多例模式

一. Bean的生命周期

bean的生命周期可以表达为:bean的定义➡bean的初始化➡bean的使用➡bean的销毁

Bean的初始化过程

1)通过XML、Java annotation(注解)以及Java Configuration(配置类)

等方式加载Bean

2)BeanDefinitionReader:解析Bean的定义。在Spring容器启动过程中,

会将Bean解析成Spring内部的BeanDefinition结构;

理解为:将spring.xml中的标签转换成BeanDefinition结构

有点类似于XML解析

3)BeanDefinition:包含了很多属性和方法。例如:id、class(类名)、

scope、ref(依赖的bean)等等。其实就是将bean(例如)的定义信息

存储到这个对应BeanDefinition相应的属性中;将所有的bean标签解析得到一个BeanDefinition定义对象,最终得到一个集合

4)BeanFactoryPostProcessor:是Spring容器功能的扩展接口。也就是在实例化之前给bean做一个拓展

注意:

1)BeanFactoryPostProcessor在spring容器加载完BeanDefinition之后,

在bean实例化之前执行的

2)对bean元数据(BeanDefinition)进行加工处理,也就是BeanDefinition

属性填充、修改等操作

5)BeanFactory:bean工厂。它按照我们的要求生产我们需要的各种各样的bean。BeanFactory会去解析处理整个集合,将所配置的所有JavaBean进行反射实例化

6)Aware感知接口:在实际开发中,经常需要用到Spring容器本身的功能资源

例如:BeanNameAware、ApplicationContextAware等等

BeanDefinition 实现了 BeanNameAware、ApplicationContextAware

7)BeanPostProcessor:后置处理器。在Bean对象实例化和引入注入完毕后,

在显示调用初始化方法的前后添加自定义的逻辑。(类似于AOP的环绕通知)

二. Bean的单例与多例模式

在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例)

singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例。单例的优点在于可以节约内存,弊端在于会有变量污染。

prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new。多例的优劣则与单例相反,不会有变量污染,但却非常消耗内存。

Spring bean默认是单例模式。

单例模式

代码示例:

package com.xissl.beanLife;
import java.util.List;
public class ParamAction {
  private int age;
  private String name;
  private List<String> hobby;
  private int num = 1;
  public ParamAction() {
    super();
  }
  public ParamAction(int age, String name, List<String> hobby) {
    super();
    this.age = age;
    this.name = name;
    this.hobby = hobby;
  }
  public void execute() {
    System.out.println("this.num=" + this.num++);
    System.out.println(this.name);
    System.out.println(this.age);
    System.out.println(this.hobby);
  }
}

测试

package com.xissl.beanLife;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/*
 * spring bean的生命週期
 * spring bean的單例多例
 */
public class Demo2 {
  // 体现单例与多例的区别
  @Test
  public void test1() {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
//    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
    ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
    ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
    // System.out.println(p1==p2);
    p1.execute();
    p2.execute();
//    单例时,容器销毁instanceFactory对象也销毁;多例时,容器销毁对象不一定销毁;
    applicationContext.close();
  }
}

spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    bean的生命周期-->
    <bean id="paramAction" class="com.xissl.beanLife.ParamAction">
        <constructor-arg name="name" value="三丰"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>抽烟</value>
                <value>烫头</value>
                <value>大保健</value>
            </list>
        </constructor-arg>
    </bean>
</beans>

运行结果:

这里的num值分别为1和2,则说明是单例的,单例模式即存在变量污染

在单例模式中,JavaBean是跟着spring上下文初始化的:

package com.xissl.beanLife;
public class InstanceFactory {
  public void init() {
    System.out.println("初始化方法");
  }
  public void destroy() {
    System.out.println("销毁方法");
  }
  public void service() {
    System.out.println("业务方法");
  }
}

测试

package com.xissl.beanLife;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/*
 * spring bean的生命週期
 * spring bean的單例多例
 */
public class Demo2 {
  // 体现单例与多例的初始化的时间点 instanceFactory
  @Test
  public void test2() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
  }
}

spring配置上下文:

<bean id="instanceFactory" class="com.xissl.beanLife.InstanceFactory"
          scope="singleton" init-method="init" destroy-method="destroy"></bean>

运行结果:

调用了初始化方法

多例模式

将spring配置文件中指定scope为prototype

<bean id="paramAction" class="com.xissl.beanLife.ParamAction" scope="prototype">
        <constructor-arg name="name" value="三丰"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>抽烟</value>
                <value>烫头</value>
                <value>大保健</value>
            </list>
        </constructor-arg>
    </bean>
    <bean id="instanceFactory" class="com.xissl.beanLife.InstanceFactory"
          scope="prototype" init-method="init" destroy-method="destroy"></bean>

运行结果:

在多例模式中,JavaBean是使用的时候才会创建,销毁跟着jvm走:

运行结果:

没有调用初始化方法

相关文章
|
19天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
19天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
116 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
6天前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
9天前
|
设计模式 Java Spring
spring源码设计模式分析(五)-策略模式
spring源码设计模式分析(五)-策略模式
|
9天前
|
消息中间件 设计模式 缓存
spring源码设计模式分析(四)-观察者模式
spring源码设计模式分析(四)-观察者模式
|
9天前
|
设计模式 Java Spring
spring源码设计模式分析(六)-模板方法模式
spring源码设计模式分析(六)-模板方法模式
|
9天前
|
设计模式 Java Spring
spring源码设计模式分析(七)-委派模式
spring源码设计模式分析(七)-委派模式
|
9天前
|
设计模式 Java 数据库
spring源码设计模式分析(八)-访问者模式
spring源码设计模式分析(八)-访问者模式
|
9天前
|
设计模式 搜索推荐 Java
spring源码设计模式分析(三)
spring源码设计模式分析(三)
|
9天前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
下一篇
无影云桌面