通过对lazy-init处理源码的分析,我们可以看出,如果设置了lazy-init属性,则容器在完成Bean定义的注册之后,会通过getBean方法,触发对指定Bean的初始化和依赖注入过程,这样当应用第一次向容器索取所需的Bean时,容器不再需要对Bean进行初始化和依赖注入,直接从已经完成实例化和依赖注入的Bean中取一个线程的Bean,这样就提高了第一次获取Bean的性能。
3.FactoryBean的实现:
在Spring中,有两个很容易混淆的类:BeanFactory和FactoryBean。
BeanFactory:Bean工厂,是一个工厂(Factory),我们Spring IoC容器的最顶层接口就是这个BeanFactory,它的作用是管理Bean,即实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
FactoryBean:工厂Bean,是一个Bean,作用是产生其他bean实例。通常情况下,这种bean没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他bean实例。通常情况下,bean无须自己实现工厂模式,Spring容器担任工厂角色;但少数情况下,容器中的bean本身就是工厂,其作用是产生其它bean实例。
当用户使用容器本身时,可以使用转义字符”&”来得到FactoryBean本身,以区别通过FactoryBean产生的实例对象和FactoryBean对象本身。在BeanFactory中通过如下代码定义了该转义字符:
StringFACTORY_BEAN_PREFIX = &;
如果myJndiObject是一个FactoryBean,则使用&myJndiObject得到的是myJndiObject对象,而不是myJndiObject产生出来的对象。
(1).FactoryBean的源码如下:
[java]- //工厂Bean,用于产生其他对象 public interface FactoryBean
{ - //获取容器管理的对象实例 T getObject() throws Exception;
- //获取Bean工厂创建的对象的类型 Class getObjectType();
- //Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例 //对象,每次请求都返回同一个实例对象
- boolean isSingleton(); }
(2). AbstractBeanFactory的getBean方法调用FactoryBean:
在第5篇博客我们分析Spring Ioc容器实例化Bean并进行依赖注入过程的源码时,提到在getBean方法触发容器实例化Bean的时候会调用AbstractBeanFactory的doGetBean方法来进行实例化的过程,源码如下:
[java]- //真正实现向IoC容器获取Bean的功能,也是触发依赖注入功能的地方 @SuppressWarnings(unchecked)
- protected
T doGetBean( final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) - throws BeansException { //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
- //如果指定的是别名,将别名转换为规范的Bean名称 final String beanName = transformedBeanName(name);
- Object bean; //先从缓存中取是否已经有被创建过的单态类型的Bean,对于单态模式的Bean整
- //个IoC容器中只创建一次,不需要重复创建 Object sharedInstance = getSingleton(beanName);
- //IoC容器创建单态模式Bean实例对象 if (sharedInstance != null && args == null) {
- if (logger.isDebugEnabled()) { //如果指定名称的Bean在容器中已有单态模式的Bean被创建,直接返回
- //已经创建的Bean if (i