代码
@Target(ElementType.METHOD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
/* 描述 */
String desc() default "";
}
@Aspect
@Component
public class LogAspct {
@Autowired
private ApplicationContext applicationContext;
/**
* 1、execution 表达式主体
* 2、第1个* 表示返回值类型 *表示所有类型
* 3、某个个包名下的某个类名下的某个方法 *表示全部, 此处:com.hl.springbootdemo.controller包下所有的类中的所有的public方法
* 6、(..) 表示方法参数,..表示任何参数
*/
// @Pointcut("execution(public * com.hl.springbootdemo.controller.*.*(..))")
// public void logPointCut(){}
/**
* 带有@Log的注解的方法
* */
@Pointcut("@annotation(com.hl.springbootdemo.anno.Log)")
public void logPointCut(){}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
try {
Object result = point.proceed();
return result;
}catch (Exception e){
throw e;
}finally {
long endTime = System.currentTimeMillis();
Log aopLog = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(Log.class);
String desc = aopLog.desc();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String uri = request.getRequestURI();
String ip = getIpAddr(request);
// 异步事件
LogAopEvent event = new LogAopEvent(this, desc, endTime - beginTime, ip, uri);
applicationContext.publishEvent(event);
}
}
/**
* 获取请求ip
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request){
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress= inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")>0){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}
}
return ipAddress;
}
}
public class LogAopEvent extends ApplicationEvent {
private String desc;
private long cost;
private String ip;
private String uri;
public LogAopEvent(Object source, String desc, long cost, String ip, String uri) {
super(source);
this.desc = desc;
this.cost = cost;
this.ip = ip;
this.uri = uri;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public long getCost() {
return cost;
}
public void setCost(long cost) {
this.cost = cost;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
}
@Service
public class WriteLogService implements ApplicationListener<LogAopEvent> {
@Override
@Async
public void onApplicationEvent(LogAopEvent event) {
// 此处可以将数据写入数据库或者做其他的操作
System.out.println(event.getIp() + " - " + event.getDesc() + " cost:" + event.getCost());
}
}
@RestController
public class TestController {
@RequestMapping("add")
@Log(desc = "新增用户")
public String addUser(){
String username = "小明";
return "success";
}
}
启动类上增加
@EnableAsync//支持异步
@Aspect //支持切面编程