BeanFactory接口Spring框架用来盛放Beans最基础最泛化的接口。相比之下,其子类如ListableBeanFactorty或ConfigureableBeanFactory都是有更确切目标的接口。Spring中,每一个盛放Bean的容器类都应该实现此接口,并且用唯一的id来标识每一个Bean。
此类主要提供了从容器中通过类型,名字来获取Bean的方法。以及通过名字类型来查询对应Bean是否是单例等信息的方法。
通常来说,使用Spring的依赖注入(DI)体系来配置Bean要比使用BeanFactory的lookUp方式来的好。Spring DI体系的实现就是基于此接口及其子类接口的。BeanFactory 一般会从配置源(如XML文件)中加载bean的定义,并通过org.springframework.beans包下的类来对其进行配置。但是此接口并没有限制必须要从那个数据源中来获取Bean。你可以实现此接口来从LDAP、RDBMS、XML、Properties甚至直接使用代码new出来一个都没有问题。只要满足你的需求。
BeanFactory接口有两个直接子接口,ListableBeanFactory和HierarchicalBeanFactory。如果一个类实现了HierarchicalBeanFactory接口,那么BeanFactory接口中的这些方法,原则上除了调用本类中的方法,还应该检查其父BeanFactory中是否有满足要求,当然具体策略还是由实现者来定,只是这样更加符合语义。
BeanFactory的具体实现类还应该支持目前Spring提供的,在Bean的各个生命阶段用来对其进行初始化或者销毁的接口。当前(4.1.2版本)中,Spring提供的所有支持在Bean生命周期内调用的初始化的方法有:
* <li>BeanNameAware's {@code setBeanName}
* <li>BeanClassLoaderAware's {@code setBeanClassLoader}
* <li>BeanFactoryAware's {@code setBeanFactory}
* <li>EnvironmentAware's {@code setEnvironment}
* <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
* <li>ResourceLoaderAware's {@code setResourceLoader}
* (only applicable when running in an application context)
* <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
* (only applicable when running in an application context)
* <li>MessageSourceAware's {@code setMessageSource}
* (only applicable when running in an application context)
* <li>ApplicationContextAware's {@code setApplicationContext}
* (only applicable when running in an application context)
* <li>ServletContextAware's {@code setServletContext}
* (only applicable when running in a web application context)
* <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
* <li>InitializingBean's {@code afterPropertiesSet}
* <li>a custom init-method definition
* <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
Spring提供的在BeanFactory销毁前调用的方法有
<ol>
* <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* <li>DisposableBean's {@code destroy}
* <li>a custom destroy-method definition
* </ol>
好了,接下来看下该接口的源码吧。接口中的方法肯定不会有逻辑的,这里只是看下Spring提倡该接口中的方法怎么用。
public interface BeanFactory {
/**
* 此符号在Spring中用以区分由FactoryBean创建出来的Bean和FactoryBean本身
* 假设 myJndiObject 是一个 FactoryBean, 那么 &myJndiObject
* 将会返回工厂本身,而不是由工厂创建的bean
*/
String FACTORY_BEAN_PREFIX = "&";
/**
* 返回指定参数那么指定的Bean
* 此方法允许BeanFactory参照单例或者原型模式来返回Bean,例如如果用户在配置Bean的时候,指定了
* Scope是Prototype的,那么没调一次此方法,都会返回一个name对应的新生成的Bean。
* 如果参数name用的是Bean对应的别名,在查找的时候会转换成全限定的名称
* 如果本BeanFactory实例中找不到此name对应的Bean,那么去其父BeanFactory中找
*/
Object getBean(String name) throws BeansException;
/**
* 和getBean(String)此方法功能相同,不过在此基础上提供了类型检查。如果BeanFactory中的Bean和所要求的Bean类型
* 不同,会抛出BeanNotOfRequiredTypeException。requiredType可以是BeanFactory中所存Bean的父类或接口
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
/**
* 返回唯一符合参数所指定类型的Bean。此方法和ListableBeanFactory的by-type Bean查找方式可能会
* 有功能上的重合。但是BeanFactory的实现类也有可能将此方法实现为针对所指定类型的by-name查找(类
* 的首字母小写定位Bean的name)。ListableBeanFactory和BeanFactoryUtils中包含更多查找Bean的方法
*/
<T> T getBean(Class<T> requiredType) throws BeansException;
/**
* 返回参数中指定name的Bean,同时此方法允许你显式的的指定创建Bean时传递给构造方法或者工厂Bean的参数,以覆盖
* Bean定义中默认参数
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanDefinitionStoreException if arguments have been given but
* the affected bean isn't a prototype
* @throws BeansException if the bean could not be created
*/
Object getBean(String name, Object... args) throws BeansException;
/**
* 和getBean(String name, Object... args)此方法类似,只不过不是指定的bean的名字,而是类型。
*/
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
/**
* 检测此BeanFactory是否包含指定名字的Bean
* 如果给定参数是Bean的别名,它会被转换成其对应的全限定名称。
* 如果实现类中实现的是HierarchicalBeanFactory,在本BeanFactory中找不到的话,会去父BeanFactory中查找。
* 如果在此BeanFactory中有指定名字的Bean,不论该Bean是否是抽象类,也不论此类是否创建好(lazy load)
* 因此即使此方法返回了true,也不表示getBean方法就一定能从容器中得到该name对应的Bean
*/
boolean containsBean(String name);
/**
* 检测指定name的Bean是否是单例的,如果是的话,getBean方法调用,将一直返回同一个引用。
* 但是如果此方法返回了false,并不意味着Bean就一定是单例的,它还有可能是request或者session作用于的
* 如果确实想检测指定bean是否是单例的请使用isPrototype方法
* 支持别名查找
* 支持向父BeanFactory查找
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
/**
* 检测指定name的Bean的scope是否是prototype的。此方法返回ture则Bean一定不是单例,每次调用
* getBean方法都会返回一个新的实例。如果此方法返回false并不代表对应Bean一定是单例,
* 其作用域可能是request或者session的。简单来说就是,想判断一个Bean是单例的话调用isSingleton
* ,想判断是否是prototype的话,调用isPrototype。
* 支持别名查找
* 支持向上查找
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
/**
* 检查给定name的Bean的类型是否匹配指定的类型,更确切的说,检测通过指定参数名字调用getBean方法
* 返回的Bean是否能指定给参数中指定类型的变量
* 支持别名
* 支持向上查找
*/
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
/**
* 和isTypeMatch(String name, ResolvableType typeToMatch)方法功能一样
* 支持别名
* 支持向上查找
*/
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
/**
* 查询指定名字的Bean的类型。如果指定的Bean是FactoryBean的话,则返回FactoryBean创建的对象的类型。
* 类似于FactoryBean的getObjectType
*/
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
/**
* 查询指定名字对应Bean的所有别名。
* 在使用所有这些返回的别名调用getBean方法时,都将返回同一种Bean。
* 如果参数本身就是别名,那么该方法会返回其全限定名和所有的别名,并且,全限定名称在数组的第一位
* 支持向上查找
*/
String[] getAliases(String name);
}