Spring框架之Bean Scope

Spring框架之Bean ScopeSpring框架支持六个作用域,其中四个只有在使用web感知的ApplicationContext时才可用。

大家好,欢迎来到IT知识分享网。

Spring框架支持六个作用域,其中四个只有在使用web感知的ApplicationContext时才可用。

Spring支持以下6中bean scopes:

  • singleton:单例模式(默认值),在Spring容器中只会创建一个实例
  • prototype:原型模式,每次通过Spring容器获取bean时,容器都会新建一个实例
  • request:每次HTTP请求都会创建一个实例,但只在http request范围有效
  • session:在http session生命周期内,共享一个实例,不同session有不同的实例
  • application:在ServletContext生命周期内,只有一个实例
  • webSocket:在webSocket范围内只有一个实例

Singleton scope

Spring容器默认的作用域,只有一个共享的单例bean实例被管理,id与bean定义的id匹配的bean请求,spring容器都会返回一个特定的bean实例。换句话说,当您定义一个bean为单例时,Spring IoC容器只会创建该bean的一个实例。这个实例存储在缓存中,所有后续对这个bean的请求和引用都返回缓存对象。

Spring框架之Bean Scope

基于java configuration方式定义一个singleton的bean

@Configuration public class AppConfiguration { @Bean @Scope("singleton") // default scope public UserService userService(){ return new UserService(); } }

prototype scope

原型模式会导致每次请求都会创新一个新的bean实例,就是说当一个bean被注入到另一个bean中,或者通过getBean()方法调用请求它时会新创建一个bean实例。通常,有状态的bean使用prototype scope,无状态的bean使用singleton scope。与其它scope不同,spring容器不管理原型scope的整个生命周期,容器实例化、配置和以其他方式组装原型对象,都将其交给client,而无需进一步记录该原型实例。

基于java configuration方式定义一个prototype的bean

@Configuration public class AppConfiguration { @Bean @Scope("prototype") public UserService userService(){ return new UserService(); } }

具有原型bean依赖项的单例bean

当您将单例bean与原型bean的依赖项一起使用时,请注意,依赖项是在实例化时解析的。因此,如果依赖项将原型注入到单例bean中,则会实例化一个新的原型bean,然后将依赖项注入到单例bean中。原型实例是唯一一个提供给单例bean的实例。

Request、Session、Application和WebSocket作用域

Request、Session、Application、WebSocket作用域仅在使用web感知的Spring ApplicationContext实现(如XmlWebApplicationContext)时可用。如果将这些作用域与常规Spring IoC容器(如ClassPathXmlApplicationContext)一起使用,则会抛出一个IllegalStateException,未知bean作用域。

鉴于目前技术发展采用前后端分离模式开发,已很少单独使用Spring web mvc模式,此处不在讲述这四个作用域,大家可以参考官方文档了解。

InitializingBean和DisposableBean

在Spring中,为了与容器bean的生命周期管理进行交互,可以实现InitializingBeanDisposableBean接口。容器初始化时执行AfterPropertieSet(),销毁是调用destroy(),以便bean在初始化和销毁bean时执行某些操作。

@PostConstruct@PreDestroy注释通常被认为是新版Spring应用程序中接收生命周期回调的最佳实践。使用这些注释意味着您的bean没有耦合到特定于Spring的接口。

  1. 实现InitializingBean接口,在所有bean设置完properties后将运行afterPropertiesSet()
  2. 实现DisposableBean接口,在Spring容器释放bean后运行destroy()

InitializingBean和DisposableBean示例

在本例中,我们将使用afterPropertiesSet()方法在应用程序启动期间使用用户对象填充内存中的列表数据结构。我们还将在应用程序关闭期间使用destroy()方法从列表中删除用户对象。

package com.demo.spring; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @Component public class DatabaseInitiaizer implements InitializingBean, DisposableBean { private List < User > listOfUsers = new ArrayList < > (); @Override public void afterPropertiesSet() throws Exception { User user = new User(1, "User"); User user1 = new User(2, "Admin"); User user2 = new User(3, "SuperAdmin"); listOfUsers.add(user); listOfUsers.add(user1); listOfUsers.add(user2); System.out.println("-----------List of users added in init() method ------------"); for (Iterator < User > iterator = listOfUsers.iterator(); iterator.hasNext();) { User user3 = (User) iterator.next(); System.out.println(user3.toString()); } // save to database } @Override public void destroy() { // Delete from database listOfUsers.clear(); System.out.println("-----------After of users removed from List in destroy() method ------------"); for (Iterator < User > iterator = listOfUsers.iterator(); iterator.hasNext();) { User user3 = (User) iterator.next(); System.out.println(user3.toString()); } System.out.println("List is clean up .."); } }
package com.demo.spring; public class User { private Integer id; private String name; public User() {} public User(Integer id, String name) { super(); this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
package com.demo.spring; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = "com.demo.spring") public class AppConfig { }

注意:@ComponentScan注解扫描指定包中所有包中包含@Component注解的类,basePackages指定包路径

package com.demo.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Application { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); context.close(); } }

Output:

-----------List of users added in init() method ------------ User [id=1, name=User] User [id=2, name=Admin] User [id=3, name=SuperAdmin] -----------After of users removed from List in destroy() method ------- List is clean up ..

注意:@PostConstruct and @PreDestroy在后面章节会专门讲解,请关注

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/83847.html

(0)
上一篇 2024-09-19 08:15
下一篇 2024-09-19 10:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信