现在的位置: 首页 > 综合 > 正文

spring AOP的异常拦截

2014年03月23日 ⁄ 综合 ⁄ 共 3799字 ⁄ 字号 评论关闭

系统的异常处理机制是衡量一个系统设计的关键因素,良好的异常处理机制能在系统出现异常时准确的找到问题的所在。

spring aop对异常的处理有良好的支持。spring 提供了一个接口 ThrowsAdvice,该接口里面没有任何方法,但是实现类里面必须的实现

afterThrowing(Method method, Object[] args, Object target, RuntimeException  throwable) 或者

afterThrowing(RuntimeException  throwable)

 

如果需要记录发生异常方法的详细信息,则实现第一个方法就行,如果只记录发生的异常,实现第二个方法就ok!

 

那么异常的处理应该在什么位置来做处理呢?

一般我们的系统都应该有以下几个层次:Action--->Service---->DAO

 

DAO负责直接和数据库打交道,也是发生异常频率较高的地方,而service只是调用DAO所提供给外面的接口,action里面大部分的操作也是调用service的服务,再加上少数其他的逻辑,这部分的异常可以单独处理!下面我们主要关心DAO层的异常处理。

 

1、定义接口

    package com.beckham.dao;  
    import java.util.List;  
    import com.beckham.model.User;  
    /** 
     *  @author Owner 
     *  Jan 19, 2010   10:15:32 PM 
     *   
     *  struts2 
     *  com.beckham.dao 
     *  UserDAO.java 
     */  
    public interface UserDAO {  
        public boolean userExsit(String username) throws Exception;  
        public User findById(int id) throws Exception;  
        public List<User> queryUser(String hql,int beginIndex) throws Exception;  
        public void saveUser(User user) throws Exception;  
        public  int gettotalSize(String hql) throws Exception ;  
    }  

2、实现

    package com.beckham.daoimp;  
    import java.util.List;  
    import com.beckham.dao.SuperDAO;  
    import com.beckham.dao.UserDAO;  
    import com.beckham.model.User;  
    import com.beckham.util.PropertyUtil;  
    /** 
     *  @author Owner 
     *  Jan 19, 2010   10:15:50 PM 
     *   
     *  struts2 
     *  com.beckham.daoimp 
     *  UserDAOImp.java 
     */  
    public class UserDAOImp extends SuperDAO implements UserDAO {  
        public User findById(int id) throws Exception {  
            User user = null;  
            try {  
                user = (User) this.getHibernateTemplate().get(User.class, id);  
            } catch (Exception e) {  
                e.printStackTrace();  
                throw new Exception("主键查询用户失败", e);  
            }  
            return user;  
        }  
        public void saveUser(User user) throws Exception {  
            try {  
                this.getHibernateTemplate().save(user);  
            } catch (Exception e) {  
                e.printStackTrace();  
                throw new Exception("增加用户失败", e);  
            }  
        }  
        @SuppressWarnings("unchecked")  
        public List<User> queryUser(String hql, int beginIndex) throws Exception {  
            try {  
                return (List<User>) this.getHibernateTemplate().getSessionFactory()  
                        .getCurrentSession().createQuery(hql).setFirstResult(  
                                beginIndex).setMaxResults(  
                                PropertyUtil.getPageSize()).list();  
            } catch (Exception e) {  
                e.printStackTrace();  
                throw new Exception("查询用户出现异常", e);  
            }  
        }  
        public boolean userExsit(String username) throws Exception {  
            boolean bl = true;  
                String hql = "from User where username='" + username + "'";  
                    if (queryUser(hql, 0).size() == 0) {  
                        bl = false;  
                    }     
            return bl;  
        }  
        public int gettotalSize(String hql) throws Exception {  
            int totalsize = 0;  
            try {  
                totalsize = Integer.parseInt(this.getHibernateTemplate().find(hql)  
                        .get(0).toString());  
            } catch (Exception e) {  
                e.printStackTrace();  
                throw new Exception("查询用户总数失败", e);  
            }  
            return totalsize;  
        }  
    }  

这里需要说明的是,这里的异常我没有细致的分类,都是throws Exception。

 

service层的代码就省略了,因为只是调用DAO层的方法,下面来写异常的拦截

    package com.beckham.aop;  
    import java.lang.reflect.Method;  
    import org.springframework.aop.ThrowsAdvice;  
    /** 
     * @author Owner Jan 18, 2010 2:37:10 PM 处理DAO层的异常 struts2 com.beckham.aop 
     *         ExceptionLog.java 
     */  
    public class ExceptionLog implements ThrowsAdvice {  
        /** 
         * Owner  
         * 参数解释 Method method 执行的方法  
         * Object[] args 方法参数 
         *  Object target 代理的目标对象 
         * Throwable throwable 产生的异常  
         * Jan 18, 2010 3:21:46 PM 
         */  
        public void afterThrowing(Method method, Object[] args, Object target,  
                RuntimeException  throwable) {  
            System.out.println("产生异常的方法名称:  " + method.getName());  
              
            for(Object o:args){  
                System.out.println("方法的参数:   " + o.toString());  
            }  
              
            System.out.println("代理对象:   " + target.getClass().getName());  
            System.out.println("抛出的异常:    " + throwable.getMessage()+">>>>>>>"  
                    + throwable.getCause());  
            System.out.println("异常详细信息:   "+throwable.fillInStackTrace());  
        }  
    }  

最后当然就是在配置文件里面配置了

    <bean id="log" class="com.beckham.aop.LogAdvice"></bean>  
        <bean id="exceptionLog" class="com.beckham.aop.ExceptionLog"></bean>  
        <!-- beanName自动代理 -->  
        <bean id="logAdvice"  
            class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  
            <property name="beanNames">  
                <list>  
                    <value>userDAO</value>  
                </list>  
            </property>  
            <property name="interceptorNames">  
            <list>  
                <value>log</value>  
                <value>exceptionLog</value>  
            </list>  
            </property>  
        </bean>  

到此,通过spring AOP拦截异常就完成了,这里只是拦截DAO层的异常,此方法的好处就是处理异常和功能实现完全分离开,只需要在写方法的时候要记得抛出相应的异常,当出现异常时ThrowsAdvice就会拦截到该异常,并获取该异常的详细信息。

原文地址:http://blog.csdn.net/gaowenming/article/details/5214737

抱歉!评论已关闭.