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 ...
随机推荐
- dp周训练 状态压缩
题目链接:题意:给你一个10*10的矩阵,每到一个格子中都要拿一个0-9的数值,求从矩阵左上方走到右下方且必须0-9都经过,拿的数值和最小是多少: #include <iostream> ...
- (Java多线程系列三)线程间通讯
Java多线程间通讯 多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同. 1.使用wait()和notify()方法在线程中通讯 需求:第一个线程写入(input)用户,另一个线程 ...
- css实现动态阴影、蚀刻文本、渐变文本
css实现动态阴影 创建与类似的阴影box-shadow 而是基于元素本身的颜色. 代码实现: <div class="dynamic-shadow-parent"> ...
- Java常考面试题整理(四)
有关所有Swing相关的面试题,都可以说是凑数的,感觉自己在敲这些的时候感觉一点用处都没有,可以从第72条开始看. 61.说出三种支持重绘(painting)的组件. 参考答案: Canvas,Fra ...
- @RepositoryRestResource注解的使用
1.Build with Maven <?xml version="1.0" encoding="UTF-8"?> <project xmln ...
- 1.2 Mac下配置maven环境变量
1.下载JDK http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2.下载Mave ...
- Android Studio设置国内镜像代理
点击主面板右下角的Configure –> settings –> Appearance & Behavior –> System Settings –> HTTP P ...
- 代码实现:输入3个数a,b,c,按大小顺序输出。
import java.util.Arrays; import java.util.Scanner; //输入3个数a,b,c,按大小顺序输出. public class Test34 { publi ...
- Ant Design使用方法
1.antd官网: https://ant.design/docs/react/introduce-cn 2.React中使用Antd 1.安装antd npm install antd --save ...
- flutter 隐藏返回按钮 自定义返回按钮
自定义返回按钮 //改变颜色 Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: BackBu ...