Java aop面向切面编程访问日志

1.Java aop面向切面编程访问日志

1.1需要使用的jar包

aspect包或者aspectjweaver包

1.2需要配置spring文件

在spring-jdbc.xml中

 <!-- 设置扫描目录 -->
    <context:component-scan base-package="com.ssm" /> 
      
      <aop:aspectj-autoproxy proxy-target-class="true" />

1.3配置aop日志的相关文件

1.3.1注解类

@Target({ElementType.METHOD,ElementType.PARAMETER})
public @interface SysServiceAop {
    String sysAopType() default "";

    String sysAopRemark()default  "";
}

1.3.2注解实现类

/**
 * @Auther: cpb
 * @Date: 2018/6/11 14:48
 * @Description:日志操作。可以直接使用Service保存
 */

@Aspect // 该注解标示该类为切面类
@Component // 注入依赖
public class SysServiceAopAspect {

    private  static String restUrl;

    private static  final Logger logger = LoggerFactory.getLogger(SysServiceAop.class);

    private static String[] types = { "java.lang.Integer", "java.lang.Double",
            "java.lang.Float", "java.lang.Long", "java.lang.Short",
            "java.lang.Byte", "java.lang.Boolean", "java.lang.Char",
            "java.lang.String", "int", "double", "long", "short", "byte",
            "boolean", "char", "float" };

    //定义切点位置这种定位方式需要在spring中配置位置需要在spring中配置
    /**
     *
     <aop:config>
     <aop:pointcut id="serviceMethods" expression="execution(* com.ssm.web.service..*(..))"/>
     <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods"/>
     </aop:config>
     */
    @Pointcut("@annotation(SysServiceAop)")
    public void serviceAop(){

    }

    @AfterReturning(value="serviceAop()",returning="object")
    public void doAfterReturning(JoinPoint joinPoint,Object object){
        SysOprlog sysOprlog = getSysOprlogInfo(joinPoint);
        sysOprlog.setOprlogStatus("1");
        saveSysOprlog(sysOprlog);
    }
    /**
     * 异常通知 用于拦截service层记录异常日志
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "serviceAop()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
        String className = joinPoint.getTarget().getClass().getName();// 获取所在实体类
        String methodName = joinPoint.getSignature().getName();// 获取方法名
        logger.error("执行失败!"+className+"->"+methodName+"失败原因:" + e.getMessage());
        SysOprlog sysOprlog = getSysOprlogInfo(joinPoint);
        sysOprlog.setOprlogRemark("异常方法:"+className+"->"+methodName+",原因:"+e.getMessage());
        sysOprlog.setOprlogStatus("0");
        saveSysOprlog(sysOprlog);
    }

    /**
     * 获取SysOprlog的属性内容
     * @param joinPoint
     * @return
     */
    private SysOprlog getSysOprlogInfo(JoinPoint joinPoint){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpSession session = request.getSession();
        // 读取session中的用户
        SysUserEntity user = (SysUserEntity) session.getAttribute("user");
        // 请求的IP
        //String ip = request.getRemoteAddr();

        String className = joinPoint.getTarget().getClass().getName();// 获取所在实体类
        String methodName = joinPoint.getSignature().getName();// 获取方法名

        SysOprlog sysOprlog = new SysOprlog();
        try {
            String paramContent = getLogParamContent(getFieldsName(this.getClass(), className, methodName), joinPoint);
            //获取注解描述
            SysServiceAop systemServiceLog = getServiceMethodDescription(joinPoint);
            sysOprlog.setOprlogId(UUID.randomUUID().toString());
            sysOprlog.setOprlogParam(paramContent);
            sysOprlog.setOprlogRemark(systemServiceLog.sysAopType());
            sysOprlog.setOprlogTime(new Date());
            sysOprlog.setOprlogType(systemServiceLog.sysAopRemark());
            sysOprlog.setOprlogUserId(user.getUserId().toString());
            sysOprlog.setOprlogUserName(user.getUsername());

        } catch (Exception e) {
            // 记录本地异常日志
            logger.error("获取失败!失败原因:" + e.getMessage());
        }
        return sysOprlog;
    }

    /**
     * 获取注解中对方法的描述信息,用于service层注解
     * @param joinPoint 切点
     * @return 方法描述
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    private SysServiceAop getServiceMethodDescription(JoinPoint joinPoint) throws Exception {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();

        SysServiceAop systemServiceLog = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                    systemServiceLog = method.getAnnotation(SysServiceAop.class);
                    break;
                }
            }
        }
        return systemServiceLog;
    }

    /**
     * 获取调用方法参数的名称
     * @param cls
     * @param clazzName
     * @param methodName
     * @return
     * @throws NotFoundException
     */
    @SuppressWarnings("rawtypes")
    private String[] getFieldsName(Class cls, String clazzName, String methodName) throws NotFoundException{
        ClassPool pool = ClassPool.getDefault();
        ClassClassPath classPath = new ClassClassPath(cls);
        pool.insertClassPath(classPath);

        CtClass cc = pool.get(clazzName);
        CtMethod cm = cc.getDeclaredMethod(methodName);
        MethodInfo methodInfo = cm.getMethodInfo();
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
        if (attr == null) {
            // exception
        }
        String[] paramNames = new String[cm.getParameterTypes().length];
        int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
        for (int i = 0; i < paramNames.length; i++){
            paramNames[i] = attr.variableName(i + pos); //paramNames即参数名
        }
        return paramNames;
    }

    /**
     * 获取日志参数内容。格式:参数名+参数内容
     * @param paramNames
     * @param joinPoint
     * @return
     */
    private String getLogParamContent(String[] paramNames, JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        StringBuilder sb = new StringBuilder();
        boolean clazzFlag = true;
        for(int k=0; k<args.length; k++){
            Object arg = args[k];
            sb.append(paramNames[k]);
            // 获取对象类型
            String typeName = arg.getClass().getName();
            for (String t : types) {
                if (t.equals(typeName)) {
                    sb.append("=" + arg+";");
                }
            }
            if (clazzFlag) {
                sb.append(getFieldsValue(arg));
            }
        }
        return sb.toString();
    }

    /**
     * 得到参数的值
     * @param obj
     */
    private String getFieldsValue(Object obj) {
        Field[] fields = obj.getClass().getDeclaredFields();
        String typeName = obj.getClass().getName();
        for (String t : types) {
            if(t.equals(typeName))
                return "";
        }
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (Field f : fields) {
            f.setAccessible(true);
            try {
                for (String str : types) {
                    if (f.getType().getName().equals(str)){
                        sb.append(f.getName() + " = " + f.get(obj)+"; ");
                    }
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        sb.append("]");
        return sb.toString();
    }

    /**
     * rest请求存储操作日志在这里可以直接调用日志dao直接保存
     * @param sysOprlog
     */
    private void saveSysOprlog(SysOprlog sysOprlog){
        AjaxResponse response = new AjaxResponse();
        response.setSuccess(false);
        response.setMessage("保存操作日志失败!");
        Map<String, String> map = ConvertUtils.convertModelToMapWithDateFormat(sysOprlog, false, null);
        HttpResponseResult responseResult = HttpClientUtils.post( restUrl+ "/sysOprLog/saveOprLog", map);
        if(responseResult.getCode() == 200) {
            String msg = responseResult.getMsg();
            try {
                response = JSON.parseObject(msg, AjaxResponse.class);
            } catch (Exception e) {
                logger.error("保存操作日志失败!rest调用返回的结果转换为实体失败,失败原因:" + e.getMessage());
            }
        }else{
            logger.error("保存操作日志失败!失败原因:" + responseResult.getMsg());
        }
    }


}



猜你喜欢

转载自blog.csdn.net/c_royi/article/details/80756694
今日推荐