java Object在实例之后返回null并调用inside方法

时间:2017-06-09 07:33:36

标签: java sqlmap

任何人都可以帮我解决这个问题,我正在使用SQLMap(ibatis)处理java。 我有3个类,MainConfiguration,SQLMap,DBUtility。

  1. 主要配置(此类用于在SQLMap类中设置对象)
  2. 
    public class MainConfiguration
    {
         public static String file = "configuration/db/SQLMapConfig.conf";
    
         public static void main(String[] args) throws Exception
         {
            new MainConfiguration().loadConfiguration();    
         }  
    
         public static void loadConfiguration()
         {
            SQLMap.setMapFile(file);
            List list = DBUtility.loadUsers();
         }
    }
    
    1. SQL Map(此类是getter和setter of and object)
    2. 
      public final class SQLMap
      {
          private static SqlMapClient sqlMap;
      
          public static void setMapFile(String sMapFile)
          {
              try
              {
                  sqlMap = SqlMapClientBuilder.buildSqlMapClient(new FileReader(sMapFile));
              }
              catch (Exception e)
              {
                  throw new RuntimeException("Error initializing SqlMapClient class", e);
              }
          }
      
          public static SqlMapClient getSqlMapInstance()
          {
              return sqlMap;
          }
      }
      
      1. DBUtility(此类是对象实例和从SQLMap类获取对象的地方)

        public class DBUtility
        {
        // object utility
        protected static SqlMapClient sqlMap = SQLMap.getSqlMapInstance();
        
        //constructor
        public DBUtility() throws Exception
        {
        }
        
        public static List loadUsers()
        {
            //it's working
            logger.info("SQLMap Get Instance = " + SQLMap.getSqlMapInstance());
        
            //it's not working
            logger.info("SQLMap Get Instance = " + sqlMap);
        
            //code below will be error because of null sqlMap
            try
            {
                listUser = sqlMap.queryForList("getUsers");
            }
            catch (Exception sqle)
            {
                logger.error("Error on load all user", sqle);
            }
            return listUser;
        }
        }
        
      2. 记录器给我这个:

        SQLMap Get Instance = com.ibatis.sqlmap.engine.impl.SqlMapClientImpl@76707e36

        SQLMap Get Instance = null

        为什么第二个日志会给我null,即使我有实例对象?

1 个答案:

答案 0 :(得分:0)

当加载DBUtility类时,您的字段sqlMap被初始化,这显然发生在SQLMap.setMapFile(file);被调用之前。因此,sqlMap指向不同的内容:静态字段中的null,以及loadUsers()中调用getter时的实际实例。

问题是DBUtility过早查找sqlMap。它必须等到file传递给SQLMap。像这样更改代码以延迟DbUtility.sqlMap的初始化:

public static void loadConfiguration()
{
    SQLMap.setMapFile(file);
    DBUtility.initMapClient();  // notify DBUtility
    List list = DBUtility.loadUsers();
}

public class DBUtility
{
    protected static SqlMapClient sqlMap;  // do not initialize too early

    public static void initMapClient()
    {
        sqlMap = SQLMap.getSqlMapInstance();  // wait for SQLMap to be ready
    }

当然,如果你在DBUtility中甚至没有sqlMap字段,那会更简单。每次需要时都可以致电SQLMap.getSqlMapInstance()。如果实例发生变化,这一点尤为重要:

listUser = SQLMap.getSqlMapInstance().queryForList("getUsers");

阅读When are static variables are initialized?以获取有关静态字段的更详细说明。