转载;https://blog.csdn.net/ma451152002/article/details/77234236
Jeecg中通过Spring_AOP+注解方式实现日志的管理 一、设计思路 通过spring的aop切面功能,拦截到请求的所有的符合切面表达式的方法,判断是否含有注解标志,生成日志对象,然后通过aop的后置通知进行日志的持久化。 二、代码实现 、工程结构: 、pom.xml增加aop依赖: <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1..RELEASE</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.</version>
</dependency> 、定义我们的Log实体对象
package aop; import java.util.Date; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table; import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.GenericGenerator;
import org.jeecgframework.core.common.entity.IdEntity; @Entity
@Table(name="assess_log_test")
@DynamicInsert(true)
@DynamicUpdate(true)
@SuppressWarnings("serial")
public class Log implements java.io.Serializable{
/**
* 日志id
*/
private String id; /**
* 当前操作人id
*/
private String loginAccount; /**
* 当前操作人ip
*/
private String loginIp; /**
* 操作请求的链接
*/
private String actionUrl; /**
* 执行的模块
*/
private String module; /**
* 执行的方法
*/
private String method; /**
* 执行操作时间
*/
private Long actionTime; /**
* 描述
*/
private String description; /**
* 执行的时间
*/
private Date gmtCreate; /**
* 该操作状态,1表示成功,-1表示失败!
*/
private Short state; @Id
@GeneratedValue(generator = "paymentableGenerator")
@GenericGenerator(name="paymentableGenerator",strategy="uuid")
@Column(name="id",nullable=false,length=)
public String getId() {
return id;
}
@Column(name="login_account",length=)
public String getLoginAccount() {
return loginAccount;
}
@Column(name="login_ip",length=)
public String getLoginIp() {
return loginIp;
}
@Column(name="action_url",length=)
public String getActionUrl() {
return actionUrl;
}
@Column(name="module",length=)
public String getModule() {
return module;
}
@Column(name="method",length=)
public String getMethod() {
return method;
}
@Column(name="action_time")
public Long getActionTime() {
return actionTime;
}
@Column(name="description",length=)
public String getDescription() {
return description;
}
@Column(name="gmt_create")
public Date getGmtCreate() {
return gmtCreate;
}
@Column(name="state")
public Short getState() {
return state;
} public void setId(String id) {
this.id = id;
} public void setLoginAccount(String loginAccount) {
this.loginAccount = loginAccount;
} public void setLoginIp(String loginIp) {
this.loginIp = loginIp;
} public void setActionUrl(String actionUrl) {
this.actionUrl = actionUrl;
} public void setModule(String module) {
this.module = module;
} public void setMethod(String method) {
this.method = method;
} public void setActionTime(Long actionTime) {
this.actionTime = actionTime;
} public void setDescription(String description) {
this.description = description;
} public void setGmtCreate(Date gmtCreate) {
this.gmtCreate = gmtCreate;
} public void setState(Short state) {
this.state = state;
} @Override
public String toString() {
return "Log [id=" + id + ", loginAccount=" + loginAccount
+ ", loginIp=" + loginIp + ", actionUrl=" + actionUrl
+ ", module=" + module + ", method=" + method + ", actionTime="
+ actionTime + ", description=" + description + ", gmtCreate="
+ gmtCreate + ", state=" + state + "]";
} } .定义注解对象
package aop; 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; /**
* 日志记录
*
* @author mgj
* @date 2017-8-11 上午10:53:19
*/
@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
String module() default "";
String methods() default "";
}
.定义aop界面拦截方法
package aop; import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
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.aspectj.lang.reflect.MethodSignature;
import org.jeecgframework.core.util.ResourceUtil;
import org.jeecgframework.core.util.StringUtil;
import org.jeecgframework.web.system.pojo.base.TSUser;
import org.jeecgframework.web.system.service.SystemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import antlr.StringUtils; @Component
@Aspect
public class LogAopAction {
private long BEGIN_TIME;
private long END_TIME;
private Log log = new Log();
@Autowired
private SystemService systemService; //@Pointcut("execution(* vote.backmanage.teachermanage.controller.AssessTeacherInfoController.*(..))")
//@Pointcut("execution(* vote.backmanage.teachermanage.controller.*.*(..))")
//@Pointcut("execution(* vote.backmanage.teachermanage.controller..*.*(..))")
@Pointcut("execution(* vote.backmanage.teachermanage.controller..*.*(..))")
public void controllerAspect(){} @Before("controllerAspect()")
public void doBefore(){
BEGIN_TIME = new Date().getTime();
} @AfterReturning("controllerAspect()")
public void doAfter(){
if (log.getState() == || log.getState() == -) {
log.setActionTime(END_TIME - BEGIN_TIME);
log.setGmtCreate(new Date(BEGIN_TIME)); System.out.println(log);
System.out.println("存入到数据库");
systemService.save(log); }else {
System.out.println(log);
System.out.println("不存到数据库里");
}
}
@After("controllerAspect()")
public void after(){
END_TIME = new Date().getTime();
} @Around("controllerAspect()")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes())
.getRequest();
//获得当前用户
TSUser user = ResourceUtil.getSessionUserName();
String name = user.getRealName();
log.setLoginAccount(name); //拦截的实体类
Object target = pjp.getTarget();
//拦截的方法名
String methodName = pjp.getSignature().getName();
//拦截的方法参数
Object[] args = pjp.getArgs();
//拦截的放参数类型
Signature sig = pjp.getSignature(); MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
} msig = (MethodSignature)sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes(); Object object = null;
Method method = null; try{
method = target.getClass().getMethod(methodName, parameterTypes);
}catch (Exception e) {
e.printStackTrace();
} if (null != method) {
if (method.isAnnotationPresent(SystemLog.class)) {//判断是否包含我们自定义的注解
SystemLog systemlog = method.getAnnotation(SystemLog.class);
log.setModule(systemlog.module());
log.setMethod(systemlog.methods());
log.setLoginIp(getIp(request));
log.setActionUrl(request.getRequestURI()); try {
object = pjp.proceed();
log.setDescription("执行成功");
log.setState((short));
} catch (Exception e) {
log.setDescription("执行失败");
log.setState((short)-);
e.printStackTrace();
} }else {//不包自定义注解
object = pjp.proceed();
log.setDescription("此操作不包含注解");
log.setState((short));
} }else {//不需要拦截
object = pjp.proceed();
log.setDescription("不需要拦截直接运行");
log.setState((short));
} return object;
} /**
* 获得ip地址
* @param request
* @return
* @author mgj
* @date 2017-8-11 下午2:19:51
*/
private String getIp(HttpServletRequest request){
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
} } .增加aop自动扫描配置 ()打开spring-mvc.xml文件,增加aop上下文 如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> ()增加aop自动扫描并实例化bean
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="logAopAction" class="aop.LogAopAction"></bean> .持久化Log实体的xml配置,使用自动扫描class的形式进行配置。打开spring-mvc-hibernate.xml文件,增加<value>aop.</value>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="entityInterceptor" ref="hiberAspect" />
<property name="hibernateProperties">
<props>
<!--<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> -->
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
</props>
</property>
<!-- 注解方式配置 -->
<property name="packagesToScan">
<list>
<value>org.jeecgframework.web.system.pojo.*</value>
<value>org.jeecgframework.web.demo.entity.*</value>
<value>org.jeecgframework.web.test.entity.*</value>
<value>org.jeecgframework.web.cgform.entity.*</value>
<value>org.jeecgframework.web.cgreport.entity.*</value>
<value>aop.</value>
</list>
</property>
</bean> .使用注解方式,配置日志,在访问的controller方法上,增加@SystemLog(module="区教师库登录",methods="区教师库的assessTeacherInfo()方法")配置
/**
* 教师库管理列表 页面跳转
*
* @return
*/
@RequestMapping(params = "assessTeacherInfo")
@SystemLog(module="区教师库登录",methods="区教师库的assessTeacherInfo()方法")
public ModelAndView assessTeacherInfo(HttpServletRequest request) {
return new ModelAndView("vote/backmanage/teachermanage/assessTeacherInfoList");
} .效果 三、注意事项
.增加aop自动扫描包时,必须写到spring-mvc.xml内,不可写到spring-mvc-aop.xml文件中。因为spring-mvc.xml会比spring-mvc-aop.xml文先执行。
.持久化Log实体,使用自动扫描class的形式进行配置时,规则如下
()<value>aop.</value>,会解析为aop/*.class 或者 aop/xxx/*.class。即aop的包以及子包下的所有class。
(2)<value>aop</value>,会解析为aop/*.class 。即aop的包下的所有class。
(3)<value>aop.*</value>,会解析为 aop/xxx/*.class。即aop的子包下的所有class。 四、思考
1.需要深刻理解spring_mvc.xml文件的执行顺序。
2.需要深刻理解使用自动扫描class的形式的配置规则。 --------------------------------------------------------------------------- 附录: Log实体创建的mysql脚本: drop table if exists assess_log_test; create table assess_log_test (
id varchar(32) not null COMMENT '主键id',
login_account varchar(32) default null comment '当前操作人',
login_ip varchar(32) default null comment '登录ip',
action_url varchar(100) default null comment '请求url',
module varchar(32) default null comment '执行模块',
method varchar(32) default null comment '执行方法',
action_time bigint default 0 comment '执行操作时间',
description varchar(200) default null comment '描述',
gmt_create datetime default null comment '执行时间',
state smallint(6) default null comment '操作状态',
primary key (id)
)engine=innodb default charset=utf8 comment '操作日志表';

Jeecg中通过Spring_AOP+注解方式实现日志的管理的更多相关文章

  1. 来一手 AOP 注解方式进行日志记录

    系统日志对于定位/排查问题的重要性不言而喻,相信许多开发和运维都深有体会. 通过日志追踪代码运行状况,模拟系统执行情况,并迅速定位代码/部署环境问题. 系统日志同样也是数据统计/建模的重要依据,通过分 ...

  2. springboot搭建环境之使用@Slf4j注解方式,进行日志管理

    如果不想每次都写private  final Logger logger = LoggerFactory.getLogger(XXX.class); 可以用注解@Slf4j 需要引入依赖为: < ...

  3. spring AOP自定义注解方式实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  4. 浅谈spring中AOP以及spring中AOP的注解方式

    AOP(Aspect Oriented Programming):AOP的专业术语是"面向切面编程" 什么是面向切面编程,我的理解就是:在不修改源代码的情况下增强功能.好了,下面在 ...

  5. Spring中的AOP注解方式和XML方式

    应掌握内容:1. AOP的全名2. AOP的实现原理[静态代理和动态代理]3. 注解方式的配置4. 通知类型     A. 每种通知的特点和使用方式    B. 获取各种数据,方便日后操作5. 执行表 ...

  6. jeecg中dictSelect取值方式

    jeecg中的dictSelect本质是生成了很多input标签和div标签组成的,input存储的对应的就是字典中的code,div存储的就是字典中的name, 下面是取出code和那么的实例: 例 ...

  7. Spring使用注解方式就行事务管理

    使用步骤: 步骤一.在spring配置文件中引入<tx:>命名空间<beans xmlns="http://www.springframework.org/schema/b ...

  8. springAOP注解方式实现日志操作

    通过自定义注解调用方法执行日志存储: package com.zktx.platform.log2; import java.lang.reflect.Method; import java.util ...

  9. 2507-AOP- springboot中使用-使用注解方式

    Springboot中使用aop,与SSM中使用AOP,整体配置与编写方式都是类似的.但是Springboot简化了很多xml配置,切点的表达式可以直接进行javaconfig. 记录一些示例 spr ...

随机推荐

  1. 用MyEclipse将java文件转换成UML类图

    用MyEclipse将java文件转换成UML类图 参考: 用MyEclipse将java文件转换成UML类图 - 君临天下的博客 - CSDN博客  http://blog.csdn.net/dan ...

  2. 简单使用Laravel-admin构建一个功能强大的后台管理

    Laravel-admin可以快速构建一个功能强大的后台,方便快速开发. 以下内容记录简单使用Laravel-admin,以及遇到小错误的解决方法. Laravel-admin 依赖以下环境 需要提前 ...

  3. (转)spring ioc原理(看完后大家可以自己写一个spring)

    原文地址:https://blog.csdn.net/it_man/article/details/4402245 最近,买了本Spring入门书:spring In Action .大致浏览了下感觉 ...

  4. new运算符工作原理(new运算符的伪码实现)

    // 只要函数创建,就有一个prototype属性// 构造函数和普通函数的区别就是调用的时候又没有用 new function Fn() { // this 就是实例化后的对象 三段式 var th ...

  5. NIO浅析(二)

    一:前言 在(一中了解了NIO中的缓冲区和通道),通过本文章你会了解阻塞和非阻塞,选择器,管道 二:完成NIO通信的三要素 * 1.通道(Channel):负责连接* java.nio.channel ...

  6. 2018 ICPC Asia Singapore Regional A. Largest Triangle (计算几何)

    题目链接:Kattis - largesttriangle Description Given \(N\) points on a \(2\)-dimensional space, determine ...

  7. cmd 运行 java 文件

    在安装好jdk 并配置好环境变量的情况下 原因一:没有指定class文件的路径 例如HI是变异好的class文件,并且在d:/RJAZB里面 如果写成 Java HI  则会报错 正确做法 java ...

  8. js基本函数和基本方法

    日期时间函数(需要用变量调用): var b = new Date(); //获取当前时间 b.getTime() //获取时间戳 b.getFullYear() //获取年份 b.getMonth( ...

  9. CSS实现进度条

    进度条经常运用于网页,即使我们意识到不是所有的东西都将瞬间被加载完成,这些进度条用于提醒使用者关于网页上具体的任务进程,譬如上传,下载,加载应用程序等. 以前如果想要创建一个进度条的动画效果,没有使用 ...

  10. babel基础配置

    babel是干什么的 es6语法已经出来很多年,但各家游览器对es6的支持各不相同.为了解决这个问题,babel应运而生. babel支持把es6语法编译成es5,完全兼容各家游览器,避免兼容性问题出 ...