2016-09-19 193 views
0

我想檢查一些數據庫主機是否還活着。 ConfigReader類分析一個xml文件並獲取一些數據庫主機的列表。 我希望看到這樣的日誌,如果某些主機不可用:春天AOP異常處理

running check for host:dbhost1 
Some Exception is ... 
running check for host:dbhost2 
host is alive 

等。

但是我看到這個例外,如果主機不活着。應用程序退出而不是記錄並拋出異常。

#### running check for host:dbhost1 
Exception in thread "main" java.sql.SQLException: Cannot create PoolableConnectionFactory (I/O-Fehler: The Network Adapter could not establish the connection) 
    at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2291) 
    at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2038) 
    at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1533) 
    at com.csinfra.jdbmon.app.CheckDatabase.runCheckGroup(CheckDatabase.java:108) 

這裏是類:

@Component 
public class ScheduleCheck { 
    public ConfigReader configReader; 
    public CheckDatabase checkDatabase; 

    public void runHostCheck() throws Exception { 
     configReader.readConfig(); 
     checkDatabase.setConfigReader(configReader);   
     for(Host host:configReader.getHostMap().values()){    
       System.out.println("#### running check for host:"+host.getId()); 
       checkDatabase.runCheckGroup(host, getCheckFromCheckGroup(host));       
     } 
    } 
} 



@Component 
public class CheckDatabase { 
    public void runCheckGroup(Host host) throws Exception{    
      createConnections(host.getJdbcurl(), host.getJdbcuser(), host.getJdbcpassword(), host.getDriverclassname()); 
      Connection connection_single = jdbcPool.getConnection(); 
      if(connection_single!=null){      
       System.out.println("host is alive"); 
      }       
    } 

    public void createConnections(String url, String username, String password, String driverClassname) throws Exception{ 
      jdbcPool = new BasicDataSource();      
      jdbcPool.setDriverClassName(driverClassname); 
      jdbcPool.setUsername(username); 
      jdbcPool.setUrl(url); 
      jdbcPool.setPassword(password); 
      jdbcPool.setInitialSize(2); 
      jdbcPool.setCacheState(false); 
      jdbcPool.setMaxTotal(2); 
      jdbcPool.setMaxWaitMillis(6000); 
      jdbcPool.setMaxIdle(2); 
      jdbcPool.setDefaultReadOnly(true); 
    } 
} 


@Configurable 
@Aspect 
@Component 
public class AopMethodLogger { 

    private static final Logger LOGGER = RootLogger.getLogger(AopMethodLogger.class); 

    @AfterThrowing(pointcut = "execution(* com.csinfra.app..*.*(..))", throwing = "exception") 
    public void logAfterThrowing(JoinPoint joinPoint, Throwable exception) throws Throwable { 
     LOGGER.debug("Some Exception is "+exception.getLocalizedMessage()); 
     throw exception; 
    } 
} 


<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> 

    <aop:aspectj-autoproxy proxy-target-class="true" /> 
    <context:component-scan base-package="com.csinfra.app /> 

    <bean id="aopMethod" class="com.csinfra.app.log.AopMethodLogger" /> 

    <bean id="scheduleCheck" class="com.csinfra.app.ScheduleCheck"> 
     <property name="configReader" ref="configReader" /> 
     <property name="checkDatabase" ref="checkDatabase" /> 
    </bean> 

    <bean id="checkDatabase" class="com.csinfra.app.CheckDatabase"> 
    </bean> 

</beans> 

回答

0

CheckDatabase.runCheckGroup拋出一個異常,它沒有被處理,這就是爲什麼在應用程序退出。 環繞您的​​通話使用try/catch來runCheckGroup和記錄異常:

try{ 
    checkDatabase.runCheckGroup(host, getCheckFromCheckGroup(host));    
} catch(Exception e){ 
    System.out.println("Exception occured :"+e); 
} 

到數據庫連接的數量是有限的,因此,創建一個新的連接,只是爲了檢查數據庫是活似乎相當昂貴。 這可能是更好地讓春天注入所有可用的數據源:

@Autowire 
List<DataSource>dataSources; 

這還具有以下優點自動檢查所有配置的數據源,無需額外配置。

而不是疊代的,每個做類似

new JdbcTemplate(dataSource).queryForInt("SELECT 1") 

,以檢查它的活着。

+0

嗨Stefan,我想拋出異常,並在AopMethodLogger類中開始一些糾正措施。是否有可能在CheckDatabase和AopMethodLogger類中捕獲異常? – user2683906