Spring AOP的实现记录操作日志
适用场景:
记录接口方法的执行情况,记录相关状态到日志中。
注解类:LogTag.java
package com.lichmama.spring.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogTag {
String value() default "";
}
@Target (使用)注解的目标类型:
CONSTRUCTOR 构造方法声明
FIELD 字段声明(包括枚举常量)
LOCAL_VARIABLE 局部变量声明
METHOD 方法声明
PACKAGE 包声明
PARAMETER 参数声明
TYPE 类、接口(包括注释类型)或枚举声明
@Retention 注解的生命周期(默认CLASS):
CLASS 编译器将把注释记录在类文件中,但在运行时VM 不需要保留注释。
RUNTIME 编译器将把注释记录在类文件中,在运行时VM 将保留注释,因此可以反射性地读取。
SOURCE 编译器要丢弃的注释。
@Documented 标记生成javadoc
切面类:ServiceAspect.java
package com.lichmama.spring.aop; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; import com.lichmama.spring.annotation.LogTag; @Aspect
@Component
public class ServiceAspect { private Log log = LogFactory.getLog(getClass()); @Pointcut("@annotation(com.lichmama.spring.annotation.LogTag)")
private void pointcut() {
} @Before("pointcut()")
public void doBefore(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.getMethod().getName();
String logTag = ((LogTag) signature.getMethod().getAnnotation(LogTag.class)).value();
log.info("before calling " + methodName + ", value: " + logTag);
}
}
@Pointcut("@annotation(com.lichmama.spring.annotation.LogTag)") 标注一个切入点,执行任意带有LogTag注解的方法触发。
业务实现:UserServiceImpl.java
package com.lichmama.spring.service.impl; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.lichmama.spring.annotation.LogTag;
import com.lichmama.spring.dao.IUserDAO;
import com.lichmama.spring.entity.User;
import com.lichmama.spring.service.IUserService; @Service
public class UserServiceImpl implements IUserService { @Autowired
private IUserDAO userDAO; @LogTag
@Override
public User getUserById(int id) {
return userDAO.getUserById(id);
} @LogTag
@Override
public void saveUser(User user) {
userDAO.saveUser(user);
} @LogTag
@Override
public void updateUser(User user) {
userDAO.updateUser(user);
} @LogTag("dangerous operation")
@Override
public void deleteUser(int id) {
userDAO.deleteUser(id);
}
}
spring配置文件:applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> <context:component-scan base-package="com.lichmama.spring.aop" />
<context:component-scan base-package="com.lichmama.spring.dao" />
<context:component-scan base-package="com.lichmama.spring.service" /> <aop:aspectj-autoproxy proxy-target-class="true" />
</beans>
写个测试:
public class TestCase { private Log log = LogFactory.getLog(getClass()); private ApplicationContext ctx; @Before
public void initSpringContext() {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
} @Test
public void testAOP() {
IUserService userService = ctx.getBean(IUserService.class); userService.saveUser(new User(1, "lichmama"));
userService.saveUser(new User(2, "james"));
userService.saveUser(new User(3, "dwyane")); userService.updateUser(new User(2, "bill")); User user = userService.getUserById(2);
log.info(user.toString()); userService.deleteUser(1);
}
}
16:06:22,517 INFO ServiceAspect:29 - before calling saveUser, value:
16:06:22,549 INFO ServiceAspect:29 - before calling saveUser, value:
16:06:22,549 INFO ServiceAspect:29 - before calling saveUser, value:
16:06:22,550 INFO ServiceAspect:29 - before calling updateUser, value:
16:06:22,551 INFO ServiceAspect:29 - before calling getUserById, value:
16:06:22,551 INFO TestSpring:35 - id: 2, name: bill
16:06:22,551 INFO ServiceAspect:29 - before calling deleteUser, value: dangerous operation
Spring AOP的实现记录操作日志的更多相关文章
- 我使用Spring AOP实现了用户操作日志功能
我使用Spring AOP实现了用户操作日志功能 今天答辩完了,复盘了一下系统,发现还是有一些东西值得拿出来和大家分享一下. 需求分析 系统需要对用户的操作进行记录,方便未来溯源 首先想到的就是在每个 ...
- spring aop切面编程实现操作日志步骤
1.在spring-mvc.xml配置文件中打开切面开关: <aop:aspectj-autoproxy proxy-target-class="true"/> 注意: ...
- 使用SpringBoot AOP 记录操作日志、异常日志
平时我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能:我们在操作某些功能时也有可能会发生异常,但是每次发生异常要定位原因我们都要到服务器去查询日志才能找到,而且也不能对发 ...
- 运用Spring Aop,一个注解实现日志记录
运用Spring Aop,一个注解实现日志记录 1. 介绍 我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到 ...
- spring AOP自定义注解方式实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- Appfuse:记录操作日志
appfuse的数据维护操作都发生在***form页面,与之对应的是***FormController,在Controller中处理数据的操作是onSubmit方法,既然所有的操作都通过onSubmi ...
- MVC 记录操作日志与过滤特殊字符
最近进行的MVC系统需要用到记录操作日志和过滤特殊字符的功能,如果每个action中都调用记录日志的方法就太麻烦了,所以根据需要结合mvc的过滤机制 写了个特殊字符验证与记录操作日志的公用类: pub ...
- Tomcat会话超时时怎样记录操作日志,满足安全审计要求
众所周知.在实际的Web应用程序中,会话管理一般都採用Web容器会话管理功能. 使用Tomcat做Webserver也是如此,并且从安全的角度考虑,尽量避免去更改和干预Web容器的会话管理功能. To ...
- Spring aop 记录操作日志 Aspect
前几天做系统日志记录的功能,一个操作调一次记录方法,每次还得去收集参数等等,太尼玛烦了.在程序员的世界里,当你的一个功能重复出现多次,就应该想想肯定有更简单的实现方法.于是果断搜索各种资料,终于搞定了 ...
随机推荐
- Java自学-数组 排序
Java 数组选择法,冒泡法排序 步骤 1 : 选择法排序 选择法排序的思路: 把第一位和其他所有的进行比较,只要比第一位小的,就换到第一个位置来 比较完后,第一位就是最小的 然后再从第二位和剩余的其 ...
- Elasticsearch 主要监控指标 -- 描述了es监控的几个维度,相当不错!
转发自:https://blog.csdn.net/majianxiong_lzu/article/details/90437559 主要指标梳理 Cluster Health – Nodes and ...
- Java 之 Cookie
Cookie 一.会话概述 1.会话:一次会话中包含多次请求和响应. 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止. 2.功能: 在一次会话的范围内的多次请求间 ...
- Kali下的内网劫持(三)
前面两种说的是在Kali下的ettercap工具通过配合driftnet和urlsnarf进行数据捕获,接下来我要说的是利用Kali下的另外一种抓包分析工具——wireshark来进行捕获数据: 首先 ...
- 利用mysql的inet_aton()和inet_ntoa()函数存储IP地址的方法
原文:https://www.jb51.net/article/29962.htm 当前很多应用都适用字符串char(15)来存储IP地址(占用16个字节),利用inet_aton()和inet_nt ...
- Eureka 中服务下线的几种方式
原文:https://blog.csdn.net/qq_15071263/article/details/85276486#1_6 Eureka 中服务下线的几种方式1.直接停掉服务根据默认的策略,如 ...
- metasploit 一款开源的渗透测试框架
渗透神器漏洞利用框架metasploit from: https://zhuanlan.zhihu.com/p/30743401 metasploit是一款开源的渗透测试框架软件也是一个逐步发展与成熟 ...
- 51nod 1115 最大M子段和 V3
环形最大M子段和,N个整数组成的序列排成一个环,a[1],a[2],a[3],…,a[n](a[n-1], a[n], a[1]也可以算作1段),将这N个数划分为互不相交的M个子段,并且这M个子段的和 ...
- Vuex 是什么?
Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变 什么是"状态管 ...
- 微信程序开发之-WeixinJSBridge调用
微信的WeixinJSBridge还是很厉害的,虽然官方文档只公布了3个功能,但是还内置的很多功能没公布,但是存在.今天就好好和大家聊聊 功能1------发送给好友 代码如下: functi ...