浅谈Spring中Bean的作用域、生命周期

以下是关于Spring中Bean的作用域和生命周期的详细讲解,包括定义、配置、作用域和生命周期四个方面。

定义

在Spring中,Bean就是被Spring容器所管理的Java对象。我们可以将Java对象配置为一个Bean,并通过Spring容器去创建、管理、装配、销毁这个Bean。

配置

Bean的配置分为两种方式:XML和注解。

XML配置

在XML文件中定义元素来配置Bean。以下是一个基本的XML配置:

<bean id="myBean" class="com.example.MyBean"/>

其中,id为Bean的唯一标识符,class指定了Bean的实现类。

注解配置

在Java代码中使用注解的方式来定义Bean。以下是一个基本的注解配置:

@Component
public class MyBean {
    // Bean的实现代码
}

其中,@Component是Spring提供的常用注解,用于将一个类声明为Bean。还有其他注解如@Service@Repository@Controller等。

作用域

Bean的作用域指定了Bean实例的创建和销毁方式。Spring提供了五种作用域:singleton、prototype、request、session、global session。

Singleton

Singleton是默认的作用域,它表示一个Bean在Spring容器中仅被创建一次,并且所有请求都返回同一个实例。在XML配置中,可以使用scope属性来指定该Bean的作用域,如下:

<bean id="myBean" class="com.example.MyBean" scope="singleton"/>

Prototype

Prototype表示每个请求都创建一个新的Bean实例。在XML配置中,使用scope属性设置为prototype即可:

<bean id="myBean" class="com.example.MyBean" scope="prototype"/>

Request

Request作用域表示一个Bean实例仅在每个HTTP请求中存在。在Web应用中,可以使用scope属性设置为request

<bean id="myBean" class="com.example.MyBean" scope="request"/>

Session

Session作用域表示一个Bean实例仅在每个HTTP会话中存在。在Web应用中,可以使用scope属性设置为session

<bean id="myBean" class="com.example.MyBean" scope="session"/>

Global Session

Global Session作用域类似于Session作用域,但它是在Portlet环境下使用。在Web应用中,可以使用scope属性设置为globalSession

<bean id="myBean" class="com.example.MyBean" scope="globalSession"/>

生命周期

Bean的生命周期可以理解为Bean从被创建到被销毁的整个过程。Spring为Bean提供了生命周期方法,开发者可以在Bean的生命周期方法中完成一些自定义的初始化或销毁操作。

初始化方法

在Bean实例被创建后,容器会调用Bean的初始化方法。Spring提供了两种方式来定义初始化方法:

  1. 使用@PostConstruct注解

    ```java
    @Component
    public class MyBean {

    @PostConstruct
    public void init() {
        // 初始化代码
    }
    

    }
    ```

  2. 在XML配置中指定init-method

    xml
    <bean id="myBean" class="com.example.MyBean" init-method="init"/>

销毁方法

在Bean实例被销毁前,容器会调用Bean的销毁方法。Spring提供了两种方式来定义销毁方法:

  1. 使用@PreDestroy注解

    ```java
    @Component
    public class MyBean {

    @PreDestroy
    public void destroy() {
        // 销毁代码
    }
    

    }
    ```

  2. 在XML配置中指定destroy-method

    xml
    <bean id="myBean" class="com.example.MyBean" destroy-method="destroy"/>

示例

接下来,我们将通过两个示例来演示作用域和生命周期的使用。

例1:@Scope示例

我们创建一个ScopeBean类,定义一个名为message的成员变量和一个setter和getter方法,并在控制台中分别输出setter和getter方法。然后使用xml和@Scope注解分别配置scope作用域和prototype作用域,输出传入的message和调用的getter方法。

@Component
public class ScopeBean {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
<bean id="singletonScopeBean" class="com.example.ScopeBean">
    <property name="message" value="Hello Singleton Scope!" />
</bean>
<bean id="prototypeScopeBean" class="com.example.ScopeBean" scope="prototype">
    <property name="message" value="Hello Prototype Scope!" />
</bean>
@Component
@Scope("prototype")
public class ScopeBean {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

测试类的代码如下:

public class ScopeTest {

    @Autowired
    @Qualifier("singletonScopeBean")
    private ScopeBean singletonBean;

    @Autowired
    @Qualifier("prototypeScopeBean")
    private ScopeBean prototypeBean;

    @Test
    public void testScope() {
        System.out.println(singletonBean.getMessage());
        System.out.println(singletonBean.getMessage());

        System.out.println(prototypeBean.getMessage());
        System.out.println(prototypeBean.getMessage());
    }
}

输出结果如下。可以看到,Singleton作用域的Bean实例仅创建了一次,而Prototye作用域的Bean实例在每次请求时都会重新创建。

Hello Singleton Scope!
Hello Singleton Scope!
Hello Prototype Scope!
Hello Prototype Scope!

例2:@PostConstruct和@PreDestroy示例

我们创建一个LifeCycleBean类,使用@PostConstruct注解定义初始化方法,在其中输出"Init method called"。使用@PreDestroy注解定义销毁方法,在其中输出"Destroy method called"。

@Component
public class LifeCycleBean {

    @PostConstruct
    public void init() {
        System.out.println("Init method called");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("Destroy method called");
    }
}

测试类的代码如下:

public class LifeCycleTest {

    @Test
    public void testLifeCycle() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        context.registerShutdownHook();
    }
}

这里我们创建了一个AnnotationConfigApplicationContext对象,并通过registerShutdownHook()方法注册了一个JVM关闭的钩子函数,以便在JVM关闭时执行销毁方法。

运行测试类输出结果如下。我们可以看到,在Bean被创建时,初始化方法被调用;在JVM关闭时,销毁方法被调用。

Init method called
Destroy method called

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈Spring中Bean的作用域、生命周期 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 微信小程序开发工具怎么下载使用?

    下面是详细讲解“微信小程序开发工具怎么下载使用”的完整攻略。 一、下载微信开发者工具 1.1 下载链接 微信开发者工具的下载链接为:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 1.2 下载方式 根据自己的操作系统选择对应版本进行下载,目前开发者工具支持Wind…

    other 2023年6月26日
    00
  • mysql单字段多值分割和合并的处理方法

    我会为你详细讲解“MySQL单字段多值分割和合并的处理方法”的完整攻略。 什么是单字段多值 单字段多值是指在MySQL表中,存在一个字段中含有多个值。这种数据格式虽然不太常见,但在某些场景中,它是不可避免的。例如,一个用户可能喜欢多个类型的电影,这些电影类型可能都存在同一个字段中。 下面是一个示例: user_id favorite_movies 1 Act…

    other 2023年6月25日
    00
  • sql server 中合并某个字段值的实例

    下面是 SQL Server 中合并某个字段值的实例的完整攻略。 1. CONCAT()函数 SQL Server 中有一个 CONCAT() 函数可以用于合并某个字段的值。它将两个或多个字符串拼接在一起,返回一个合并后的字符串。 示例1:将两个字段合并为一个新字段 假设有一个学生信息表(Student),包含姓名(StuName)、性别(Gender)和年…

    other 2023年6月25日
    00
  • 详解如何热重启golang服务器

    下面是关于如何热重启Golang服务器的详细攻略: 简介 热重启指在运行中的程序重启时,不需要中断或停止该程序的服务,而是在后台保持其服务的情况下,重新加载代码和配置文件,并使新代码和文件生效。 Golang 提供了一些方便的库和工具,可以让我们实现 HTTP 服务器的热重启,使得服务的高可用性和无停机更新成为可能。 方式1:graceful gracefu…

    other 2023年6月27日
    00
  • MySQL数据库实现MMM高可用群集架构

    MySQL数据库实现MMM高可用群集架构攻略 简介 MMM(Master-Master Replication Manager)是一种基于MySQL的高可用性解决方案,它通过实现多主复制来提供数据库的高可用性和负载均衡。以下是实现MMM高可用群集架构的详细攻略: 步骤一:安装和配置MySQL 在每个服务器上安装MySQL数据库,并确保版本一致。 配置MySQ…

    other 2023年10月18日
    00
  • Android视图控件架构分析之View、ViewGroup

    Android视图控件架构分析之View、ViewGroup 1. View View 是 Android 中所有用户界面的基本单元。它代表屏幕上的一个矩形区域,能够处理用户的交互事件。View 是所有控件的基类,包括像 Button、TextView、EditText 等常见控件都继承自 View。 1.1 View 的绘制过程 View 的绘制过程是 A…

    other 2023年6月26日
    00
  • 微信公众号如何获取用户unionid

    以下是关于“微信公众号如何获取用户unionid”的完整攻略,包含两个示例。 微信公众号如何获取用户unionid 在微信公众号开发中,我们通常需要获取用户的unionid,以更好地管理用户。以下是关于如何获取用户unionid的详细攻略。 1. 用户授权获取 在用户授权登录时,我们可以通过OAuth2.0协议获取用户的unionid。以下是一个示例: //…

    other 2023年5月9日
    00
  • 微信小程序Echarts动态使用及图表层级踩坑解决方案

    微信小程序Echarts动态使用及图表层级踩坑解决方案 背景 微信小程序是一款便捷的开发平台,而Echarts又是一款非常强大的数据可视化工具,将二者结合起来可以展现出更加生动、形象的数据图表。但是在实际的开发中,我们可能会遇到一些问题,例如动态使用Echarts和图表层级问题等。 动态使用Echarts 在小程序开发中,我们希望在不同的页面中使用不同的图表…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部