以下是关于Spring中Bean的作用域和生命周期的详细讲解,包括定义、配置、作用域和生命周期四个方面。
定义
在Spring中,Bean就是被Spring容器所管理的Java对象。我们可以将Java对象配置为一个Bean,并通过Spring容器去创建、管理、装配、销毁这个Bean。
配置
Bean的配置分为两种方式:XML和注解。
XML配置
在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提供了两种方式来定义初始化方法:
-
使用
@PostConstruct
注解```java
@Component
public class MyBean {@PostConstruct public void init() { // 初始化代码 }
}
``` -
在XML配置中指定
init-method
xml
<bean id="myBean" class="com.example.MyBean" init-method="init"/>
销毁方法
在Bean实例被销毁前,容器会调用Bean的销毁方法。Spring提供了两种方式来定义销毁方法:
-
使用
@PreDestroy
注解```java
@Component
public class MyBean {@PreDestroy public void destroy() { // 销毁代码 }
}
``` -
在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技术站