Spring-系统启动时初始化数据库的数据/系统启动时操作数据库

Spring-系统启动时初始化数据库的数据/系统启动时操作数据库

需求:在系统启动的时候把数据库的数据进行重置(或者插入数据,或者取出一系列的数据缓存起来)

摸索:SBean可以IoC注入需要的资源比如DataSource;

Spring Bean Config
< bean  id ="idPoolsInitilizedProcessor"  class ="utils.IDPoolsInitilizedListener"  scope ="singleton"   >
         < property  name ="datasource"  ref ="dataDS" />
  </ bean >

Spring Bean Code
public  class JcIDPoolsInitilizedListener {
     private DataSource datasource =  null
  
   public JcIDPoolsInitilizedBean() {
    System.out.println("%%%%%%%%%%%%%%");    
     try {
       //initilize  msgid
      String refName = CxcConstants.REFCOUNTER_MSGID; 
      String sql = "update refcounter set nextnumber=(select max(msgid)+1 from msg) where refcounterid=?";
      update(sql,  new Object[]{refName}); 
    }  catch (Exception ex) {
      ex.printStackTrace();
    }
  }
     private  int update(String anSql, Object[] args)  throws Exception {
       int affactRows = 0;
      Connection con =  null;
      PreparedStatement stmt =  null;
       try {
        con = datasource.getConnection();
        stmt = con.prepareStatement(anSql);
        setSQLParams(stmt, args);
        affactRows = stmt.executeUpdate();
         return affactRows;
      }  finally {
         try
           if ( null != stmt) {
            stmt.close();
          }
           if ( null != con) {
            con.close();
          }
        }  catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    }
    
     private  void setSQLParams(PreparedStatement stmt, Object[] args)  throws Exception {
       if ( null != args && 0 < args.length) {
         for ( int i = 0, n = args.length; i < n; i++) {
          stmt.setObject(i + 1, args[i]);
        }
      }
    }

     public DataSource getDatasource() {
       return datasource;
    }

     public  void setDatasource(DataSource datasource) {
       this.datasource = datasource;
    }
}

结果:程序启动的时候会抛出NullPointException,因为 datasource并没有初始化好。

摸索:Spring的事件机制:实现ApplicationListener,在onApplicationEvent的方法进行数据初始化操作,只要容器启动,就会执行这里的代码。

public  class JcIDPoolsInitilizedListener  implements ApplicationListener {
  
   private DataSource datasource =  null
  
   public  void onApplicationEvent(ApplicationEvent argo) {
     // todo: code is same as previous 
  }
    
   // todo: all the other part is same as previous
}

成功。

然后的然后呢?会发现程序中这个初始化被多次调用。
为什么呢? 原因是Listener定义不到位。
为什么呢? 只要是ApplicationEvent都会触发,默认的事件是org.springframework.security.access.event.PublicInvocationEvent,肯定触发的。

怎么办呢?
好吧,既然是Listener,总得告诉它Listen什么Event吧。
第一 定义Listener
public  class JcIDPoolsInitilizedListener  implements ApplicationListener {
  
   private DataSource datasource =  null
  
   public  void onApplicationEvent(ApplicationEvent argo) {
      if  (argo instanceof IDPoolsInitilizedEvent) {
         // todo: code is same as previous 
      }
   
      // todo: all the other part is same as previous
}

第二 定义Event
public  class IDPoolsInitilizedEvent  extends ApplicationEvent{
   private  static  final  long serialVersionUID = 646140097162842368L;
  
   public IDPoolsInitilizedEvent(Object source){
      super(source);
  }
}

第三 定义Event抛出点

public  class IDPoolsInitilizedBean  implements ApplicationContextAware{
   private ApplicationContext applicationContext;
   public  void setApplicationContext(ApplicationContext applicationContext)  throws BeansException {
     this.applicationContext = applicationContext;
    IDPoolsInitilizedEvent event =  new IDPoolsInitilizedEvent("IDPoolsInitilized");
     this.applicationContext.publishEvent(event);
  }
}

第四 定义配置文件
< bean  id ="idPoolsInitilizedListenerProcessor"  class ="utils.IDPoolsInitilizedListenerBean"
        scope
="singleton"   >
         < property  name ="datasource"  ref ="dataDS" />
     </ bean >
     < bean  id ="idPoolsInitilizedProcessor"  class ="utils.IDPoolsInitilizedBean"
        scope
="singleton"   />

你可能感兴趣的:(Spring-系统启动时初始化数据库的数据/系统启动时操作数据库)