Spring MVC 中使用AOP 进行统一日志管理--注解实现
1.AOP简介
AOP称为面向切面编程
AOP的基本概念
(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
(5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
2.为什么要这么做?
AOP最常见的用法是进行日志管理和事务管理。现在我们重点说日志,下一节我们再介绍日志。
加入没使用AOP日志,但是为了日常维护方便和查找错误方便,我们要输入日志的话只能使用log.info()输出,关键是每一个需要日志的地方都要进行重复操作,而且不同的人输出的日志格式或者日志信息不统一,不便于使用。所以,我们使用切面,将日志服务作为一个组件动态地切入到我们需要地方,统一管理。
3.实现
我是在以前搭建的Spring MVC 工程基础上实现的日志功能。
首先在原来的基础上添加
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
这个jar包的版本要和jdk匹配,否则会报错,jdk1.7以上必须使用1.7以上版本,为了避免报错,我直接使用了最高版本的。另外还要保证maven jar 保证有
这两个jar包
4.项目配置
项目配置中特别需要注意的是我是给controller层添加日志服务,而controller层是由Spring MVC 进行管理的,所以我们的日志服务组件也要确保能被spring MVC 扫到,而且要在spring MVC 配置文件中天AOP命名空间的支持,同时开启aop 支持。我之前走了很多弯路,就算因为我把这些配置都写在了spring的配置文件中,导致切面类一直无法生效。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
> <mvc:annotation-driven />
<!-- 扫描controller(controller层注入) -->
<context:component-scan base-package="com.lzl.sss.controller"/> <context:component-scan base-package="com.lzl.sss.aop"/> <aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"> </property>
<property name="suffix" value=".jsp"></property>
</bean> </beans>
5.切面类
package com.lzl.sss.aop; import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; @Component
@Aspect
//定义切面类
public class WebLogAspect {
private Logger logger = LoggerFactory.getLogger(WebLogAspect.class); //定义切入点
@Pointcut("execution(* com.lzl.sss.controller.*.*(..))")
public void log(){ } //定义通知,方法执行前
@Before("log()")
public void doBefore(JoinPoint poin) throws UnsupportedEncodingException{
logger.info("方法执行前,当前时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 记录下请求内容
logger.info("请求URL : " + request.getRequestURL().toString());
logger.info("请求方法 : " + request.getMethod());
logger.info("IP地址 : " + request.getRemoteAddr());
Enumeration<String> enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String name = (String) enu.nextElement();
logger.info("参数:{},值:{}", name,new String(request.getParameter(name).getBytes("ISO-8859-1"),"utf-8"));
} } //定义通知,方法执行后
@After("log()")
public void after(JoinPoint poin){
logger.info("方法执行后,当前时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
} //定义通知,方法返回前
@AfterReturning(pointcut="log()",returning="returnVal")
public void AfterReturning(JoinPoint poin){
logger.info("方法返回前,当前时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
} //定义通知,抛出异常
@AfterThrowing(pointcut="log()",throwing="error")
public void AfterThrowing(Throwable error){
logger.info("方法报错,当前时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
} //定义通知环绕型
@Around("log()")
public Object Around (ProceedingJoinPoint pjp) throws Throwable{
logger.info("环绕前:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
Object obj= pjp.proceed();
logger.info("环绕后:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
return obj;
}
}
切面类有以下几个注意的点:
(1).切点表达式。
第一个*表示匹配任意的方法返回值,..(两个点)表示零个或多个,上面的第一个..表示controller包及其子包,第二个*表示所有类,第三个*表示所有方法,第二个..表示方法的任意参数个数
(2).环绕型通知
环绕型通知在方法执行前后都会执行。且要添加返回类型,否则会导致连接点执行的方法无返回值。
(3).通知类型的执行顺序
正常情况:around--->before--->要执行的方法--->around---->after--->afterReturnning
报错情况下:around--->before--->要执行的方法--->around---->after--->afterThrowing
(4)注解
@Component 注解将类声明为一个组件,并注入到spring MVC 容器中
@Aspect 将这个bean修饰成一个切面类
6.实现效果

Spring MVC 中使用AOP 进行统一日志管理--注解实现的更多相关文章
- Spring MVC 中使用AOP 进行统一日志管理--XML配置实现
1.介绍 上一篇博客写了使用AOP进行统一日志管理的注解版实现,今天写一下使用XML配置实现版本,与上篇不同的是上次我们记录的Controller层日志,这次我们记录的是Service层的日志.使用的 ...
- Spring Boot中使用AOP记录请求日志
这周看别人写的springboot后端代码中有使用AOP记录请求日志,以前没接触过,因此学习下. 一.AOP简介 AOP为Aspect Oriented Programming的缩写,意为:面向切面编 ...
- Spring MVC 中使用AOP 进行事务管理--XML配置实现
1.今天写一篇使用AOP进行事务管理的示例,关于事务首先需要了解以下几点 (1)事务的特性 原子性(Atomicity):事务是一个原子操作,由一系列动作组成.事务的原子性确保动作要么全部完成,要么完 ...
- Spring MVC 中使用AOP 进行事务管理--注解实现
注解实现实现事务管理很简单,和配置式差不多,配置文件的头文件也要加相应的支持.配置数据源,并开启事务管理支持即可. <bean id="transactionManager" ...
- Spring Boot中使用AOP统一处理Web请求日志
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...
- 46. Spring Boot中使用AOP统一处理Web请求日志
在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...
- spring MVC中的异常统一处理
1.spring MVC中定义了一个标准的异常处理类SimpleMappingExceptionResolver 该类实现了接口HandlerExceptionResolver 2.看下SimpleM ...
- 【Java分享客栈】超简洁SpringBoot使用AOP统一日志管理-纯干货干到便秘
前言 请问今天您便秘了吗?程序员坐久了真的会便秘哦,如果偶然点进了这篇小干货,就麻烦您喝杯水然后去趟厕所一边用左手托起对准嘘嘘,一边用右手滑动手机看完本篇吧. 实现 本篇AOP统一日志管理写法来源于国 ...
- Spring MVC中各个filter的用法
转载:http://blog.csdn.net/qyp1314/article/details/42023725 Spring MVC中各个filter的用法 2014-12-19 09:08 105 ...
随机推荐
- layui的数据表格加上操作
数据表格加上操作. <script type="text/html" id="barDemo"> <a class="layui-b ...
- 【LOJ2316】「NOIP2017」逛公园
[题目链接] [点击打开链接] [题目概括] 对给定\(K\),起点\(1\)到终点\(n\)中对长度为\([L,L+K]\)的路径计数. \(L\)为\(1\)到\(n\)的最短路长度. [思路要点 ...
- 试用saucelabs进行浏览器兼容性测试
Hi,all 跟大家分享下saucelabs,一个云测试平台,支持PC和手机(自带的)浏览器的兼容性测试,并且支持selenium/appium的自动化测试,不过是收费的,价格还挺贵,但是人工的测试是 ...
- JavaWeb_JSTL标签数据的存储
菜鸟教程 传送门 JSTL jar包下载 JSTL[百度百科]:(JavaServer Pages Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库 ...
- 为Windows编译libobjc2(通过交叉编译的方式)
前提:Linux系统.git.clang-8.g++-mingw-w64-x86-64.gobjc++-mingw-w64-x86-64. 一.下载源代码 git clone https://gith ...
- mysql索引失效问题
1.两表关联使用的条件字段中字段的长度是否是一致的 2.两表关联使用的条件字段中字段的编码是否是一致的
- 全面解读php-面向对象
一.类的自动载入 //类的自动载入我们使用 spl_autoload_register($autoload_function ).我们需要在不同的地方包含更多不同的类文件,只需要多写几个 $autol ...
- P1070道路游戏题解
日常吐槽 作为hin久hin久以前考试考到过的一道题窝一直咕咕咕到现在才想起来去做因为讲解都忘干净了然后自己重新考虑发现被卡了3天 题面 看到题目发现这题的dp状态似乎有点不是很明确? 我们来理一理题 ...
- 浅谈2-SAT
引入: 相信大家都了解过差分约束系统.差分约束系统的大体意思就是给出一些有某种关系的变量,问你是否有某种赋值使得这些关系全部成立 其实\(2-SAT\)的题目描述和这个很像(虽然解法不一样) 那么\( ...
- LinkedList,ArrayList,Vector,HashMap,HashSet,HashTable之间的区别与联系
在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影!java中集合大家族的成员实在是太丰富了,有常用的ArrayList. ...