Spring学习——Bean和容器

1、Bean

1.1、Bean是什么

简单概括,一个Bean对应Spring容器里的一个Java实例

1.2、Bean的作用域

当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。

Spring支持5种作用域:

  • Singleton:单例模式。在整个SpringIoC容器中,使用singleton定义的Bean将只有一个实例,这是默认的配置
  • Prototype:原型模式。每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
  • request:对于每次HTTP请求,使用request定义的Bean都将产生一个新的实例,即每次HTTP请求都会产生不同的Bean实例。当然只有在WEB应用中使用Spring时,该作用域才真正有效
  • session:对于每次HTTPSession,使用session定义的Bean都将产生一个新的实例,即每次HTTP Session都将产生不同的Bean实例。同HTTP一样,只有在WEB应用才会有效
  • global session:每个全局的HTTPSession对应一个Bean实例。仅在portlet Context的时候才有效

​ 比较常用的singleton和prototype。

  1. 如果一个Bean实例被设置为singleton,那么每次请求该Bean时都会获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为。
  2. 如果一个Bean实例被设置为prototype,那么每次请求该di的Bean,Spring都会创建一个新的Bean实例返回给程序,在这种情况下,Spring容器仅仅使用new关键字创建Bean实例,一旦创建成功,容器将不会再跟踪实例,也不会维护Bean实例的状态

​ 如果我们不指定Bean的作用域,则Spring会默认使用singleton作用域。设置Bean的作用域是通过scope属性来指定。可以接受Singleton、prototype、request、session、global session 5个值。

1.3、Bean的生命周期

在传统的Java应用中,bean的生命周期很简单。使用Java关键字new进行bean实例化,然后该bean就可以使用了。一旦不再使用,则由Java自动进行垃圾回收。

Spring容器中Bean的生命周期

  1. Spring对bean进行实例化
  2. Spring将值和bean的引用注入到bean对应的属性中
  3. 如果bean实现了BeanNameAware接口,Spring将bean的id传递给setBeanName()方法
  4. 如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
  5. 如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext方法,将bean所在的应用上下文的引用传入进来
  6. 如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法
  7. 如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用
  8. 如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法
  9. 此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留于应用上下文中,直到该应用上下文被销毁
  10. 如果bean实现了DisposableBean接口,Spring将调用它的destroy()方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用

2、Spring容器

在基于Spring的应用中,应用对象生存于Spring容器(container)中。Spring容器负责创建对象,装配它们,配置它们并管理它们的整个生命周期。

2.1、Spring容器是什么

容器是Spring框架的核心。Spring容器使用DI管理构成应用的组件,它会创作相互协作的组件之间的关联。

2.2、Spring容器有哪些

Spring容器并不是只有一个。Spring自带了多个容器实现,可以归纳为两种不同的类型:

  1. bean工厂(由org.springframework.beans.factory.BeanFactory接口定义),是最简单的容器,提供基本的DI支持。
  2. 应用上下文(由org.springframework.context.ApplicationContext接口定义)基于BeanFactory构建,并提供框架级别的服务,例如从属性文件解析文本信息以及发布应用事件给感兴趣的事件监听者。

2.3、应用上下文分类

虽然我们可以在bean工厂和应用上下文之间任选一种,但bean工厂对于大多数应用来说往往太低级了。

Spring自带了多种类型的应用上下文,下面是最常见的几种:

  • AnnotationConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文
  • AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载SpringWeb应用上下文
  • ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源
  • FilesSystemXmlApplicationContext:从文件系统下的一个或多个XML配置文件中加载上下文定义
  • XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义

2.4、使用应用上下文

2.4.1、使用FilesSystemXmlApplicationContext或者ClassPathXmlApplicationContext

这两个的使用很相似,如下:

//使用FilesSystemXmlApplicationContext
ApplicationContext context=new FilesSystemXmlApplicationContext("c:/ApplicationContext.xml");

//使用ClassPathXmlApplicationContext
ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml");

这两者区别:

  • FilesSystemXmlApplicationContext在指定的文件系统路径下查找ApplicationContext.xml文件
  • ClassPathXmlApplicationContext在所有的类路径(包含jar文件)下查找ApplicationContext.xml文件
2.4.2、使用AnnotationConfigApplicationContext
ApplicationContext context=new AnnotationConfigApplicationContext(配置类的全限定类名.class);
2.4.3、AnnotationConfigWebApplicationContext和XmlWebApplicationContext
//TODO 在学习基于Web的Spring应用时再做记录

应用上下文准备就绪后,就可以调用上下文的getBean()方法从Spring容器中获取bean


代码书写世界,吉他演奏生活