当前位置:首页 > 服务端 > 浅入java架构-Aspect-日志处理

浅入java架构-Aspect-日志处理

2022年09月16日 14:16:21服务端4

浅入java架构-Aspect-日志处理

很多的架构师,或者高级程序员在面试新人的时候,都会在架构方面问一个非常常见且十分经典的知识:那就是怎样设计系统日志输出程序。毫无疑问,面试官想了解面试者的spring中aspect的编程思想及在程序的运用,从而了解面试者在以前的项目当中所担任的项目角色和所做的事情范围。

闲话少说,今天笔者就spring中aspect,也就是面向切面编程,与广大java爱好者一起探讨下,在项目中日志打印的设计;

六个步骤即可完成日志打印:

一、定义注解(annocation):AutoLogMethod

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

二、定义注解(annocation):MethodParam

@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.PARAMETER})
@Documented
@Component
public @interface MethodParam{
	String value() default "param->";
}

三、创建日志输入工具类:LogUtil

public class LogUtil {
	private static final Logger logger = LoggerFactory.getLogger(LogUtil.class);
	public static void error(final String message) {
		if (logger != null) {
			logger.error(message);
		} else {
			System.err.printf("ERROR: %s\n", message);
		}
	}
	public static void error(final String message, final Throwable t) {
		if (logger != null) {
			logger.error(message, t);
		} else {
			String err = message  + "\r\n" + ExceptionUtils.getRootCauseMessage(t);
			System.err.printf("ERROR: %s\n", err);
		}
	}
	public static void error(String message, Throwable t, Object... obj) {
		String err = String.format(message, obj) ;
		error(err,t);
	}
	
	public static void info(final String message) {
		if (logger != null) {
			logger.info(message);
		} else {
			System.err.printf("INFO: %s\n", message);
		}
	}

	public static void info(String message, Object... obj) {
		info(String.format(message, obj));
	}
}

四、创建切面(Aspect):LogAspect

    (1)、引入Aspectj所需相关jar支持

                 pom.xml

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

    (2)、spring管理启动Aspectj,这只自动启动

                <aop:aspectj-autoproxy proxy-target-class="true"/>

    (3)、创建切面(Aspect):LogAspect

                注意:因为是日志打印处理,所以给该切面的优先级设置最高,即@Order(-1)

@Aspect
@Component
@Order(-1)
public class LogAspect {

	@Pointcut("@annotation(com.jd.jr.hd.jsf.common.annocation.AutoLogMethod)")
	public void autoLog() {
	}

	@Around(value = "autoLog()")
	public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable {
		Field filed = pjp.getClass().getDeclaredField("methodInvocation");
		filed.setAccessible(true);
		Object methodInvocation = (Object) filed.get(pjp);

		Method method = methodInvocation.getClass().getMethod("getMethod");
		Method m = (Method) method.invoke(methodInvocation);
		String mn = pjp.getTarget().getClass().getName() + '.' + m.getName();
		AutoLogMethod autoLogMethod = m.getAnnotation(AutoLogMethod.class);
		StringBuffer sb = new StringBuffer();
		if (autoLogMethod != null) {
			Annotation annotation[][] = m.getParameterAnnotations();
			for (int i = 0; i < pjp.getArgs().length; i++) {
				String paramName = null;
				for (Annotation a : annotation[i]) {
					if (a.annotationType() == MethodParam.class) {
						paramName = ((MethodParam) a).value();
						break;
					}
				}
				if (paramName != null) {
					sb.append('[').append(paramName);
					sb.append(':');
					sb.append(pjp.getArgs()[i] == null ? "" : pjp.getArgs()[i].toString()).append(']');
				}
			}
			LogUtil.info("autoLog %s --> %s请求	%s", mn, autoLogMethod == null ? "" : autoLogMethod.value(), sb.toString());
		}
		try {
			Object retVal = pjp.proceed();
			LogUtil.info("autoLog %s --> %s响应	%s", mn, autoLogMethod == null ? "" : autoLogMethod.value(), retVal);
			return retVal;
		} catch (Throwable t) {
			LogUtil.error(String.format("autoLog %s --> %s异常	%s", mn, autoLogMethod == null ? "" : autoLogMethod.value(), sb.toString()), t);
			throw t;
		}
	}
}

五、创建一个服务供测试调用:LogService

@Service
public class LogService {
	
	@AutoLogMethod(value = "autoLogTest")
	public void autoLogTest(@MethodParam("参数") LoginReq req) throws ServiceException {
		System.out.println("----------------------autoLogTest打印成功!-----------------------");
	}
	
	public String logTest(String name) {
		System.out.println("----------------------logTest打印成功!-----------------------");
		return name+"返回了";
	}
}

六、创建JUnit测试启动类:LogTest.autoLogtest()

@Service
public class LogService {
	
	@AutoLogMethod(value = "autoLogTest")
	public void autoLogTest(@MethodParam("参数") LoginReq req) throws ServiceException {
	    if("".equals(req.getUserId())) {
            throw new ServiceException("-1", "用户名不能为空");
        }
        if("".equals(req.getPassword())) {
            throw new ServiceException("-2", "密码不能为空");
        }
		System.out.println("----------------------autoLogTest打印成功!-----------------------");
	}
	
	public String logTest(String name) {
		System.out.println("----------------------logTest打印成功!-----------------------");
		return name+"返回了";
	}
}


作者:lin777lin
来源链接:https://blog.csdn.net/lin777lin/article/details/80691757

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/42043.html

分享给朋友:

“浅入java架构-Aspect-日志处理” 的相关文章

No enclosing instance of type JDStudent is acAcessible. Must qualify the allocation with an enclosin

No enclosing instance of type JDStudent is acAcessible. Must qualify the allocation with an enclosin

No enclosing instance of type JDStudent is acAcessible. Must qualify the allocation with an enclosing instance of type JDStudent (e.g. x.new A() wher...

python实现——处理Excel表格(超详细)

python实现——处理Excel表格(超详细)

目录 xls和xlsx 基本操作 1:用openpyxl模块打开Excel文档,查看所有sheet表 2.1:通过sheet名称获取表格...

【python】函数用法详解(一)

【python】函数用法详解(一)

✅作者简介:大家好我是姐姐划船吗?让我们一起共同进步吧!🏆 📃个人主页:姐姐划船吗? 🔥系列专栏:学会python,逆天改命 💖如果觉得博主的文章还不错的话,请点赞👍+收藏⭐️+留言📝支持一下博主哦🤞 💬格言:静坐要辨己过,闲谈莫论人非🔥 学习目标:   &nbs...

软件工程复习要点

软件工程复习要点

软件工程复习 一、填空题 二、选择题 三、简答题 8.根据一学期的学习,谈谈你对软件工程学科的认识。...

[C#]richtextbox实现拖放

namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeCo...

[C#][控件]常用控件命名规范

Data Control AccessDataS...

[C#][控件]列表控件listbox(一)

1. 常用属性列表:    SelectionMode    组件中条目的选择类型,即多选(Multiple)、单选(Single)    Rows    ...

计算机组成原理考试复习

计算机组成原理考试复习

计算机组成原理考试复习 第一章(计算机系统概论) 第二章(运算方法和运算器) 第三章(存储系统) 第四章(指令系统) 第五章(中央处理器)...

centos7中 yum的安装

centos7中 yum的安装

自己误将yum卸载, 在重装时由于依赖问题一直报错: error: Failed dependencies:     /usr/bin/python is ne...

CentOS7搭建本地YUM仓库,并定期同步阿里云源

CentOS7同步阿里云镜像rpm包并自建本地yum仓库 系统环境 # cat /etc/centos-release CentOS Linux release 7.6.1810 (Core) # uname -r 3.10.0-957.e...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。