• spring的FactoryBean


    (以下内容翻译自spring/docs/3.2.18.RELEASE)

    为具有工厂属性的对象实现FactoryBean接口。

    FactoryBean接口是spring IoC 容器实例化逻辑的一点补充。
    如果你有一个复杂的对象,更适合用java代码描述而不是xml,你可以创建自己的FactoryBean,
    并在类中写复杂的实例化代码,然后把自定义的FactoryBean加入到spring容器中。

    示例:

    <bean id="myBean" class="com.dao.MyFactoryBean"></bean>
    public class ComplexObj {
        public Date date;
        
        public ComplexObj() {
            System.out.println("ComplexObj construtcor");
        }
    }
    public class MyFactoryBean implements FactoryBean<ComplexObj> {
        public MyFactoryBean() {
            System.out.println("MyFactoryBean constructor");
        }
        
        @Override
        public ComplexObj getObject() throws Exception {
            ComplexObj obj = new ComplexObj();
            obj.date = new Date();
            return obj;
        }
    
        @Override
        public Class<?> getObjectType() {
            return ComplexObj.class;
        }
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    }

    getBean("myBean");    //返回FactoryBean创建的对象
    getBean("&myBean"); //返回FactoryBean对象自身

    Object bean = appCtx.getBean("myBean");
    System.out.println(bean);
    Object bean2 = appCtx.getBean("&myBean");
    System.out.println(bean2);

    1. spring容器创建MyFactoryBean的调用栈,就是一个普通单例bean的创建过程:

    2. 创建工厂产品的调用栈:

    AbstractBeanFactory

    // AbstractBeanFactory
    protected <T> T doGetBean(
            final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {
    
        final String beanName = transformedBeanName(name);
        Object bean;
    
        // Eagerly check singleton cache for manually registered singletons.
        Object sharedInstance = getSingleton(beanName);
        //获取工厂的产品对象,走if分支
        // sharedInstance是MyFactoryBean对象
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        else {
            ...
        }
    
        // Check if required type matches the type of the actual bean instance.
        if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
            try {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type [" +
                            ClassUtils.getQualifiedName(requiredType) + "]", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

    延伸:dubbo的ReferenceBean实现了FactoryBean接口,所以启动consumer的时候,只会创建一个FactoryBean,

    并不会去创建invoker代理,只有在触发getBean("xxx")操作时,才会真正去创建invoker代理。

    public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean {}
  • 相关阅读:
    Asp.Net MVC4 系列--进阶篇之路由 (2)
    Asp.Net MVC4 系列-- 进阶篇之路由(1)
    ASP.NET MVC AJAX的调用示例
    MVC中Controller控制器相关技术
    MVC中View界面数据呈现示例
    IEnumerable,ICollection,IList,List之间的区别
    Dapper数据库相关操作
    集合类---Map
    工厂模式
    适配器模式与外观模式
  • 原文地址:https://www.cnblogs.com/allenwas3/p/8413069.html
Copyright © 2020-2023  润新知