Spring AOP 自定義註解實現日誌管理

目錄

一、配置文件

二、新建一個日誌實體類Log

三、編寫 service 層

四、編寫 service 層的實現 serviceimpl

五、自定義註解類

六、編寫切面類

七、spring + aop 需要的 jar 包

八、使用方法


博客的代碼是基於 SSM 環境編寫的,而SSM環境的搭建不是本次的重點,所以還不會的搭建環境的可以看下我另外一篇博客:

eclipse+maven 配置SSM項目環境

一、配置文件

在 spring 的配置中,掃描 aop 的包,還有打開註解掃描。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd" >

    <!-- 掃描 aop 包 -->
    <context:component-scan base-package="com.yyzheng.aop" />
    <!-- 打開註解掃描 -->
    <aop:aspectj-autoproxy proxy-target-class="true" />

</beans>

二、新建一個日誌實體類Log

可根據的需求修改實體類參數。

package com.yyzheng.pojo;

import java.io.Serializable;
import java.util.Date;

public class TLog implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 日誌id
     */
    private Integer id;
    /**
     * 管理員id
     */
    private String adminId;
    /**
     * 管理員姓名
     */
    private String adminName;
    /**
     * 操作
     */
    private String operation;
    /**
     * 操作方法名
     */
    private String method;
    /**
     * 參數
     */
    private String params;
    /**
     * 消耗時間
     */
    private Integer time;
    /**
     * ip地址
     */
    private String ip;
    /**
     * 操作時間
     */
    private Date createTime;

     //省略 get and set 
}

三、編寫 service 層

package com.yyzheng.service;

import com.yyzheng.pojo.TLog;

public interface LogService {
    public void insertLogInfo(TLog log);
}

四、編寫 service 層的實現 serviceimpl

package com.yyzheng.service.impl;

import com.yyzheng.dao.mapping.TLogMapper;
import com.yyzheng.pojo.TLog;
import com.yyzheng.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class LogServiceImpl implements LogService{

    @Autowired
    private TLogMapper tLogMapper;

    @Override
    public void insertLogInfo(TLog log) {
        //這裏調用的是mybatis的逆向工程生成的mapper
        tLogMapper.insert(log);
    }
}

五、自定義註解類

package com.yyzheng.aop;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
    String value() default "";
}

六、編寫切面類

package com.yyzheng.aop;

import java.lang.reflect.Method;
import java.util.Date;

import com.yyzheng.pojo.TAdmin;
import com.yyzheng.pojo.TLog;
import com.yyzheng.service.LogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


/**
 * 系統日誌,切面處理類
 *
 */
@Aspect
@Component
public class SysLogAspect {
	
	@Autowired
	private LogService logService;
	
	@Pointcut("@annotation(com.yyzheng.aop.SysLog)")
	public void logPointCut() {}

	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		long beginTime = System.currentTimeMillis();
		//執行方法
		Object result = point.proceed();
		//執行時長(毫秒)
		int time = (int)(System.currentTimeMillis() - beginTime);
		//保存日誌
		saveSysLog(point, time);
		return result;
	}

    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
        // 獲取當前操作的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        TLog log = new TLog();
        SysLog syslog = method.getAnnotation(SysLog.class);
        if(syslog != null){
            //註解上的描述
            log.setOperation(syslog.value());
        }
        //請求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        log.setMethod(className + "." + methodName + "()");
        // 獲取 ip 地址
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        System.out.println("ip地址:"+request.getRemoteAddr());
        String ip = request.getRemoteAddr();
        log.setIp(ip);
        //請求的參數
        Object[] args = joinPoint.getArgs();
        try{
            String params = args[0].toString();
            log.setParams(params);
        }catch (Exception e){
            e.printStackTrace();
        }
        TAdmin admin = (TAdmin)request.getSession().getAttribute("user");
        if( admin != null){
            log.setAdminId(admin.getAdminId());
            log.setAdminName(admin.getAdminName());
            log.setCreateTime(new Date());
        }

        log.setTime((int)time);

        // 保存日誌
        logService.insertLogInfo(log);
    }
	
}

七、spring + aop 需要的 jar 包

<!-- Spring AOP 日誌管理需要導入的包 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.13</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.18.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.4</version>
        </dependency>
        <!-- 結束 -->

八、使用方法

在需要記錄的方法上打上自定義的註解名字就行:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章