BeanFactory:bean的管理者

public interface Aware {
//Aware类超接口标记,表明这个bean能够被spring容器框架的回调式方法通知,
//有且只能有一个方法,并且方法参数只能有一个且没有返回值(void)
//所有BeanFactory的实现类应该支持尽量支持生命周期中的接口
}

  BeanFactory是Spring实现依赖注入的核心接口.提供应用的统一配置注册功能,实现业务开发解偶.使用getBean可以代替单例,原型设计模式.

BeanFactory注释说明

  • 1.它是用于访问Spring bean 的根容器接口,是bean容器的基本客户端视图,例如ListableBeanFactory and ConfigurableBeanFactory  都有特殊作用,都是继承它;
  • 2.持有BeanDefinitions的对象实现了此接口,每一个对象都一个字符串类型的名字来唯一标示;根据BeanDefinition的定义内容,BeanFactory将会返回一个独立的实例(用的原型设计模式), 或者是一个单一的共享实例(一个更好的选择-单例设计模式,该实例在BeanFactory的作用域是单例的)根据BeanFactory API配置返回实例,自Spring2.0之后,根据具体的上下文作用于也不同了,如request和Session作用域
  • 3.BeanFactory是应用组件的注册中心,并能够把这些组件的配置集中处理(例如实例的配置文件不需要它自己读取)通常BeanFactory 加载的BeanDefinition,它的属性都放在配置文件里例如XML文档,spring-beans jar包中类来配置这些beans 它的实现只能是直接用Java代码创建java对象。属性定义的存储呢没有任何限制,LDAP、RDBMS、XML、properties文件都可以,实现类支持引用(即依赖注入) 相比较于ListableBeanFactory的方法,在HierarchicalBeanFactory中所有的操作都需要检验父工厂;此Factory中的所有的Beans需要重写任何父工厂的同名方法
  • 4.所有BeanFactory的实现类应该支持尽量支持生命周期中的接口

具体:

  1、4个获取实例的方法。getBean的重载方法。

  2、4个判断的方法。判断是否存在,是否为单例、原型,名称类型是否匹配。

  3、1个获取类型的方法、一个获取别名的方法。根据名称获取类型、根据名称获取别名。一目了然!

public interface BeanFactory {
 
//&被用作区分FactoryBean创建的实例和创建实例的FactoryBean,例如 myJndiObject 返回的是名为my///JndiObject的FactoryBean 实例,而 &myJndiObject返回的是创建这个
//FactoryBean实例的工厂类的实例
    String FACTORY_BEAN_PREFIX = "&";
//这个方法可以返回BeanFactory不采用单例模式或原型模式创建的对象,如果是单例的bean,
//回调方法可以保留对返回对象的引用,按照约定的bean名称返回别名;
//假如这个bean没找到的话,将会向他的上级工厂找 
    Object getBean(String name) throws BeansException;
    <T> T getBean(String name, Class<T> requiredType) 
                             throws BeansException;
    <T> T getBean(Class<T> requiredType) throws BeansException;
    Object getBean(String name, Object... args) throws BeansException;
    boolean containsBean(String name);
   
    boolean isSingleton(String name);// 是否为单实例
    boolean isPrototype(String name) // 是否为原型(多实例)
    boolean isTypeMatch(String name, Class<?> targetType);// 名称、类型是否匹配
    Class<?> getType(String name) ;// // 获取类型
    String[] getAliases(String name);
}                 

 

 

顶重要的BeanFactory里注释写得太好了.所以咱们先翻译下注释,后面再详细分析.

重点直接看红色标注吧.

 

The root interface for accessing a Spring bean container.
This is the basic client view of a bean container;
further interfaces such as {@link ListableBeanFactory} and
{@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
are available for specific purposes.

访问一个Spring bean容器的根接口。这是一个bean容器的基本客户端视图;  进一步的接口,如{@link ListableBeanFactory}和  {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}  可用于特殊目的。

This interface is implemented by objects that hold a number of bean definitions,
each uniquely identified by a String name. Depending on the bean definition,
the factory will return either an independent instance of a contained object
(the Prototype design pattern), or a single shared instance (a superior
alternative to the Singleton design pattern, in which the instance is a
singleton in the scope of the factory). Which type of instance will be returned
depends on the bean factory configuration: the API is the same. Since Spring
2.0, further scopes are available depending on the concrete application
context (e.g. "request" and "session" scopes in a web environment).

  此接口由持有一些bean定义的对象来实现,每个bean由String字符串唯一标识。根据bean定义,  工厂将返回一个独立对象实例(原型设计模式),或者一个单个共享实例(Singleton设计模式的优雅代替实现,其中该实例是一个factory范围内的单例)。实例的哪种类型将被返回依赖于bean工厂配置:即使API是一样的。从Spring2.0开始,作用域扩展到根据具体的应用上下文,如web环境的request,session。

The point of this approach is that the BeanFactory is a central registry
of application components, and centralizes configuration of application
components (no more do individual objects need to read properties files,
for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and
Development" for a discussion of the benefits of this approach.

 这种方案的关键是,BeanFactory的是应用程序组件注册的中心,同时集中应用程序组件的配置(程序模块不再需要读取诸如properties的配置文件)。这种设计的更多好处讨论详见的<J2EE设计开发编程指南>第4和第11章.

强烈推荐看这本书,就是国内不好买了.

Note that it is generally better to rely on Dependency Injection
("push" configuration) to configure application objects through setters
or constructors, rather than use any form of "pull" configuration like a
BeanFactory lookup. Spring's Dependency Injection functionality is
implemented using this BeanFactory interface and its subinterfaces.

相比诸如 BeanFactory 中查找的pull配置方式,通过setters或者构造方法,依赖注入的方式配置应用对象更好.Spring的依赖注入功能就是通过实现BeanFactory和其子接口实现的.

Normally a BeanFactory will load bean definitions stored in a configuration
source (such as an XML document), and use the {@code org.springframework.beans}
package to configure the beans. However, an implementation could simply return
Java objects it creates as necessary directly in Java code. There are no
constraints on how the definitions could be stored: LDAP, RDBMS, XML,
properties file, etc. Implementations are encouraged to support references
amongst beans (Dependency Injection).

  通常,一个BeanFactory会从配置源(如X​​ML文件)中加载bena 定义,并使用{@code org.springframework.beans}包解析bean。然而,实现可以简单地返回Java代码直接新建的Java对象。这里没有限制bean 定义文件的格式:LDAP,RDBMS,XML.实现类欢迎支持应用而非bean(依赖注入)


In contrast to the methods in {@link ListableBeanFactory}, all of the
operations in this interface will also check parent factories if this is a
{@link HierarchicalBeanFactory}. If a bean is not found in this factory instance,
the immediate parent factory will be asked. Beans in this factory instance
are supposed to override beans of the same name in any parent factory.

 对比{@link ListableBeanFactory}中的方法,如果这是一个{@link HierarchicalBeanFactory},这个接口的全部实现都会查找父工厂.如果在这个工厂实例找不到bean,去直接父工厂查找。factory实例中的bean会覆盖父factory实例中的同名bean。

Bean factory implementations should support the standard bean lifecycle interfaces
as far as possible. The full set of initialization methods and their standard order is:
bean factory 实现类应该尽量支持标准bean的生命周期接口.全套的初始化方法,已经排序如下

感觉这坨概念得好好理理
1. BeanNameAware's {@code setBeanName}
2. BeanClassLoaderAware's {@code setBeanClassLoader}
3. BeanFactoryAware's {@code setBeanFactory}
4. ResourceLoaderAware's {@code setResourceLoader}
(only applicable when running in an application context)
5. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
(only applicable when running in an application context)
6. MessageSourceAware's {@code setMessageSource}
(only applicable when running in an application context)
7. ApplicationContextAware's {@code setApplicationContext}
(only applicable when running in an application context)
8. ServletContextAware's {@code setServletContext}
(only applicable when running in a web application context)
9. {@code postProcessBeforeInitialization} methods of BeanPostProcessors
10. InitializingBean's {@code afterPropertiesSet}
11. a custom init-method definition
12. {@code postProcessAfterInitialization} methods of BeanPostProcessors

On shutdown of a bean factory, the following lifecycle methods apply:
1. DisposableBean's {@code destroy}
2. a custom destroy-method definition

 

BeanFactory与FactoryBean的区别

 BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的的最基本的接口,也就是 Spring IOC 所遵守的最底层和最基本的编程规范。在  Spring 代码中, BeanFactory 只是个接口,并不是 IOC 容器的具体实现,但是 Spring 容器给出了很多种实现,如 DefaultListableBeanFactory 、 XmlBeanFactory 、 ApplicationContext 等,都是附加了某种功能的实现。

 

    一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。
FactoryBean接口对于 Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式:
 一句话:BeanFactory是用来管理beans的,而FactoryBean是用来生成Bean的
 
 
补充:

其中有一段英文注释

Note that it is generally better to rely on Dependency Injectio ("push" configuration) to configure application objects through sette  or constructors, rather than use any form of "pull" configuration like a BeanFactory lookup. Spring's Dependency Injection functionality is implemented using this BeanFactory interface and its subinterfaces. 
少写鄙人理解:Lookup方法注射指容器能够重写容器中bean的抽象或具体方法,返回查找容器中其他bean的结果。 被查找的bean在上面描述的场景中通常是一个non-singleton bean (尽管也可以是一个singleton的)。Spring通过使用CGLIB库在客户端的类之上修改二进制码, 从而实现上述的场景要求。
包含方法注入的客户端类,必须按下面的形式的抽象(具体)定义方法:
protected abstract SingleShotHelper createSingleShotHelper();

 如果方法不是抽象的,Spring就会直接重写已有的实现。在XmlBeanFactory的情况下,你可以使用bean定义中的lookup-method 属性来指示Spring去注入/重写这个方法,以便从容器返回一个特定的bean。

猜你喜欢

转载自jenny-run.iteye.com/blog/2319047