转载;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. JS-jQuery:百科

    ylbtech-JS-jQuery:百科 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQu ...

  2. jmeter3.0启动时报错误 “unable to access jarfile apachejmeter.jar“

    jdk环境也配置好了.但启动时报错.才发现jmeter3.0的bin目录下没有这个.jar文件.复制了一份放到这个目录下就不报这个错了.

  3. Redis 单机模式,主从模式,哨兵模式(sentinel),集群模式(cluster),第三方模式优缺点分析

    Redis 的几种常见使用方式包括: 单机模式 主从模式 哨兵模式(sentinel) 集群模式(cluster) 第三方模式 单机模式 Redis 单副本,采用单个 Redis 节点部署架构,没有备 ...

  4. 2019牛客多校第五场B-generator 1(矩阵快速幂)

    generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...

  5. PHP实现RSA2加密

    PHP实现RSA2加密 1. 需要开启php的 php_openssl扩展 <?php /* * RSA2签名 * @param array 请求的参数 * @param string 私钥 * ...

  6. 转 Jmeter业务请求比例

    [转载]Jmeter业务请求比例1   ps:文章转自订阅号“测试那点事儿”,链接:https://mp.weixin.qq.com/s/qVD4iNO0QqRIwAIq9_E_Kw   方法二: 可 ...

  7. The Accomodation of Students HDU - 2444 二分图判定 + 二分图最大匹配 即二分图-安排房间

    /*655.二分图-安排房间 (10分)C时间限制:3000 毫秒 |  C内存限制:3000 Kb题目内容: 有一群学生,他们之间有的认识有的不认识.现在要求把学生分成2组,其中同一个组的人相互不认 ...

  8. void v.s. void *

    在學校老師一定都會教void是無型態的返回值例如 void swap(int *a, int *b){      int temp = *a;      *a = *b;      *b = temp ...

  9. 关于UEditor的使用配置(图片上传配置)

    接到新需求,需要在平台上使用富文本编辑器,我这次选择了百度的UEditor 在官网上下载l.net版本的1.4.3开发版本 http://ueditor.baidu.com/website/downl ...

  10. Java中this的基础用法

    update on 2019-07-07 在Java核心技术一书中看到调用方法时this作为隐式参数传入的. 突然间许多问题都懂了 比如:方法的多态 父类变量指向子类对象的引用 对象变量指向的实际类型 ...