Spring Aop+Log4j 动态日志

困扰了两天的Spring Aop+log4j动态日志Demo.

实现的功能:SSH框架,对Action/Service/Dao 三层的方法使用Spring Aop进行日志的添加(排除Action内的set get方法等)

遇到的问题:

      Action层使用Spring Aop添加日志后,竟然获取不到前台提交的参数(就是这个问题困扰了太久,其它很 简单,service dao层的方法 都能正常)

 问题解决方案以及注意事项

      1).将Aop配置为 proxy-target-class="true"(基于类的代理)

      2).若设置 proxy-target-class="true",需要导入cglib相关包, 但不要导入cglib jar包,而应该使用cglib-nodep  jar包, 譬如我用的是 cglib-nodep-2.2.3.jar.  用cglib jar包,会报异常: Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(Z)V

     3).Struts2的action 需交给Spring容器去管理

相关的代码

 1.Log类

package com.miao.log;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;


public class MyLog {
	Logger logger = Logger.getLogger(MyLog.class);
	String logStr = null ;
	
	
	/**
	 * 前置通知:在某连接点之前执行的通知,但这个通知不能阻止连接点前的执行
	 */
	public void doBefore(JoinPoint jp) {	
		logStr = jp.getTarget().getClass().getName() + " 类的 "
				+ jp.getSignature().getName()+" 方法开始执行 ***Start***";
		logger.info(logStr);
	}
	
	
    /**
     * 环绕通知:包围一个连接点的通知,可以在方法的调用前后完成自定义的行为,也可以选择不执行
     */
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
    	
    	Object result=null;
		try{  
			result = pjp.proceed();  
		}catch(Exception e){  
			logStr = "方法:"+pjp.getTarget().getClass() + "." + pjp.getSignature().getName()+ "()  ";
			logStr = logStr+"错误信息如下:["+e+"]";
			logger.info(logStr); 
		}
  
        return result;
    }
    
    
    /**
     * 后置通知
     */
    public void doAfter(JoinPoint jp) {
    	logStr =jp.getTarget().getClass().getName() + " 类的 "
    			+ jp.getSignature().getName() +" 方法执行结束 ***End***"; 
    	logger.info(logStr);
    }
    
    
}

2.Spring Aop日志相关配置

<!-- 
	    配置日志 使用Aop 记录日志  
	    注意:
		1). 此处proxy-target-class="true" 否则Action内的参数会被拦截掉,导致action内无法获得前台传递的参数 
		2). Action需交给spring容器去管理
	-->
	<aop:config expose-proxy="true" proxy-target-class="true">
	    <aop:aspect  id="aopRiZhiAspect" ref="myRiZhi"> 
	    <!-- 对哪些方法进行日志记录, 此处屏蔽action内的set get方法 -->
            <aop:pointcut id="aopRiZhi" expression="(execution(* com.miao.*.*.*.*(..)) ) and (!execution(* com.miao.*.action.*.set*(..)) ) and (!execution(* com.miao.*.action.*.get*(..)) )" />  
            <aop:before pointcut-ref="aopRiZhi" method="doBefore"/>  
            <aop:after pointcut-ref="aopRiZhi" method="doAfter"/>  
            <aop:around pointcut-ref="aopRiZhi" method="doAround"/>  
        </aop:aspect>
	</aop:config>


	<beans>
		<bean id="myRiZhi" class="com.miao.log.MyLog"></bean>	<!-- Aop日志类 -->
		<bean id="logonAction" class="com.miao.logon.action.LogonAction" scope="prototype" ></bean>	<!-- 要使用spring aop记录日志的action 需要交给spring容器来管理 -->
	</beans>

3.log4j配置, Struts配置等略, 注意需要的jar包即可,附件是去掉jar包后的项目

  

相关推荐