首页 > 编程语言 > 详细

Spring Bean概览

时间:2021-06-09 09:46:16      阅读:25      评论:0      收藏:0      [点我收藏+]

Bean概览

如前所述,bean是使用配置诠释中的bean定义创建的,在container内部这些bean的定义用一个BeanDefinition对象来表示,具有一下诠释:

  1. 一个包限定的类名,及bean的类型
  2. bean的行为配置元素,例如时间上的存在范围(scope)、生命周期回调等等
  3. bean的依赖
  4. 其他配置信息,例如类池的大小(最多可实例化的个数),一个bean最大的管理的连接数

bean定义中的配置信息会被转换成BeanDefenition的属性,如下:

property
Class
Name
Scope
Constructor arguments
Properties
Autowiring mode
Lazy initialization mode
Initialization method
Destruction method

除了允许配置诠释中的定义外,ApplicationContext还允许Container外部对象的注册。通过调用ApplicationContextgetBeanFactory方法得到一个BeanFactory实例,这个实例是其中BeanFactory的其中一个实现DefaultListableBeanFactory,再使用这个实例的registerSingleton或者registerBeanDefinition方法即可完成。

注意:Container外的单例对象应该尽早的注册,以免在Autowiring或其他的Spring内部进行的步骤中发生错误。由于一定程度上,Container允许一定程度上的诠释的覆盖(override),新注册的bean不会得到正式的支持,从而引发并发上的访问问题,在Container中状态不一致等问题。

命名Beans

每一个Beans拥有一个或多个标识符,这些标识符在主持它的容器中必须是唯一的。一个bean可以拥有一个id标识符和多个name标识符。如果不显示地给一个bean提供标识符,Container会生成一个,但这样就没法在其他地方引用这个bean。不提供标识符通常与inner beans或使用autowiring collaborators有关。

Container生成标识符的规则与一般的命名方式相同,在不适用的时候保留类名。

通常在配置诠释中配置一个bean的name,但是也允许在bean的定义配置诠释外配置一个bean的别名,这通常用在一个每个子系统都有各自配置的大系统中。在xml中从外部配置一个bean的别名:

<alias name="fromName" alias="toName"/>

使用java配置时,从@Bean的属性中配置别名。

实例化Beans

如上所述,一个BeanDefinition是一个创建Bean的配置单,Container通过访问BeanDefinition中封装的信息来创建一个实际的bean对象。

BeanDefinition的Class属性,或者说配置诠释中的Class属性,有以下两种应用方式:

  • 指定一个由Container通过反射机制直接构造的bean(与使用new操作符等价)的类型
  • 指定一个有静态工厂方法的类,Container通过调用这个类的静态工厂方法来创建bean,实际得动的bean的类型不受约束。

以构造器方式实例化

这种方式下所有常规类都是可用的,并且与Spring兼容,这表示这个被开发的类不需要实现任何接口或者以一种特定的方式coded。仅仅提供类型即可。不过,也许你需要给这个类写一个默认的无参构造方法。

大多数人喜欢写无参构造方法以及getter和setter方法以便Container使用。Container中也可以管理一些不那么符合上面这种方式写出的类,例如一些遗留下来的,完全没有依附于Spring的类。

静态工厂方法实例化

如上所述,BeanDefinition的Class属性可以指定一个拥有静态工厂方法的类。这种方式的一个用处是调用遗留代码中的静态工厂方法。

这样的bean的配置诠释的一个例子:

<bean id="clientService"
	class="examples.ClientService" 
      factory-method="createInstance"/>

注意,使用哪一个工厂方法是需要指定明确的。

通过一个实例的工厂方法实例化

与调用静态工厂方法实例化一个类的方式类似,不过不要指定需要实例化的bean的类型,通过factory-bean指定容器中的另一个bean,由这个bean调用其被factory-method指定的工厂方法实例化需要的bean。

例如:

<!-- the factory bean, which contains a method called createInstance() --> 
<bean id="serviceLocator" class="examples.DefaultServiceLocator"> 
    <!-- inject any dependencies required by this locator bean -->
</bean>
<!-- the bean to be created via the factory bean --> 
<bean id="clientService"
	factory-bean="serviceLocator"
	factory-method="createClientServiceInstance"/>

这里需要指出的是,Container中的bean是可以作为一个工厂对象去实例化另外的bean的。

有个易混淆的东西:在Spring中factory-bean指生成bean的工厂对象,而FactoryBean是指一个FactoryBean的特定实现。

判定一个bean的运行时类型

一个bean的配置诠释中的类只是一个最初的参考,这个类与一个工厂方法组合在一起,或者是一个FactoryBean类,这两种情况可能导致bean的不同运行时类型,或者在一个使用实例的工厂方法实例化的情况下完全没有指定。其他的,AOP代理可能在接口基础上包装一个bean实例以免暴露这个bean的真正运行时类型。

要找出一个bean的运行时类型,建议对这个bean(通过bean的标识符)使用BeanFactory.getType,这个方式将上面所有的情况纳入了考虑,并且返回的类型和对特定表示符使用BeanFactory.getBean(这个方法需要两个参数name和type)同样的类型。

Spring Bean概览

原文:https://www.cnblogs.com/kicey/p/14865315.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!