BeanFactory总览
BeanFactory接口是Spring IoC的基础。它的特定契约主要用于与Spring的其他部分以及相关的第三方框架集成,它的“DefaultListableBeanFactory”实现是高级“GenericApplicationContext”容器中的一个关键委托。
“BeanFactory”和相关接口(如“BeanFactoryAware”、“InitializingBean”、“DisposableBean”)是其他框架组件的重要集成点:不需要任何注解甚至反射,它们允许容器及其组件之间非常高效的交互。应用程序级bean可能使用相同的回调接口,但通常更喜欢声明性依赖注入,通过注解或编程配置。
请注意,核心的“BeanFactory”API级别及其“DefaultListableBeanFactory”实现对配置格式或要使用的任何组件注释不做任何假设。所有这些功能都是通过诸如“XmlBeanDefinitionReader”和“AutowiredAnnotationBeanPostProcessor”等扩展来实现的,这些扩展在作为核心元数据表示的共享“BeanDefinition”对象上运行。这就是使Spring容器如此灵活和可扩展的本质。
如果bean name配置为单例,应用内只会获取到一个实例.如果配置为原型,那么可以实例化好后填充属性(基于用户的配置).
BeanFactory需要管理bean的生命周期,比如初始化时需要按顺序实现如下接口:
- BeanNameAware's {@code setBeanName}
- BeanClassLoaderAware's {@code setBeanClassLoader}
- BeanFactoryAware's {@code setBeanFactory}
- ResourceLoaderAware's {@code setResourceLoader}仅对application context有效
- ApplicationEventPublisherAware's {@code setApplicationEventPublisher}仅对application context有效
- MessageSourceAware's {@code setMessageSource}仅对application context有效
- ApplicationContextAware's {@code setApplicationContext}仅对application context有效
- ServletContextAware's {@code setServletContext}仅对application context有效
- {@code postProcessBeforeInitialization} methods of BeanPostProcessors
- InitializingBean's {@code afterPropertiesSet}
- a custom init-method definition xml中配置的init-method
- {@code postProcessAfterInitialization} methods of BeanPostProcessors
还有关闭容器的接口:
- DisposableBean's {@code destroy}
- a custom destroy-method definition xml配置中的destroy-method
接口里定义了一个变量String FACTORY_BEAN_PREFIX = "&"; 这是用来区分是获取FactoryBean还是FactoryBean的createBean创建的实例.如果&开始则获取FactoryBean;否则获取createBean创建的实例.
BeanFactory接口方法
序号 | 方法名称 | 描述 |
---|---|---|
1 | Object getBean(String name) throws BeansException; | 返回指定bean的一个实例,该实例可以是共享的,也可以是独立的。 |
2 | <T> T getBean(String name, Class<T> requiredType) throws BeansException; | 输入bean必须匹配。可以是实际类的接口或超类,也可以是任何匹配的{null}。例如,如果值是{Object.class}对象。无论返回的实例的类是什么,这个方法都会成功。 |
3 | <T> T getBean(Class<T> requiredType) throws BeansException; | 允许指定显式构造函数参数/工厂方法参数,覆盖bean定义中指定的默认参数(如果有的话) |
4 | Object getBean(String name, Object... args) throws BeansException; | 使用显式参数创建bean实例时使用的args参数(仅在创建新实例而不是检索现有实例时使用) |
5 | <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; | 使用显式参数创建bean实例时使用的args参数(仅在创建新实例而不是检索现有实例时使用) |
6 | boolean containsBean(String name); | 这个bean工厂是包含bean定义还是外部注册的具有给定名称的singleton实例 |
7 | boolean isSingleton(String name) throws NoSuchBeanDefinitionException; | 是否singleton |
8 | boolean isPrototype(String name) throws NoSuchBeanDefinitionException; | 是否prototype |
9 | boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; | name与传入类型是否匹配,ResolvableType是封装的java.lang.reflect.Type |
10 | boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; | name与传入类型是否匹配 |
11 | Class<?> getType(String name) throws NoSuchBeanDefinitionException; | 返回给定bean name的类型 |
12 | String[] getAliases(String name); | 返回给定bean name的别名 |
总结:
1、4个获取实例的方法。getBean的重载方法。
2、4个判断的方法。判断是否存在,是否为单例、原型,名称类型是否匹配。
3、1个获取类型的方法、一个获取别名的方法。根据名称获取类型、根据名称获取别名。一目了然!
这10个方法,很明显,这是一个典型的工厂模式的工厂接口。
2. AutowireCapableBeanFactory
在BeanFactory基础上实现对已存在实例的管理.
可以使用这个接口集成其它框架, 捆绑并填充并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用.
一般应用开发者不会使用这个接口,所以像ApplicationContext这样的外观实现类不会实现这个接口,如果真手痒痒可以通过ApplicationContext的getAutowireCapableBeanFactory接口获取.
这边定义了5种自动装配策略:不注入AUTOWIRE_NO,使用bean name策略装配AUTOWIRE_BY_NAME,使用类型装配策略AUTOWIRE_BY_TYPE,使用构造器装配策略AUTOWIRE_CONSTRUCTOR,自动装配策略AUTOWIRE_AUTODETECT
这边的自动策略是先尝试构造器,然后才是byType.这边应该是跟xml配置文件中的装配策略对应.
AutowireCapableBeanFactory定义的方法:
序号 | 方法名称 | 描述 |
---|---|---|
1 | <T> T createBean(Class<T> beanClass) throws BeansException; | 创建和填充外部bean实例的典型方法 |
2 | void autowireBean(Object existingBean) throws BeansException; | 使用autowireBeanProperties装配属性 |
3 | Object configureBean(Object existingBean, String beanName) throws BeansException; | 自动装配属性,填充属性值,使用诸如setBeanName,setBeanFactory这样的工厂回调填充属性,最好还要调用post processor |
4 | Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; | 在bean的生命周期进行细粒度控制的专门方法。会执行bean完整的初始化,包括BeanPostProcessors和initializeBean |
5 | Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; | 根据指定Class创建一个全新的Bean实例 |
6 | void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException; | 在bean的生命周期进行细粒度控制的专门方法。 |
7 | void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException; | 在bean的生命周期进行细粒度控制的专门方法。 |
8 | Object initializeBean(Object existingBean, String beanName) throws BeansException; | 在bean的生命周期进行细粒度控制的专门方法。 |
9 | Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException; | 在bean的生命周期进行细粒度控制的专门方法。 |
10 | Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException; | 初始化之后执行BeanPostProcessors |
11 | void destroyBean(Object existingBean); | 销毁给定的bean |
12 | <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException; | 解析与给定对象类型(如果有的话)唯一匹配的bean实例,包括它的bean名称。 |
13 | Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException; | 分解指定的依赖 |
14 | Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException; | 分解指定的依赖 |
ListableBeanFactory
ListableBeanFactory是BeanFactory接口的扩展,bean工厂可以枚举所有bean实例,而不是根据客户的请求逐一查找。需要预加载所有bean定义(例如基于xml的工厂)的BeanFactory实现可以实现这个接口。
这个接口中的方法仅仅关注此工厂内部的bean定义,会会忽略任何被像ConfigurableBeanFactory的registerSingleton方法已注册的单例的bean。getBeanNamesOfType和getBeansOfType例外,但也会手动的检查已被注册的单例bean。当然,BeanFactory的getBean方法也可以透明的访问这些特殊的bean(已被注册的单例bean)。然而,在一般的场合,无论如何,所有bean都会被外部定义,所以许多程序不需要考虑这方面区别。
注意: getBeanDefinitionCount和containsBeanDefinition的实现方法因为效率比较低,还是少用为好.
总结:
1、总共5个静态不可变常量来指明装配策略,其中一个常量被Spring3.0废弃、一个常量表示没有自动装配,另外3个常量指明不同的装配策略——根据名称、根据类型、根据构造方法。
2、9个跟自动装配有关的方法,实在是繁杂,具体的意义我们研究类的时候再分辨吧。
3、2个执行BeanPostProcessors的方法。
4、3个分解指定依赖的方法
这个工厂接口继承自BeanFacotory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean、执行前、后处理器等。
ListableBeanFactory方法
序号 | 方法名称 | 描述 |
---|---|---|
1 | boolean containsBeanDefinition(String beanName); | 检查这个BeanFactory是否包含给定名字的的bean定义。 不考虑这个工厂参与的任何层级关系,忽略不是bean定义的所有通过其他方式注册的单例bean |
2 | int getBeanDefinitionCount(); | 返回在此工厂中定义的bean数量。不考虑这个工厂参与的任何层级关系,忽略不是bean定义的所有通过其他方式注册的单例bean |
3 | String[] getBeanDefinitionNames(); | 返回此工厂中定义的所有bean的名字。不考虑此工厂参与的所有层次关系,忽略不是bean定义的所有通过其他方式注册的单例bean |
4 | String[] getBeanNamesForType(ResolvableType type); | 返回匹配给定类型(包括子类)的所有bean的名字,如果是普通bean,则是bean定义的名字,如果是FactoryBean,则是其getObjectType方法返回的对象的名字 |
5 | String[] getBeanNamesForType(Class<?> type); | 返回匹配给定类型(包括子类)的所有bean的名字,如果是普通bean,则是bean定义的名字,如果是FactoryBean,则是其getObjectType方法返回的对象的名字 |
6 | String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit); | allowEagerInit:是否允许马上加载 ,如果是factoryBean创建的对象,此处应是true |
7 | <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; | 返回匹配给定类型(包含子类)的实例,可能是通过bean定义创建,也可以是FactoryBean时其getObjectType返回 |
8 | String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType); | 返回指定注解的bean name |
9 | Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException; | 返回指定注解的bean map |
10 | <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) throws NoSuchBeanDefinitionException; | 返回指定bean name上的指定注解对象 |
HierarchicalBeanFactory
提供父容器的访问功能.至于父容器的设置,需要找ConfigurableBeanFactory的setParentBeanFactory(接口把设置跟获取给拆开了!)。
HierarchicalBeanFactory方法
序号 | 方法名称 | 描述 |
---|---|---|
1 | BeanFactory getParentBeanFactory(); | 返回父bean factory对象 |
2 | boolean containsLocalBean(String name); | 检查这个BeanFactory是否包含给定名字的的bean定义。 不考虑这个工厂参与的任何层级关系,忽略不是bean定义的所有通过其他方式注册的单例bean |
ConfigurableBeanFactory
ConfigurableBeanFactory定义BeanFactory的配置.ConfigurableBeanFactory中定义了太多太多的api,比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系,合并其他ConfigurableBeanFactory,bean如何销毁.
ConfigurableBeanFactory同时继承了HierarchicalBeanFactory 和 SingletonBeanRegistry 这两个接口,即同时继承了分层和单例类注册的功能。
ConfigurableBeanFactory方法
序号 | 方法名称 | 描述 |
---|---|---|
1 | String SCOPE_SINGLETON = "singleton"; | 单例 |
2 | String SCOPE_PROTOTYPE = "prototype"; | 原型 |
3 | void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException; | 搭配HierarchicalBeanFactory接口的getParentBeanFactory方法 |
4 | void setBeanClassLoader(ClassLoader beanClassLoader); | 设置、返回工厂的类加载器 |
5 | ClassLoader getBeanClassLoader(); | 设置、返回工厂的类加载器 |
6 | void setTempClassLoader(ClassLoader tempClassLoader); | 设置、返回一个临时的类加载器 |
7 | ClassLoader getTempClassLoader(); | 设置、返回一个临时的类加载器 |
8 | void setCacheBeanMetadata(boolean cacheBeanMetadata); | 设置、是否缓存元数据,如果false,那么每次请求实例,都会从类加载器重新加载(热加载) |
9 | isCacheBeanMetadata(); | 是否缓存元数据 |
10 | void setBeanExpressionResolver(BeanExpressionResolver resolver); | Bean表达式分解器 |
11 | BeanExpressionResolver getBeanExpressionResolver(); | 设置、返回一个转换服务 |
12 | void setConversionService(ConversionService conversionService); | 设置、返回一个转换服务 |
13 | ConversionService getConversionService(); | 设置属性编辑登记员... |
14 | void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar); | 注册常用属性编辑器 |
15 | void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass); | 用工厂中注册的通用的编辑器初始化指定的属性编辑注册器 |
16 | void copyRegisteredEditorsTo(PropertyEditorRegistry registry); | 设置、得到一个类型转换器 |
17 | void setTypeConverter(TypeConverter typeConverter); | 设置、得到一个类型转换器 |
18 | TypeConverter getTypeConverter(); | 设置、得到一个类型转换器 |
19 | void addEmbeddedValueResolver(StringValueResolver valueResolver); | 增加一个嵌入式的StringValueResolver |
20 | boolean hasEmbeddedValueResolver(); | 是否有一个嵌入式的StringValueResolver |
21 | String resolveEmbeddedValue(String value); | 分解指定的嵌入式的值 |
22 | void addBeanPostProcessor(BeanPostProcessor beanPostProcessor); | 设置一个Bean后处理器 |
23 | int getBeanPostProcessorCount(); | 返回Bean后处理器的数量 |
24 | void registerScope(String scopeName, Scope scope); | 注册范围 |
25 | String[] getRegisteredScopeNames(); | 返回注册的范围名 |
26 | Scope getRegisteredScope(String scopeName); | 返回指定的范围 |
27 | AccessControlContext getAccessControlContext(); | 返回本工厂的一个安全访问上下文 |
28 | void copyConfigurationFrom(ConfigurableBeanFactory otherFactory); | 从其他的工厂复制相关的所有配置 |
29 | void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException; | 给指定的Bean注册别名 |
30 | void resolveAliases(StringValueResolver valueResolver); | 根据指定的StringValueResolver移除所有的别名 |
31 | BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; | 返回指定Bean合并后的Bean定义 |
32 | boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException; | 判断指定Bean是否为一个工厂Bean |
33 | void setCurrentlyInCreation(String beanName, boolean inCreation); | 设置一个Bean是否正在创建 |
34 | boolean isCurrentlyInCreation(String beanName); | 返回指定Bean是否已经成功创建 |
35 | void registerDependentBean(String beanName, String dependentBeanName); | 注册一个依赖于指定bean的Bean |
36 | String[] getDependentBeans(String beanName); | 返回依赖于指定Bean的所欲Bean名 |
37 | String[] getDependenciesForBean(String beanName); | 返回指定Bean依赖的所有Bean名 |
38 | void destroyBean(String beanName, Object beanInstance); | 销毁指定的Bean |
39 | void destroyScopedBean(String beanName); | 销毁指定的范围Bean |
40 | void destroySingletons(); | 销毁所有的单例类 |
分类:
1、2个静态不可变常量分别代表单例类和原型类。
2、1个设置父工厂的方法,跟HierarchicalBeanFactory接口的getParentBeanFactory方法互补。
3、4个跟类加载器有关的方法:get/set工厂类加载器和get/set临时类加载器。
4、2个设置、是否缓存元数据的方法(热加载开关)。
5、11个处理Bean注册、加载等细节的方法,包括:Bean表达式分解器、转换服务、属性编辑登记员、属性编辑器、属性编辑注册器、类型转换器、嵌入式的字符串分解器
6、2个处理Bean后处理器的方法。
7、3个跟注册范围相关的方法。
8、1个返回安全访问上下文的方法、1个从其他的工厂复制相关的所有配置的方法。
9、2个跟Bean别名相关的方法、1个返回合并后的Bean定义的方法。
10、1个判断是否为工厂Bean的方法、2个跟当前Bean创建时机相关的方法。
11、3个跟Bean依赖相关的方法、3个销毁Bean相关的方法。
SingletonBeanRegistry 这两个接口,并额外独有38个方法!这38个方法包含了工厂创建、注册一个Bean的众多细节。这个工厂名为ConfigurableBeanFactory,真是名不虚传!统计一下此时的ConfigurableBeanFactory的方法数吧。自有的37个方法、HierarchicalBeanFactory的2个方法、SingletonBeanRegistry的5个方法、爷爷接口BeanFactory的10个方法,共有54个方法!虽然方法繁多,还算井井有条!
ConfigurableListableBeanFactory
提供bean definition的解析,注册功能,再对单例来个预加载(解决循环依赖问题).
貌似我们一般开发就会直接定义这么个接口了事.而不是像Spring这样先根据使用情况细分那么多,到这边再合并
ConfigurableListableBeanFactory方法
序号 | 方法名称 | 描述 |
---|---|---|
1 | void ignoreDependencyType(Class<?> type); | 忽略自动装配的依赖类型 |
2 | void ignoreDependencyInterface(Class<?> ifc); | 忽略自动装配的接口 |
3 | void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue); | 注册一个可分解的依赖 |
4 | boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException; | 判断指定的Bean是否有资格作为自动装配的候选者 |
5 | BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; | 返回注册的Bean定义 |
6 | void freezeConfiguration(); | 暂时冻结所有的Bean配置 |
7 | boolean isConfigurationFrozen(); | 判断本工厂配置是否被冻结 |
8 | void preInstantiateSingletons() throws BeansException; | 使所有的非延迟加载的单例类都实例化。 |
9 | Iterator<String> getBeanNamesIterator(); | 返回bean name迭代器 |
10 | void clearMetadataCache(); | 清除元数据缓存 |
具体:
1、2个忽略自动装配的的方法。
2、1个注册一个可分解依赖的方法。
3、1个判断指定的Bean是否有资格作为自动装配的候选者的方法。
4、1个根据指定bean名,返回注册的Bean定义的方法。
5、2个冻结所有的Bean配置相关的方法。
6、1个使所有的非延迟加载的单例类都实例化的方法。
7、1个返回所有bean name的迭代器方法
8、1个清除元数据缓存的方法
总结:工厂接口ConfigurableListableBeanFactory同时继承了3个接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,扩展之后,加上自有的这8个方法,这个工厂接口总共有83个方法,实在是巨大到不行了。这个工厂接口的自有方法总体上只是对父类接口功能的补充,包含了BeanFactory体系目前的所有方法,可以说是接口的集大成者。
BeanFactory or ApplicationContext?
尽量使用‘ApplicationContext’除非你有很好的理由不这样做,使用‘GenericApplicationContext’和它的子类‘AnnotationConfigApplicationContext’作为通用的自定义引导实现。这些是Spring核心容器的主要入口点,用于所有常见目的:加载配置文件、触发类路径扫描、以编程方式注册bean定义和带注释的类。
因为“ApplicationContext”包含“BeanFactory”的所有功能,所以通常建议使用它而不是普通的“BeanFactory”,除非是需要对bean处理进行完全控制的场景。在‘ApplicationContext’(如‘GenericApplicationContext’实现)中,有几种类型的bean将被约定(即通过bean名称或bean类型)检测,特别是后处理器,而普通的‘DefaultListableBeanFactory’与任何特殊bean无关。
对于许多扩展容器特性,如注释处理和AOP代理,' BeanPostProcessor '扩展点是必不可少的。如果你只使用一个普通的“DefaultListableBeanFactory”,这样的后处理器在默认情况下不会被检测和激活。这种情况可能令人困惑,因为您的bean配置实际上没有任何问题;在这种情况下,需要通过额外的设置完全引导容器。
下表列出了“BeanFactory”和“ApplicationContext”接口和实现提供的功能
Feature | BeanFactory |
ApplicationContext |
---|---|---|
Bean instantiation/wiring | Yes | Yes |
Integrated lifecycle management | No | Yes |
Automatic BeanPostProcessor registration |
No | Yes |
Automatic BeanFactoryPostProcessor registration |
No | Yes |
Convenient MessageSource access (for internalization) |
No | Yes |
Built-in ApplicationEvent publication mechanism |
No | Yes |
要显式地将bean后处理器注册到DefaultListableBeanFactory,您需要以编程方式调用addBeanPostProcessor:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// now start using the factory
要将' BeanFactoryPostProcessor '应用到普通的' DefaultListableBeanFactory '上,需要调用其' postProcessBeanFactory '方法:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// bring in some property values from a Properties file
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
// now actually do the replacement
cfg.postProcessBeanFactory(factory);
在这两种情况下,显式注册步骤都不方便,这就是为什么在spring支持的应用程序中,各种“ApplicationContext”变体比普通的“defaultlistablebeanfactory”更受青睐的原因,特别是在典型的企业设置中依赖“BeanFactoryPostProcessor”和“BeanPostProcessor”实现扩展容器功能时更是如此。
一个“AnnotationConfigApplicationContext”具有所有现成注册的通用注释后处理器,并且可以通过配置注释(如“@EnableTransactionManagement”)在幕后引入额外的处理器。在Spring基于注释的配置模型的抽象级别上,bean后处理器的概念仅仅是一个内部容器细节。