java编程

Spring的FactoryBean介绍

字号+ 作者:风潇潇 来源:原创 2016-04-25 17:14 我要评论( )

这里使用了FactoryBean,可以说是妙用

这个KeyCenter明明是个复杂的对象,这里给spring之后,我们使用这个类返回给Spring的是这个类的处理对象String类型,在Spring调用getBean的时候会检测一下是不是FactoryBean的实例化,如果是就走调用FactoryBean的getObject()方法;
这种接口spring是想的很周到,适用于这种情况,也许我们并不是要去真正获得这个对象,而只是获得这个对象的处理结果或者其他结果对象

public class KeyCenter implements FactoryBean {

    private String text;
    
    private String keyName;
    
    @Resource
    private Cryptograph cryptograph;
    
    //返回对象
    @Override
    public Object getObject() throws Exception {
        return cryptograph.decrypt(text, keyName);
    }

    //返回对象类型
    @Override
    public Class getObjectType() {
        return String.class;
    }

    //是否是单例
    @Override
    public boolean isSingleton() {
        return false;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setKeyName(String keyName) {
        this.keyName = keyName;
    }
    
    public void setCryptograph(Cryptograph cryptograph) {
        this.cryptograph = cryptograph;
    }

}

下面是BeanFactory的源码解析,
//spring 在getBean之前都会调用一下这个方法
protected Object getObjectForBeanInstance(
                                          Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

                                      //此方法bean标注是FactoryBean却没实现接口,则报错
                                        //在isFactoryDereference 里面可以看到,如果是factoryBean他的name前面会有个&符号,如果有个&

                                      if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
                                          throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
                                      }

                                      //这个bean不是FactoryBean,直接返回
                                      if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
                                          return beanInstance;
                                      }

                                      
                                      Object object = null;
                                      if (mbd == null) {
                                        //获得bean
                                          object = getCachedObjectForFactoryBean(beanName);
                                      }
                                      if (object == null) {
                                          // 强转
                                          FactoryBean factory = (FactoryBean) beanInstance;
                                          // 如果是singleton实例,
                                          if (mbd == null && containsBeanDefinition(beanName)) {
                                              mbd = getMergedLocalBeanDefinition(beanName);
                                          }
                                          boolean synthetic = (mbd != null && mbd.isSynthetic());
                                          //这个方法里就会调用FactoryBean的,当然在调用这个方法之前,还会交给子类处理这个对象
                                          object = getObjectFromFactoryBean(factory, beanName, !synthetic);
                                      }
                                      return object;
                                  }

//getObjectFromFactoryBean方法
    protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {
        if (factory.isSingleton() && containsSingleton(beanName)) {
            synchronized (getSingletonMutex()) {
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
//最终是在这个方法里调用的
                    object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
                    this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                }
                return (object != NULL_OBJECT ? object : null);
            }
        }
        else {
            return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
        }
    }

//doGetObjectFromFactoryBean 方法
private Object doGetObjectFromFactoryBean(
            final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
            throws BeanCreationException {

        AccessControlContext acc = AccessController.getContext();
        return AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                Object object;

                try {
//从factorybean里得到对象
                    object = factory.getObject();
                }
                catch (FactoryBeanNotInitializedException ex) {
                    throw new BeanCurrentlyInCreationException(beanName, ex.toString());
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
                }

          //这里省略了一系列源码…………

                return object;
            }
        }, acc);
    }

这是处于spring的bean里实例化、初始化会设置属性、调用相应的初始化方法,才会处理的上面的逻辑

转载请注明出处。

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • SpringMVC转换Form参数分析

    SpringMVC转换Form参数分析

    2016-03-11 17:00

  • SpringMVC 国际化

    SpringMVC 国际化

    2016-02-26 16:51

  • SpringMVC搭建遇到的坑

    SpringMVC搭建遇到的坑

    2016-01-12 21:35

  • spring <context:component-scan>使用说明

    spring <context:component-scan>使用说明

    2016-02-28 22:30

网友点评
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)