Jeecg中通过Spring_AOP+注解方式实现日志的管理
来源:互联网 发布:matlab2014b for mac 编辑:程序博客网 时间:2024/06/16 16:45
Jeecg中通过Spring_AOP+注解方式实现日志的管理
一、设计思路
通过spring的aop切面功能,拦截到请求的所有的符合切面表达式的方法,判断是否含有注解标志,生成日志对象,然后通过aop的后置通知进行日志的持久化。
二、代码实现
1、工程结构:
2、pom.xml增加aop依赖:<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.5.3</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.4</version> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.4</version> </dependency>3、定义我们的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=32)public String getId() {return id;} @Column(name="login_account",length=32)public String getLoginAccount() {return loginAccount;} @Column(name="login_ip",length=32)public String getLoginIp() {return loginIp;} @Column(name="action_url",length=100)public String getActionUrl() {return actionUrl;} @Column(name="module",length=32)public String getModule() {return module;} @Column(name="method",length=32)public String getMethod() {return method;} @Column(name="action_time") public Long getActionTime() {return actionTime;} @Column(name="description",length=200)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;}@Overridepublic String toString() {return "Log [id=" + id + ", loginAccount=" + loginAccount+ ", loginIp=" + loginIp + ", actionUrl=" + actionUrl+ ", module=" + module + ", method=" + method + ", actionTime="+ actionTime + ", description=" + description + ", gmtCreate="+ gmtCreate + ", state=" + state + "]";}}
4.定义注解对象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)@Documentedpublic @interface SystemLog {String module() default "";String methods() default "";}5.定义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@Aspectpublic class LogAopAction {private long BEGIN_TIME;private long END_TIME;private Log log = new Log();@Autowiredprivate 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() == 1 || log.getState() == -1) {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)1);} catch (Exception e) {log.setDescription("执行失败");log.setState((short)-1);e.printStackTrace();}}else {//不包自定义注解object = pjp.proceed();log.setDescription("此操作不包含注解");log.setState((short)0);}}else {//不需要拦截object = pjp.proceed();log.setDescription("不需要拦截直接运行");log.setState((short)0);}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");}}6.增加aop自动扫描配置(1)打开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/mvchttp://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 ">
(2)增加aop自动扫描并实例化bean
<aop:aspectj-autoproxy proxy-target-class="true" /><bean id="logAopAction" class="aop.LogAopAction"></bean>7.持久化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>
8.使用注解方式,配置日志,在访问的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");}9.效果
三、注意事项
1.增加aop自动扫描包时,必须写到spring-mvc.xml内,不可写到spring-mvc-aop.xml文件中。因为spring-mvc.xml会比spring-mvc-aop.xml文先执行。
2.持久化Log实体,使用自动扫描class的形式进行配置时,规则如下
(1)<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 '操作日志表';
阅读全文
0 0
- Jeecg中通过Spring_AOP+注解方式实现日志的管理
- SpringMVC自定义注解的方式AOP实现 日志管理
- aop注解方式实现全局日志管理
- aop注解方式实现日志管理
- Spring MVC AOP通过注解方式拦截Controller等实现日志管理
- Spring MVC AOP通过注解方式拦截Controller等实现日志管理
- Spring MVC AOP通过自定义注解方式拦截Controller等实现日志管理
- Spring_AOP的实现
- 通过注解实现记录日志的功能
- Spring AOP 自定义注解方式实现实现日志管理
- spring AOP自定义注解方式实现日志管理
- spring AOP自定义注解方式实现日志管理
- spring AOP自定义注解方式实现日志管理 详解
- spring AOP自定义注解方式实现日志管理
- spring AOP自定义注解方式实现日志管理
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- java SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- 第6章 网页解析器和BeautifulSoup第三方插件
- android.os.FileUriExposedException:file:///storage/emulated/0/1502852028434.jpg exposed beyond app t
- css 一列固定一列自适应布局-flex布局实现
- HDU_6127 Hard challenge 【思维】
- img bug 有1px的空白
- Jeecg中通过Spring_AOP+注解方式实现日志的管理
- F
- Android访问网络,使用HttpURLConnection还是HttpClient?
- CSS盒模型
- 搭建开发环境
- 触摸屏驱动-JZ2440
- Java多线程处理任务的封装
- 搜索文本内容——Java代码的简单实现(修改版)
- ztree搜索并且定位到搜索节点