Spring AOP异常处理

时间:2016-09-19 15:36:07

标签: java spring exception aop spring-aop

我试图检查某些数据库主机是否还活着。 ConfigReader类解析xml文件并获取某些数据库主机的列表。 如果某些主机不可用,我想看到这样的日志:

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>

1 个答案:

答案 0 :(得分:0)

CheckDatabase.runCheckGroup抛出异常并且没有处理,这就是应用程序退出的原因。 使用try / catch调用runCheckGroup并记录异常:

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

与数据库的连接数量有限,因此创建新连接只是为了检查数据库是否存活似乎相当昂贵。 让spring注入所有可用的数据源可能更好:

@Autowire
List<DataSource>dataSources;

这样做的好处是可以自动检查所有已配置的数据源,无需额外配置。

而不是迭代那些,为每个做像

这样的事情
new JdbcTemplate(dataSource).queryForInt("SELECT 1")

检查它的活着。