Spring AOP记录日志信息

 Spring AOP面向切面编程,主要用于日志记录、性能监控、安全检测等

相关术语:

1.切面(Aspect) 适用于类中(@Aspect)

2.连接点(JoinPoint) 一个连接点代表一个方法的执行

3.通知(Advice) 包括 around、before、after 等通知类型,一般都是用拦截器做通知模型(拦截器链)

4.切入点(Pointcut)定义出一个或一组方法,当执行这些方法时可产生通知,Spring缺省使用AspectJ切入点语法

 

通知类型

· 前置通知(@Before):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)

· 返回后通知(@AfterReturning):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回

· 抛出异常后通知(@AfterThrowing):方法抛出异常退出时执行的通知

· 后通知(@After):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)

· 环绕通知(@Around):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型,环绕通知可以在方法调用前后完成自定义的行为,它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行

Spring Aop配置的两种方式:

1.Xml

2.注解

今天介绍记录日志怎么通过AOP实现

1.自定义系统日志注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 
 * 系统日志注解
 * 
 *
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {
	
	String value();
}

2.AOP解析类

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
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 com.my.data.cache.annotation.LogAnnotation;
import com.my.data.cache.consit.SystemConsist;
import com.my.data.cache.domain.Log;
import com.my.data.cache.service.LogService;
import com.my.data.cache.utils.ExceptionUtil;
import com.my.data.cache.utils.SpringWebUtil;


/**
 * 
 * 拦截所有的service方法,系统全局应用日志记录
 */
@Component
@Aspect
public class GlobalLoggerAdvisor {
	
	private static final String LOG_RESULT_SUCCESS = "操作成功";
	private static final String LOG_RESULT_ERROR = "操作失败";
	
	
	@Autowired
	private LogService logService;
	
	@Pointcut("execution(* com.my.data.cache.service.*Service.*(..))")  
    private void aspectjMethod(){}; 
    
    @Around(value = "aspectjMethod()")    
    public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {    
        //调用核心逻辑  
        Object retVal = pjp.proceed();
        
        成功日志记录
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        LogAnnotation logAnnotation = signature.getMethod().getAnnotation(LogAnnotation.class);
        if(logAnnotation != null){
        	String ip = "";
        	String operator = "";
        	if(SpringWebUtil.getRequest() != null){
        		ip = getRemoteAddress(SpringWebUtil.getRequest());
        		if("0:0:0:0:0:0:0:1".equals(ip)){
        			ip = "localhost";
        		}
        		if(SpringWebUtil.getRequest().getSession().getAttribute(SystemConsist.CURRENT_USER) != null){
        			operator = SpringWebUtil.getRequest().getSession().getAttribute(SystemConsist.CURRENT_USER).toString();
        		}
        	}
        	saveLogInfo(ip, 
        			LOG_RESULT_SUCCESS, logAnnotation.value(), operator);
        }
        return retVal;  
    }
    
    @AfterThrowing(value = "aspectjMethod()", throwing = "ex")    
    public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {
    	MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        LogAnnotation logAnnotation = signature.getMethod().getAnnotation(LogAnnotation.class);
    	if(logAnnotation != null){
    		//异常日志记录
    		String ip = "";
        	String operator = "";
        	if(SpringWebUtil.getRequest() != null){
        		ip = getRemoteAddress(SpringWebUtil.getRequest());
        		if("0:0:0:0:0:0:0:1".equals(ip)){
        			ip = "localhost";
        		}
        		if(SpringWebUtil.getRequest().getSession().getAttribute(SystemConsist.CURRENT_USER) != null){
        			operator = SpringWebUtil.getRequest().getSession().getAttribute(SystemConsist.CURRENT_USER).toString();
        		}
        	}
    		saveLogInfo(ip, 
    				LOG_RESULT_ERROR, ExceptionUtil.createStackTrackMessage(ex), operator);
    	}
    } 
    
    private void saveLogInfo(String host, String result, String desc, String operator) {
		Log log = new Log();
		log.setIp(host);
		log.setLogDesc(desc);
		log.setOperator(operator);
		log.setOperateDate(new Date());
        log.setResult(result);
        logService.saveLog(log);
        System.out.println("记录日志成功");
	}
    
    private String getRemoteAddress(HttpServletRequest request) {  
        String ip = request.getHeader("x-forwarded-for");  
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
            ip = request.getHeader("Proxy-Client-IP");  
        }  
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
            ip = request.getHeader("WL-Proxy-Client-IP");  
        }  
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
            ip = request.getRemoteAddr();  
        }  
        return ip;  
    }
	
}
3.日志服务接口

import com.my.data.cache.domain.Log;

public interface LogService {
	
	public void saveLog(Log log);
	
	public void logLoginInfo(String userName, String result);


	
}
4.日志业务实体类
import java.io.Serializable;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;


/**
 * 日志信息
 * 
 */
@Entity
@Table(name = "sys_log")
public class Log implements Serializable{
	private static final long serialVersionUID = 2346530761836619342L;

	@Id
	private String id;

	// 日志描述
	private String logDesc;

	// 操作人
	private String operator;

	// 操作时间
	private Date operateDate;

	// 操作结果
	private String result;

	// IP地址
	private String ip;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getLogDesc() {
		return logDesc;
	}

	public void setLogDesc(String logDesc) {
		this.logDesc = logDesc;
	}

	public String getOperator() {
		return operator;
	}

	public void setOperator(String operator) {
		this.operator = operator;
	}

	public Date getOperateDate() {
		return operateDate;
	}

	public void setOperateDate(Date operateDate) {
		this.operateDate = operateDate;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}


}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值