什么是AOP、切面编程?想必各位Java Coder早已不陌生,徐叔就不过多解释。直接上代码需要的小伙伴们可以参考。
一、自定义注解
/** * 打印日志注解<br> * 作者:徐承恩<br> * 日期:2016/12/7-17:11<br> */ @Retention(value = RetentionPolicy.RUNTIME) @Target(value = ElementType.METHOD) @Inherited public @interface PrintLog { }
二、添加AspectJ依赖并整合Spring
<!-- AOP注解编程组件 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.9</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency>
整合spring使用注解的方式进行AOP编程
<!-- 注意:子容器可以访问父容器的Bean但父容器不可以访问子容器的Bean。--> <!-- 开启父容器注解 --> <context:annotation-config/> <!-- 开启任务注解 --> <task:annotation-driven/> <!-- 开启AOP注解 --> <aop:aspectj-autoproxy/> <!-- 父容器只扫描@Service、@Repository、@Component的注解 --> <context:component-scan base-package="com.bbc.rec"> <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
三、编写切面类
/** * 打印日志切面类<br> * 作者:徐承恩<br> * 日期:2016/12/7-17:14<br> */ @Aspect public class PrintLogAop { private static final Logger log = LoggerFactory.getLogger(PrintLogAop.class); /** * 返回通知 */ @AfterReturning(value = "execution(@com.bbc.rec.common.annotation.PrintLog * *(..))", returning = "result") public void afterreturning(JoinPoint joinPoint, Object result) { try { Class targetClass = joinPoint.getTarget().getClass(); //将代理类方法转为原始类方法以便拿到注解信息 Method proxyMethod = ((MethodSignature) joinPoint.getSignature()).getMethod(); //原始方法名 Method targetMethod = targetClass.getMethod(proxyMethod.getName(), proxyMethod.getParameterTypes()); //得到参数列表 Object[] params = joinPoint.getArgs(); //得到目标类名 String className = targetClass.getSimpleName(); //得到目标方法名 String methodName = targetMethod.getName(); //得到参数类型 Class[] parmsClass = targetMethod.getParameterTypes(); Map<String, Object> paramsMap = new HashedMap(); for (int i = 0; i < parmsClass.length; i++) { String _className = parmsClass[i].getSimpleName(); Object _param = params[i]; paramsMap.put(_className, _param); } Map<String, Object> map = new LinkedHashMap<String, Object>(); map.put("目标类名", className); map.put("目标方法名", methodName); map.put("请求参数", paramsMap); if (null != result) { Class resultClazz = result.getClass(); //得到返回值类名 String resultClassName = resultClazz.getSimpleName(); map.put("返回值类名", resultClassName); map.put("返回值", result); } log.info("【切面打印日志】{}", JSONObject.toJSONString(map, SerializerFeature.WriteMapNullValue)); } catch (NoSuchMethodException e) { log.error("【切面打印日志异常】【异常栈】", e); } }