Spring版本:5.1.3.RELEASE
BeanFactory
接口:
1 | String FACTORY_BEAN_PREFIX = "&"; |
是简单工厂模式的应用,根据传入的beanName实例化相应的实例。
JavaDoc翻译(使用Google翻译并加以润色,如有歧义欢迎指出):
用于访问Spring bean容器的根接口。 这是bean容器的基本客户端视图; 其他接口(如ListableBeanFactory和org.springframework.beans.factory.config.ConfigurableBeanFactory)可用于特定目的。
该接口被一些持有bean定义的对象实现,每个bean定义由一个字符串名称唯一标识。
根据bean定义,工厂将返回包含对象的独立实例(Prototype设计模式)或单个共享实例(Singleton设计模式的高级替代,其中实例是工厂范围中的单例)。
将返回哪种类型的实例取决于bean工厂配置:API是相同的。
从Spring 2.0开始,根据具体的应用程序上下文(例如Web环境中的“request”和“session”范围),可以使用更多的scope(范围)。
这种方法的重点是BeanFactory是应用组件的注册中心和集中的配置中心(例如,不再需要单个对象去读取属性文件)。
有关此方法的优点的讨论,请参见”Expert One-on-One J2EE Design and Development”的第4章和第11章。
请注意,依靠依赖注入(“push”配置)通过setter或构造函数来配置应用对象通常更好,而不是像BeanFactory查找一样的使用“pull”配置的任意方式。Spring的依赖注入功能是使用这个BeanFactory接口及其子接口实现的。
通常,BeanFactory将加载存储在配置源(例如XML文档)中的bean定义,并使用org.springframework.beans包来配置bean。尽管如此,一种简单地实现是直接在Java代码中返回Java对象。如何存储定义没有限制:LDAP,RDBMS,XML,属性文件等。鼓励实现支持bean之间的引用(依赖注入)。
与ListableBeanFactory中的方法相反,如果这是HierarchicalBeanFactory,则此接口中的所有操作也将检查父工厂。如果在此工厂实例中找不到bean,则会询问直接父工厂(从父类bean工厂中获取)。此工厂实例中的Bean应该在任何父工厂中覆盖同名的Bean。
Bean工厂实现应尽可能支持标准bean生命周期接口。 完整的初始化方法及其标准顺序是:
- BeanNameAware 接口的 setBeanName 方法
- BeanClassLoaderAware 接口的 setBeanClassLoader 方法
- BeanFactoryAware 接口的 setBeanFactory 方法
- EnvironmentAware 接口的 setEnvironment 方法
- EmbeddedValueResolverAware 接口的 setEmbeddedValueResolver 方法
- ResourceLoaderAware 接口的 setResourceLoader 方法 (仅适用于在应用程序上下文(Application Context)中运行时)
- ApplicationEventPublisherAware 接口的 setApplicationEventPublisher 方法 (仅适用于在应用程序上下文(Application Context)中运行时)
- MessageSourceAware 接口的 setMessageSource 方法 (仅适用于在应用程序上下文(Application Context)中运行时)
- ApplicationContextAware 接口的 setApplicationContext 方法 (仅适用于在应用程序上下文(Application Context)中运行时)
- ServletContextAware 接口的 setServletContext 方法 (仅适用于在应用程序上下文(Application Context)中运行时)
- 所有实现了BeanPostProcessor接口的类的 postProcessBeforeInitialization 方法
- InitializingBean 接口的 afterPropertiesSet 方法
- 自定义的init方法
- 所有实现了BeanPostProcessor接口的类的 postProcessAfterInitialization 方法
关闭Bean工厂时,应用以下生命周期方法:
- 所有实现了DestructionAwareBeanPostProcessor接口的类的 postProcessBeforeDestruction 方法
- DisposableBean 接口的 destroy 方法
- 自定义的destroy 方法
Spring Bean生命周期图:
Spring 4.3.17.RELEASE 源码的JavaDoc文档写的也是以上流程。跟其它网上的文章写的流程有出入,应该以官方文档为准。
FactoryBean
接口:
1 | T getObject() throws Exception; |
是工厂方法模式的应用,由子类实现相应的实例。
JavaDoc翻译(使用Google翻译并加以润色,如有歧义欢迎指出):
接口被BeanFactory中使用的对象所实现,这些对象本身就是单个对象的工厂。如果bean实现了这个接口,它将被用作暴露此对象的工厂,而不是直接将自己作为bean实例给暴露出来。
注意:实现此接口的bean不能用作普通bean。
FactoryBean是被定义成bean的形式,但是bean对象的引用(getObject()方法获得)始终是由它创建的。
FactoryBeans可以支持单例和原型,可以根据需要懒惰地创建对象,也可以在启动时急切地创建对象。
SmartFactoryBean接口允许公开更细粒度的行为元数据。
该接口在框架内部大量使用,例如用于AOP的 org.springframework.aop.framework.ProxyFactoryBean类 或 org.springframework.jndi.JndiObjectFactoryBean类。
它也可以用于定制组件;但是,这仅适用于基础架构代码。
FactoryBean是一个programatic contract (编程合约)。实现不应该依赖annotation-driven (注解驱动)的注入或其他反射设施。
getObjectType()和getObject()方法的调用可能在引导过程的早期发生,甚至在所有的(post-processor)后置处理器设置之前。
如果您需要访问其他bean,请实现 BeanFactoryAware 并以编程方式获取它们。
最后,FactoryBean对象参与包含BeanFactory的bean创建的同步。
除了FactoryBean本身(或类似)中的延迟初始化之外,通常不需要内部同步。
下面从源码层面深入分析二者区别:
查看 BeanFactory接口的抽象类 AbstractBeanFactory的getObjectForBeanInstance方法的实现:
1 | protected Object getObjectForBeanInstance( |
在getObjectFromFactoryBean方法实现中会调用doGetObjectFromFactoryBean方法:
1 | private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) |
实现FactoryBean的类,在初始化放入容器后,通过BeanFactory的getBean方法调用时,会调用FactoryBean的getObject方法返回对应的bean实例对象,而不是像普通的bean一样直接返回bean实例.
BeanFactory的常量&
的作用是在获取bean的时候直接返回FactoryBean的bean实例,而不是调用的getObject方法返回对应的bean实例.
以上,如有问题欢迎提出!