SpringAop+注解 实现 日志记录
起因
对于aop和注解都只是处于了解的状态,并没有在项目中使用过这些技术,最近这段时间偶然看别人的项目的源码的时候发现了人家自定义的一套日志系统,只需要在方法上打上注解就可以实现日志记录的作用,可以自己选择保存到文件还是存入数据库。
思考
通过以上这种实现,还可以实现的有权限系统(接口级别).(暂时只能想到这么多>~<)...
实现
话不多说,来进行基础实现
pom文件
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<!-- aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
其中aop包是主要用的,MVC相关包就不用多说了。
controller
@RestController
@Slf4j
public class LogController {
@GetMapping("/log")
@LogAnno(opertion = "打印日志:{1}")
public String getLog(String msg){
log.info("打印:"+msg);
return msg;
}
}
注解类
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnno {
/**
* 操作
* @return
*/
String opertion() default "";
/**
* 是否保存
* @return
*/
boolean isSave() default true;
}
配置切面
@Slf4j
@Aspect
@Component
public class LogAspect {
/**
* 配置要扫描的注解切面
*/
@Pointcut(value = "@annotation(cn.wm.demo_aspectlog.annotation.LogAnno)")
public void pointcut() {
}
/**
* 配置环绕方法
* @param point
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object process(ProceedingJoinPoint point) throws Throwable {
// 1.方法执行前的处理,相当于前置通知
//---------doSomething----------//
// 2.方法执行
Object result = point.proceed();
try {
handle(point);
} catch (Exception e) {
log.error("日志出错!",e);
}
return result;
}
private void handle(ProceedingJoinPoint point) throws Exception {
// 获取方法
Method currentMethod = AspectUtil.INSTANCE.getMethod(point);
//获取操作名称
// 获取方法上面的注解
LogAnno logAnno = currentMethod.getAnnotation(LogAnno.class);
// 获取操作描述的属性值
boolean save = logAnno.isSave();
String bussinessName = AspectUtil.INSTANCE.parseParams(point.getArgs(), logAnno.opertion());
String ua = RequestUtil.getUa();
if (!save) {
return;
}
log.info("{} | {} | {} | {} | {}", bussinessName, RequestUtil.getIp(), RequestUtil.getMethod(), RequestUtil.getRequestUrl(), ua);
}
}
相关工具类
AOP相关的工具
public enum AspectUtil {
INSTANCE;
/**
* 获取当前切面执行的方法的方法名
*
* @param point 当前切面执行的方法
*/
public Method getMethod(JoinPoint point) throws NoSuchMethodException {
// Signature sig = point.getSignature();
// MethodSignature msig = (MethodSignature) sig;
// Object target = point.getTarget();
// return target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
// 获取方法签名
MethodSignature methodSignature = (MethodSignature) point.getSignature();
// 获取方法
return methodSignature.getMethod();
}
public String parseParams(Object[] params, String name) {
if (name.contains("{") && name.contains("}")) {
List<String> result = RegexUtils.match(name, "(?<=\\{)(\\d+)");
for (String s : result) {
int index = Integer.parseInt(s);
name = name.replaceAll("\\{" + index + "}", JSON.toJSONString(params[index - 1]));
}
}
return name;
}
}
IP工具类
public class IpUtil {
/**
* 获取真实IP
*
* @param request
* @return
*/
public static String getRealIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
return checkIp(ip) ? ip : (
checkIp(ip = request.getHeader("Proxy-Client-IP")) ? ip : (
checkIp(ip = request.getHeader("WL-Proxy-Client-IP")) ? ip :
request.getRemoteAddr()));
}
public static String getRealRealIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
/**
* 校验IP
*
* @param ip
* @return
*/
private static boolean checkIp(String ip) {
return !StringUtils.isEmpty(ip) && !"unknown".equalsIgnoreCase(ip);
}
}
正则表达式工具类
public class RegexUtils {
/**
* @param regex
* 正则表达式字符串
* @param str
* 要匹配的字符串
* @return 如果str 符合 regex的正则表达式格式,返回true, 否则返回 false;
*/
public static List<String> match(String str, String regex) {
if (null == str) {
return null;
}
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
List<String> list = new LinkedList<>();
while (matcher.find()) {
list.add(matcher.group());
}
return list;
}
public static boolean checkByRegex(String str, String regex) {
if (null == str) {
return false;
}
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
return matcher.find();
}
}
request工具类
public class RequestUtil {
public static String getParameters() {
HttpServletRequest request = RequestHolder.getRequest();
if (null == request) {
return null;
}
Enumeration<String> paraNames = request.getParameterNames();
if (paraNames == null) {
return null;
}
StringBuilder sb = new StringBuilder();
while (paraNames.hasMoreElements()) {
String paraName = paraNames.nextElement();
sb.append("&").append(paraName).append("=").append(request.getParameter(paraName));
}
return sb.toString();
}
public static Map<String, String[]> getParametersMap() {
HttpServletRequest request = RequestHolder.getRequest();
if (null == request) {
return new HashMap<>();
}
return request.getParameterMap();
}
public static String getHeader(String headerName) {
HttpServletRequest request = RequestHolder.getRequest();
if (null == request) {
return null;
}
return request.getHeader(headerName);
}
public static String getReferer() {
return getHeader("Referer");
}
public static String getUa() {
return getHeader("User-Agent");
}
public static String getIp() {
HttpServletRequest request = RequestHolder.getRequest();
if (null == request) {
return null;
}
return IpUtil.getRealIp(request);
}
public static String getRequestUrl() {
HttpServletRequest request = RequestHolder.getRequest();
if (null == request) {
return null;
}
return request.getRequestURL().toString();
}
public static String getMethod() {
HttpServletRequest request = RequestHolder.getRequest();
if (null == request) {
return null;
}
return request.getMethod();
}
public static boolean isAjax(HttpServletRequest request) {
if (null == request) {
request = RequestHolder.getRequest();
}
if (null == request) {
return false;
}
return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"))
|| request.getParameter("ajax") != null;
}
}
RequestHolder
@Slf4j
public class RequestHolder {
/**
* 获取request
*
* @return HttpServletRequest
*/
public static HttpServletRequest getRequest() {
log.debug("getRequest -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
if (null == servletRequestAttributes) {
return null;
}
return servletRequestAttributes.getRequest();
}
/**
* 获取Response
*
* @return HttpServletRequest
*/
public static HttpServletResponse getResponse() {
log.debug("getResponse -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
if (null == servletRequestAttributes) {
return null;
}
return servletRequestAttributes.getResponse();
}
/**
* 获取session
*
* @return HttpSession
*/
public static HttpSession getSession() {
log.debug("getSession -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
HttpServletRequest request = null;
if (null == (request = getRequest())) {
return null;
}
return request.getSession();
}
/**
* 获取session的Attribute
*
* @param name session的key
* @return Object
*/
public static Object getSession(String name) {
log.debug("getSession -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
if (null == servletRequestAttributes) {
return null;
}
return servletRequestAttributes.getAttribute(name, RequestAttributes.SCOPE_SESSION);
}
/**
* 添加session
*
* @param name
* @param value
*/
public static void setSession(String name, Object value) {
log.debug("setSession -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
if (null == servletRequestAttributes) {
return;
}
servletRequestAttributes.setAttribute(name, value, RequestAttributes.SCOPE_SESSION);
}
/**
* 清除指定session
*
* @param name
* @return void
*/
public static void removeSession(String name) {
log.debug("removeSession -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
if (null == servletRequestAttributes) {
return;
}
servletRequestAttributes.removeAttribute(name, RequestAttributes.SCOPE_SESSION);
}
/**
* 获取所有session key
*
* @return String[]
*/
public static String[] getSessionKeys() {
log.debug("getSessionKeys -- Thread id :{}, name : {}", Thread.currentThread().getId(), Thread.currentThread().getName());
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
if (null == servletRequestAttributes) {
return null;
}
return servletRequestAttributes.getAttributeNames(RequestAttributes.SCOPE_SESSION);
}
}