概述
需要对某些 service 方法添加日志和监控报警. 找了好长时间, 添加过程如下:
- 编写
@LogAndWarn
注解 - 编写拦截器
LogAndWarnInterceptor
- 编写切入点配置
LogAndWarnAdviser
- 在对应 Service 类或方法加上
@LogAndWarn
注解, 并测试
编写 @LogAndWarn 注解代码
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAndWarn {
}
编写 LogAndWarnInterceptor 拦截器代码
import org.aopalliance.intercept.MethodInterceptor;
@Component
public class LogAndWarnInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("#### before method");
Object retVal = invocation.proceed();
System.out.println("#### after method");
return retVal;
}
}
注: 此示例代码并没有实现具体逻辑, 详细实现可以参考: https://my.oschina.net/u/1169457/blog/1489767
编写 LogAndWarnAdviser 切入点配置代码
@Component
public class LogAndWarnAdviser extends AbstractPointcutAdvisor {
private static final long serialVersionUID = 1L;
@Autowired
private LogAndWarnInterceptor interceptor;
private final StaticMethodMatcherPointcut pointcut = new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return method.isAnnotationPresent(LogAndWarn.class) || targetClass.isAnnotationPresent(LogAndWarn.class);
}
};
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
@Override
public Advice getAdvice() {
return this.interceptor;
}
}
编写 service 代码, 查看执行结果
service简单这么写:
@LogAndWarn
public void test(){
System.out.println("###### test...");
}
通过 http 请求调用 controller 再调用 service 方法, 控制台输出如下:
#### before method
###### test...
#### after method
参考:
http://blog.javaforge.net/post/76125490725/spring-aop-method-interceptor-annotation
http://todayleave.blogspot.jp/2016/02/spring-methodinterceptor.html https://my.oschina.net/u/1169457/blog/1489767