Spring管理的这些bean藉由配置元数据创建,例如被@Bean注解。那么在 Spring 内部又是如何存储这些信息的呢?
1 BeanDefinition
1.1 域
在容器内,这些bean定义被表示为BeanDefinition对象,它包含但不限于如下元数据:
这些元数据会转换为构成每个bean定义内的一组属性。
1.1.1 包限定类名
被定义bean的实际实现类
1.1.2 bean行为
这些状态指示bean在容器中的行为(作用域、生命周期回调等)。如下即为作用域:
默认的作用域也就是singleton
1.1.3 需要的其它bean引用
这些引用也就是常见的协作或依赖对象。
例如对于如下类:
除了包含有关如何创建特定bean信息的bean定义外,ApplicationContext实现还允许注册在容器外部(用户自定义的)创建的现有对象。
这是通过getBeanFactory()方法访问ApplicationContext的BeanFactory完成的,该方法返回其DefaultListableBeanFactory实现。
DefaultListableBeanFactory通过registerSingleton(..)和registerBeanDefinition(..)方法支持此注册。当然了,我们开发的应用程序一般只使用通过常规的bean定义内的元数据定义的bean。
DefaultListableBeanFactory支持通过如下两种方式进行注册:
registerSingleton(String beanName, Object singletonObject)
bean实例就是传递给registerSingleton方法的singletonObject对象
registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
容器根据BeanDefinition实例化bean
当然了,一般的应用程序还是仅通过元数据定义的bean来定义bean。
Bean元数据和显式编码提供的单例实例需尽早地注册,方便容器在自动装配和其他自省(指在运行时来判断一个对象的类型的能力)过程能正确推理它们。虽然在某种程度上支持覆盖现有的元数据或单例实例,但在运行时(与对工厂的实时访问并发)对新bean的注册并不被正式支持,并且可能导致并发访问异常,比如bean容器中的状态不一致。