浅谈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日

相关文章

  • Ubuntu系统下扩展LVM根目录的方法

    以下是Ubuntu系统下扩展LVM根目录的详细攻略: 1. 确认LVM分区 在扩展LVM根目录之前,我们需要确认LVM分区是否正确。可以使用以下命令查看: sudo fdisk -l 其中,LVM分区的标志是Linux LVM。如果没有这个标志的话,则需要先创建LVM分区。 2. 创建物理卷 首先需要将新硬盘划分为一个物理卷,并加入LVM卷组。我们用设备/d…

    other 2023年6月27日
    00
  • 第0章概述及常见dos命令

    以下是关于DOS命令的概述及常见命令的完整攻略: 第0章:概述 DOS(Disk Operating System)是一种早期的操作系统,主要用于IBM PC和兼容机。DOS命令是在DOS操作系统中使用的命令行命令,可以用于执行各种任务,如文件管理、磁盘管理、网络管理等。虽然DOS已经被现代操作系统所取代,但DOS命令仍然被广泛使用,特别是在自动化脚本和批处…

    other 2023年5月9日
    00
  • Java实现带头结点的单链表

    下面我会详细讲解Java实现带头结点的单链表的完整攻略。整个过程分为以下几个步骤: 1. 定义单链表节点类 首先,我们需要定义一个节点类来表示单链表的节点。节点类需要包含以下两个属性: 数据域:用来存储节点中的数据。 指针域:指向下一个节点的指针。 以下是节点类的定义示例: public class ListNode { int val; ListNode …

    other 2023年6月27日
    00
  • 服务器135、137、138、139、445等端口解释和关闭方法

    服务器端口解释和关闭方法 端口解释 在网络通信中,端口是指计算机内部进程与外部网络通信的接口。服务器会默认开放一些端口,以供网络通信使用。以下是常见的一些服务器端口及其解释: 端口 135:远程过程调用(RPC)协议,提供服务器上运行的远程程序的调用服务。 端口 137:NetBIOS 名称服务,将 NetBIOS 名称转换为 IP 地址。 端口 138:N…

    other 2023年6月27日
    00
  • 批量列出所有文件名的批处理

    首先,我们需要明确批处理文件的编写目标,即在指定的文件夹中列出所有文件名,并将其输出到一个文本文件中。下面是完成这个目标的具体步骤: 步骤一:打开命令提示符窗口 在电脑屏幕上按下Win+R组合键,打开运行窗口,输入cmd并点击确定,即可打开命令提示符窗口。 步骤二:进入要扫描的文件夹 在命令提示符窗口中输入cd路径,其中路径是指要扫描的文件夹路径。例如,如果…

    other 2023年6月26日
    00
  • 骁龙660aie和骁龙660区别两者性能对比哪个好?

    以下是“骁龙660AIE和骁龙660区别两者性能对比哪个好?”的完整攻略: 骁龙660AIE和骁龙660区别两者性能对比哪个好? 骁龙660AIE和骁龙660都是高通公司推出的中高端移动处理器,它们在性能和功能上有所不同。本攻略将详细讲解骁龙660AIE和骁龙660的区别,以及两者性能的对比。 骁龙660AIE和骁龙660的区别 骁龙660AIE和骁龙660…

    other 2023年5月8日
    00
  • 使用无线网卡时怎样查看ip地址?

    当使用无线网卡时,可以通过以下步骤查看IP地址: 打开命令提示符或终端窗口。在Windows系统中,可以按下Win键+R,然后输入\”cmd\”并按下回车键。在Mac或Linux系统中,可以打开终端应用程序。 在命令提示符或终端窗口中,输入以下命令并按下回车键: ipconfig 这个命令用于显示当前网络连接的详细信息,包括IP地址。 在命令输出中,查找无线…

    other 2023年7月30日
    00
  • java父类和子类初始化顺序的深入理解

    下面我将详细讲解Java父类和子类初始化顺序的深入理解。 父类和子类初始化顺序的基本概念 在Java中,对象的初始化包括两部分:静态初始化和实例初始化。当类被加载时,它的静态成员会被初始化;当类的对象被创建时,会调用构造函数进行实例初始化。父类和子类的初始化顺序如下: 父类的静态成员初始化 子类的静态成员初始化 父类的实例成员初始化 父类的构造函数初始化 子…

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