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 ...
随机推荐
- Redis——认识
Redis和Memcached比较: https://www.cnblogs.com/JavaBlackHole/p/7726195.html https://blog.csdn.net/lch_20 ...
- C# 选择文件夹 选择文件
选择文件 //选择文件 OpenFileDialog dialog = new OpenFileDialog(); dialog.Multiselect = true;//该值确定是否可以选择多个文件 ...
- MySQ彻底删除与安装配置
彻底删除 1.查看 MySQL 安装了哪些东西 rpm -qa |grep -i mysql 2.卸载 -.el7.x86_64 -.el7.x86_64 .noarch -.el7.x86_64 - ...
- Mongo Cursor
简介 在使用 Java 对数据库进行连接时,都会获取到一个 cursor ,cursor 实际指到的是我们查询数据库的query,而并不是 query 查询到的数据集. 此次在使用 mongo 的 c ...
- [CSP-S模拟测试]:笨小猴(随机化)
题目传送门(内部题118) 输入格式 输入第一行是一个整数$n$,意义如以上所示. 接下来有$2n+1$行,每行为两个正整数,第$i$行的两个正整数分别代表$A_i$和$B_i$. 输出格式 如果无法 ...
- Django日志的配置
做开发离不开日志,以下是我在工作中写Django项目常用的logging配置. BASE_LOG_DIR = os.path.join(BASE_DIR, "log") LOG ...
- 选题 Scrum立会报告+燃尽图 05
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8749 一.小组情况组长:贺敬文组员:彭思雨 王志文 位军营 杨萍队名:胜 ...
- NOIP2010提高组真题部分整理(没有关押罪犯)
目录 \(NOIP2010\)提高组真题部分整理 \(T1\)机器翻译: 题目背景: 题目描述: 输入输出格式: 输入输出样例: 说明: 题解: 代码: \(T2\)乌龟棋 题目背景: 题目描述: 输 ...
- Java代码审计-铁人下载系统
初学 java 代码审计,跟着表哥们脚步,走一遍审计流程,就选了个没有使用 Java 框架的 java 系统,作为入门. 目的是为了熟悉代码审计流程,寻找漏洞的思路,入门记录. 准备工作 为了验证审计 ...
- 阶段3 2.Spring_07.银行转账案例_9 基于子类的动态代理
代理一个普通的java类 导入cglib的包 它还有一个asm的依赖.会自动加进来 创建cglib的文件夹.把proxy里面的Client和Producer复制到cglib文件夹 Producer不实 ...