项目中总要发布一下服务供系统内外调用,为了方便排查错误,入参出参都要以日志的形式记录下来。
传统做法:缺点一目了然,参数少的时候只能说还好,参数一多,烦不胜烦,浪费时间。
private static final Logger logger = Logger.getLogger(HelloServiceImpl.class);
public String sayHello(String name,String words) {
logger.info("remote input:name="+name+",words="+words);
//业务逻辑
String result = "Hello"+name+","+words);
logger.info("remote output:result="+result);
return result;
}
于是借鉴了AOP的思想,将日志功能做成一个切面,横向切入到业务逻辑前后(方法开始前和结束后)。
另外,解释一下什么是【基于java.lang.annotation约定】。
由于java的反射是不能获取方法的参数名的,网上有一个第三方工具包JAVAssist提供了现成的方法,但笔者觉得挺麻烦的,决定使用约定优于配置的方式来获取方法的参数名。大家大概猜到是什么了吧?对!就是建一个自定义注解。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AOPLog4jAnnotation {
String paramCollection();
}
在需要日志切面的地方(方法)加上这个注解。
public class HelloServiceImpl implements HelloService{
@Override
@AOPLog4jAnnotation(paramCollection="name,words")
public String sayHello(String name,String words) {
String text = "Hello "+name+"!"+words+".";
return text;
}
}
大家也看到了,笔者的这种方式的明显的缺点:需要按一定规则(把参数按顺序填进去,并用英文逗号隔开)把方法参数名配置在注解中。
@AOPLog4jAnnotation(paramCollection="name,words")
唯一的好处是...只需要复制上面这行,然后遵循规则填写参数名。
唯二的好处是...日志格式统一。
完了,伤心了,感觉实用性不强,哎。
算了,把代码都贴上吧,留着以后改进。
Spring配置:
<bean id="helloService" class="com.aop.log4j.service.impl.HelloServiceImpl" />
<bean id="aspect" class="com.aop.log4j.aspect.HelloAspect"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.aop.log4j.service.HelloService.*(..)))" />
<aop:aspect ref="aspect">
<aop:around pointcut-ref="pointcut" method="arround"/>
</aop:aspect>
</aop:config>
切面代码:
public class HelloAspect {
private static final Logger logger = Logger.getLogger(HelloAspect.class);
private static final String DOT = ".";//点号
private static final String COMMA = ",";//逗号
public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
StringBuilder sb = new StringBuilder();
Object[] paramValues = joinPoint.getArgs();//获取参数值
String[] paramNames = new String[paramValues.length];
Class<? extends Object> invokeClass = joinPoint.getTarget().getClass();
String signatureName = joinPoint.getSignature().getName();
Method methods[] = invokeClass.getMethods();
for (Method method : methods) {
if(method.getName().equals(signatureName)) {
String paramCollection = method.getAnnotation
(AOPLog4jAnnotation.class).paramCollection();//获取注解值
String[] names = paramCollection.split(COMMA);
System.arraycopy(names, 0, paramNames, 0, names.length);
}
}
for (int i = 0; i < paramValues.length; i++) {
sb.append(paramNames[i] + "=" + paramValues[i] + COMMA);
}
//入参日志
logger.info(invokeClass + DOT + signatureName + ",remote input:"
+ sb.toString().substring(0, sb.length() - 1));
try {
Object result = joinPoint.proceed();
//出参日志
logger.info(invokeClass + DOT + signatureName
+ ",remote output:" + result);
return result;
} catch (Exception e) {
logger.error(invokeClass + DOT + signatureName
+ " invoke error");
}
return null;
}
}
调用HelloService服务,输出:
[INFO] 2012-10-03 11:54:29,807 [com.aop.log4j.aspect.HelloAspect.arround] - class com.aop.log4j.service.impl.HelloServiceImpl.sayHello,remote input:name=Java,words=I love you.
[INFO] 2012-10-03 11:54:29,808 [com.aop.log4j.aspect.HelloAspect.arround] - class com.aop.log4j.service.impl.HelloServiceImpl.sayHello,remote output:Hello Java!I love you.
分享到:
相关推荐
java错误-java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Around Spring的AOP需要上述三个jar包
1、基于springboot+mvc+freemarker+aop实现校友信息管理系统源码.zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考...
当添加Studnet的信息的时候实现日志的插入 Spring的AOP实现的日志功能案例.zip Spring的AOP实现的日志功能案例.zip Spring的AOP实现的日志功能案例.zip Spring的AOP实现的日志功能案例.zip Spring的AOP实现的日志...
4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、...
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
学习Spring开发的AOP面向切面编程时所需要的jar包,包括com.springsource.net.sf.cglib-2.2.0.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
Spring AOP 日志管理 实例LoggingThrowsAdvice.java
spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...
import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework....
Java进阶之SpringAOP应用共16页.pdf.zip
描述一下Spring AOP? 在Spring AOP中关注点(concern)和横切关注点(cross-cutting concern)有什么不同? AOP有哪些可用的实现? Spring中有哪些不同的通知类型(advice types)? Spring AOP 代理是什么? 引介...
标签:springframework、spring、aop、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译...
标签:springframework、spring、aop、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...
nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: ...
java springAOP实现数据字典
spring-aop-5.0.0.RELEASE.jar;spring-aop-5.0.0.RELEASE.jar;spring-aop-5.0.0.RELEASE.jar
该压缩包中包含了一个myeclipse6.5下开发的JAVA基于spring实现的日志记载例子,该例子提供了接受切点参数,解析切点返回值,并且都打印出来了,有详细的文档介绍。
顾名思义,Before Advice会在目标对象的方法执行之前被调用,您可以通过实现org.springframework.aop.MethodBeforeAdvice接口来实现Before Advice的逻辑,接口定义如下: java 代码 1. package org.spring...
开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...