spring aop之 xml配置+自定义注解实现日志管理

最近在做ssh项目时,有一个操作日志的功能,我是用xml配置的方式实现的,在这里做一下记录:

创建日志注解

package com.zking.crm.aop;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 操作日志注解
 * @author lenovo
 * @date 2018年12月27日 10:03:08
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
    //对操作的描述
	String action() default "";
}

创建切面通知类

package com.zking.crm.aop;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import com.opensymphony.xwork2.ActionContext;
import com.zking.crm.biz.ILogBiz;
import com.zking.crm.entity.User;

public class OperationLogAspect{
	private ILogBiz iLogBiz; 
	public ILogBiz getiLogBiz() {
		return iLogBiz;
	}
	public void setiLogBiz(ILogBiz iLogBiz) {
		this.iLogBiz = iLogBiz;
	}
	/**
	 * 环绕通知
	 * @param pjp
	 * @return
	 */
	public Object around(ProceedingJoinPoint pjp){
		try {
			//开始时间
			long beginTime = System.currentTimeMillis();
			//执行目标方法
			Object proceed = pjp.proceed();
			//执行时长 (毫秒)
			long time = System.currentTimeMillis()-beginTime;
			saveSystemLog(pjp, proceed, time);
			return proceed;
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 保存日志
	 * @param joinPoint
	 * @param time
	 */
	private void saveSystemLog(ProceedingJoinPoint joinPoint, Object proceed, long time) {
		/*	得到request对象
		 * HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		 *	
		 * 	得到response对象
		 *	HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE);
		 */
		//得到session
		Map<String,Object> session =  (Map<String,Object>)ActionContext.getContext().getSession();
		//得到session中当前登录的用户
		Object obj = session.get("ActiveUser");
		 MethodSignature signature = (MethodSignature) joinPoint.getSignature();
	     Method method = signature.getMethod();
	     Map<String, String[]> sysLogMap = new HashMap<>();
	     /**
	      * 下面为我的日志表字段
	      * log_id		日志id(主键)
			operate_user	操作的用户
			operate_do	操作的动作
			log_method	操作调用的方法
			log_params	操作方法的参数
			operate_time	操作耗时
			operate_create_date	日志操作的时间
			operate_flag	操作是否成功(1、成功, 2、失败)
	      */
	     SystemLog sysLog = method.getAnnotation(SystemLog.class);
	     if(sysLog!=null) {
	    	 // 注解上的描述
	    	 sysLogMap.put("operate_do", new String[] {sysLog.action()});
	     }
	    // 获取目标类名
        String className = joinPoint.getTarget().getClass().getName();
        
        // 获取方法名
        String methodName = signature.getName();
        sysLogMap.put("log_method", new String[] {className+"."+methodName});

        // 请求的参数
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length != 0 && args[0] != null) {
        	sysLogMap.put("log_params", new String[] {Arrays.toString(args)});
        }
        //由于登录时,session中是不存在当前的登录用户,所以取用请求参数中登录的用户名
        if(obj!=null) {
	    	 User user=(User)obj;
	    	 sysLogMap.put("operate_user", new String[] {user.getUser_name()});
	     }else {
	    	 sysLogMap.put("operate_user", new String[] {((User)args[0]).getUser_name()});
	     }
        sysLogMap.put("operate_time", new String[] {time+""});
        if(proceed!=null && proceed!="0") {
        	sysLogMap.put("operate_flag", new String[] {"1"});
        }else {
        	sysLogMap.put("operate_flag", new String[] {"2"});
        }
        // 保存系统日志
        iLogBiz.addLog(sysLogMap);
	};
}

 AspectJ配置文件

    <bean id="logDao" class="com.zking.crm.dao.LogDao" parent="baseDao"></bean>
	<bean id="logBiz" class="com.zking.crm.biz.impl.LogBizImpl">
		<property name="ld" ref="logDao"></property>
	</bean>
	<!-- 切面类 -->
	<bean id="operationLogAspect" class="com.zking.crm.aop.OperationLogAspect">
		<property name="iLogBiz" ref="logBiz"></property>
	</bean>
	<aop:config>
		<!-- 切面 -->
		<aop:aspect ref="operationLogAspect">
			<!-- 定义切点 -->
			<aop:pointcut expression="@annotation(com.zking.crm.aop.SystemLog)" id="pt"/>
			<!-- 声明环绕通知 -->
			<aop:around method="around" pointcut-ref="pt"/>
		</aop:aspect>
	</aop:config>

 在AspectJ配置文件中定义了切点的切入位置为加了@SystemLog注解的方法中(即标有@SystemLog注解的方法才会保存到数据库中)

效果

猜你喜欢

转载自blog.csdn.net/qq_41097820/article/details/85307389