源代码如下:public class SqlMapClientFactoryBean
    implements FactoryBean, InitializingBean
{    public static LobHandler getConfigTimeLobHandler()
    {
        return (LobHandler)configTimeLobHandlerHolder.get();
    }    public SqlMapClientFactoryBean()
    {
        useTransactionAwareDataSource = true;
        transactionConfigClass = com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig.class;
        transactionConfigProperties = new Properties();
        transactionConfigProperties.setProperty("SetAutoCommitAllowed", "false");
    }    public void setConfigLocation(Resource configLocation)
    {
        this.configLocation = configLocation;
    }    public void setSqlMapClientProperties(Properties sqlMapClientProperties)
    {
        this.sqlMapClientProperties = sqlMapClientProperties;
    }    public void setDataSource(DataSource dataSource)
    {
        this.dataSource = dataSource;
    }    public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource)
    {
        this.useTransactionAwareDataSource = useTransactionAwareDataSource;
    }    public void setTransactionConfigClass(Class transactionConfigClass)
    {
        if(transactionConfigClass == null || !(com.ibatis.sqlmap.engine.transaction.TransactionConfig.class).isAssignableFrom(transactionConfigClass))
        {
            throw new IllegalArgumentException("Invalid transactionConfigClass: does not implement com.ibatis.sqlmap.engine.transaction.TransactionConfig");
        } else
        {
            this.transactionConfigClass = transactionConfigClass;
            return;
        }
    }    public void setTransactionConfigProperties(Properties transactionConfigProperties)
    {
        this.transactionConfigProperties = transactionConfigProperties;
    }    public void setLobHandler(LobHandler lobHandler)
    {
        this.lobHandler = lobHandler;
    }    public void afterPropertiesSet()
        throws Exception
    {
        if(configLocation == null)
            throw new IllegalArgumentException("configLocation is required");
        if(lobHandler != null)
            configTimeLobHandlerHolder.set(lobHandler);
        java.io.InputStream is = configLocation.getInputStream();
        sqlMapClient = sqlMapClientProperties == null ? SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader(is)) : SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader(is), sqlMapClientProperties);
        if(dataSource != null)
        {
            TransactionConfig transactionConfig = (TransactionConfig)transactionConfigClass.newInstance();
            DataSource dataSourceToUse = dataSource;
            if(useTransactionAwareDataSource && !(dataSource instanceof TransactionAwareDataSourceProxy))
                dataSourceToUse = new TransactionAwareDataSourceProxy(dataSource);
            transactionConfig.setDataSource(dataSourceToUse);
            transactionConfig.initialize(transactionConfigProperties);
            applyTransactionConfig(sqlMapClient, transactionConfig);
        }
        if(lobHandler != null)
            configTimeLobHandlerHolder.set(null);
        break MISSING_BLOCK_LABEL_198;
        Exception exception;
        exception;
        if(lobHandler != null)
            configTimeLobHandlerHolder.set(null);
        throw exception;
    }    protected void applyTransactionConfig(SqlMapClient sqlMapClient, TransactionConfig transactionConfig)
    {
        if(!(this.sqlMapClient instanceof ExtendedSqlMapClient))
        {
            throw new IllegalArgumentException("Cannot set TransactionConfig with DataSource for SqlMapClient if not of type ExtendedSqlMapClient: " + this.sqlMapClient);
        } else
        {
            ExtendedSqlMapClient extendedClient = (ExtendedSqlMapClient)this.sqlMapClient;
            transactionConfig.setMaximumConcurrentTransactions(extendedClient.getDelegate().getMaxTransactions());
            extendedClient.getDelegate().setTxManager(new TransactionManager(transactionConfig));
            return;
        }
    }    public Object getObject()
    {
        return sqlMapClient;
    }    public Class getObjectType()
    {
        return sqlMapClient == null ? com.ibatis.sqlmap.client.SqlMapClient.class : sqlMapClient.getClass();
    }    public boolean isSingleton()
    {
        return true;
    }    private static ThreadLocal configTimeLobHandlerHolder = new ThreadLocal();
    private Resource configLocation;
    private Properties sqlMapClientProperties;
    private DataSource dataSource;
    private boolean useTransactionAwareDataSource;
    private Class transactionConfigClass;
    private Properties transactionConfigProperties;
    private LobHandler lobHandler;
    private SqlMapClient sqlMapClient;}关键是:afterPropertiesSet方法,spring的会调用此方法完成此factoryBean的组装

解决方案 »

  1.   

    还不是很明白,看了源代码,就是不知道spring是怎么操作的
      

  2.   

    public class SqlMapClientFactoryBean
        implements FactoryBean, InitializingBean
    =====================================================
    这个class实现了两个interface:FactoryBean和InitializingBean
    ==============================================================================================
    InitializingBean只有一个方法afterPropertiesSet()
    spring调用构造函数后,发现它实现了InitializingBean接口,所以还会调用afterPropertiesSet来进一步初始化此class。
    sqlMapClient 就是在这里面创建的。
    至此一个完整的工厂创建完成。
    ==============================================================================================
    FactoryBean接口主要方法就是public Object getObject();
    要知道SqlMapClientFactoryBean是一个工厂类,他的作用就是你需要的时候调用它的一个方法,它就会返回你一个你需要的对象。
    当然此处返回的就是一个sqlMapClient 对象。
    所以这里的getObject实现就是把sqlMapClient 返回给调用者。
    spring就是根据接口里的定义来调用getObject方法的,这样可以忽略到底是调用的那个对象的实例(也就是不关心调用的是哪个factory)。
    也不关心返回的是什么对象,spring只知道调用了getObject就可以得到此factory所创建的对象就够了。 public Object getObject()
        {
            return sqlMapClient;
        }
    =================================================================================================================public interface FactoryBean
    {    public abstract Object getObject()
            throws Exception;    public abstract Class getObjectType();    public abstract boolean isSingleton();
    }public interface InitializingBean
    {    public abstract void afterPropertiesSet()
            throws Exception;
    }