springaop日志处理.docx
- 文档编号:24413689
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:19
- 大小:111.07KB
springaop日志处理.docx
《springaop日志处理.docx》由会员分享,可在线阅读,更多相关《springaop日志处理.docx(19页珍藏版)》请在冰豆网上搜索。
springaop日志处理
基于注解的spring-aop日志处理
编写一个简易demo:
1,在maven的pom.xml文件中添加所需jar包
2,创建如下一个日志处理类
/**
*日志记录处理类
*@authordell
*
*/
@Aspect
@Component
publicclassLogerAspect{
//起一个标记作用
@Pointcut("execution(*com.manager.*.service.*.*(..))")
publicvoidlogAspect(){
}
//logAspect()引用上面的标记
@Before(value="logAspect()")
publicsynchronizedvoidbeforeOperateLog(JoinPointjp){
//这里可以做些调用之前的控制操作,比如说权限控制,拦截等
System.out.println(“beforerun….”);
}
@After("logAspect()")
publicsynchronizedvoidaddOperateLog(JoinPointjp){
//这里可以做一些调用之后的处理,如记录日志到数据库
System.out.println(“afterrun….”);
}
}
3,创建一个TeseService接口,以及接口的实现类TestServiceImpl
publicinterfaceTestService{
publicvoidtest();
}
publicclassTestServiceImplimplementTestService{
publicvoidtest(){
System.out.println(“servicerun….”);
}
}
4,在application-context.xml配置文件中添加如下配置
—强制使用cglib的动态代理,据说性能会好一点-->
aspectj-autoproxyproxy-target-class=”true”/> —日志处理类--> --测试service--> 5,创建一个junit单元测试 publicclassTestModel{ ClassPathXmlApplicationContextcontext; TestServiceservice; @Before publicvoidbefore(){ context=newClassPathXmlApplicationContext("application-context.xml"); service=(TestService)context.getBean("testService"); } @Test publicvoidtest(){ service.test(); } } 6,测试运行结果显示: 模拟一个简单的增删改查的日志记录过程 1.首先创建一个描述注解,用与对字段进行描述,后期用得到 /** *注解字段 *@authordell * */ @Target(ElementType.FIELD)//表示该注解只能用于字段 @Retention(RetentionPolicy.RUNTIME) @Documented public@interfaceDescAnnotation{ //描叙 Stringdescription(); } 2.创建一个操作日志注解(这个写的很好,不是我写的) /** * *@authordell * */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Document public@interfaceOperateLoger{ /** *描叙信息 *@return */ Stringcontent()default"无描述信息"; /** *C: 增加R: 查询U: 修改D: 删除 *@authordell * */ enumOperationType{ C,R,U,D,LOGIN_IN,LOGIN_OUT }; OperationTypeoperationType()defaultOperationType.R; /** *U时必须传入原始对象(修改时要有用到,action中必须有getOldBean()方法,也就是先的查询出修改前的对象) *@return */ StringoldObject()default"OldBean"; /** *C,U时候用到,目标对象必须传入值(增加,删除,查询时用到,页面传过来的对象,action中必须有getBean()方法) *@return */ StringtargetObject()default"Bean"; /** *OUT: 通知外部系统,IN: 通知本系统,ALL: 同时通知 *@authordell * */ enumNoticeSystem{ OUT,IN,ALL }; NoticeSystemnoticeSystem()defaultNoticeSystem.ALL; /** *对应的表,多个的话以“,”分割 *@return */ Stringtables()default""; } 3.创建一个操作记录实体类(也不是我写的,字段记录的很全) @Component publicclassOperateRecord{ @DescAnnotation(description="唯一id") privateStringid; @DescAnnotation(description="用户编号") privateStringuserId; @DescAnnotation(description="资源编码") privateStringrsrcCode; @DescAnnotation(description="dict: tab操作类型: C: 新增R: 查询U: 更新D: 删除") privateStringopType; @DescAnnotation(description="操作时间") privateStringopTime; @DescAnnotation(description="操作结果") privateStringopResult; @DescAnnotation(description="操作说明") privateStringopDesc; @DescAnnotation(description="传入参数") privateStringparams; @DescAnnotation(description="修改前内容只记录修改的") privateStringprevContent; @DescAnnotation(description="修改后内容") privateStringcontent; @DescAnnotation(description="记录生成日期") privateDatecreateTime; @DescAnnotation(description="记录最后更新日期") privateDatelastUpdTime; @DescAnnotation(description="客户端ip") privateStringclientIp; //省略gettersetter方法,省略toString方法 } 4.创建一个测试对象 publicclassPersonimplementsCloneable{ privateIntegerid; privateStringname; privateIntegerage; //省略gettersetter以及toString,clone方法 } 5.用java集合创建一个模拟数据库(数据库操作不是这里讨论的重点) /** *模拟一个数据库 *@authordell * */ publicclassDataBase{ privatestaticintid=0; privatestaticList privatestaticList static{ //生成一些测试数据 for(inti=0;i<3;i++){ Personp=newPerson(); p.setId(i); p.setName("名称_"+i); p.setAge(10+i); datas.add(p); } } //下面是模拟数据库的操作 publicstaticPersonget(intindex){ returndatas.get(index); } publicstaticintadd(Personop){ returndatas.add(op)? 1: 0; } publicstaticList returndatas; } publicstaticintupdate(Personperson){ for(inti=0;i if(datas.get(i).getId()==person.getId()){ datas.set(i,person); return1; } } return0; } publicstaticintremove(intindex){ try{ datas.remove(index); return1; }catch(Exceptione){ e.printStackTrace(); return0; } } //往数据库里面添加日志 publicstaticintaddLog(OperateRecordoperateRecord){ try{ logs.add(operateRecord); return1; }catch(Exceptione){ e.printStackTrace(); return0; } } publicstaticList returnlogs; } //用于模拟生成ID publicsynchronizedstaticintgetId(){ returnid++; } 6.修改之前TestService接口以及实现类 publicinterfaceTestService{ publicPersonget(intid); publicList publicintadd(Personerson); publicintupdate(Personperson); publicintdelete(intid); } publicclassTestServiceImplimplementsTestService{ //目标对象(添加,修改时候用到) privatePersonbean; //原始对象(修改时候用到) privatePersonoldBean; @OperateLoger(content="查询单个对象操作",operationType=OperationType.R, noticeSystem=NoticeSystem.IN) publicPersonget(intid){ returnDataBase.get(id); } @OperateLoger(content="查询List操作",operationType=OperationType.R, noticeSystem=NoticeSystem.IN) publicList returnDataBase.list(); } @OperateLoger(content="添加操作",operationType=OperationType.C, noticeSystem=NoticeSystem.ALL) publicintadd(Personperson){ returnDataBase.add(person); } @OperateLoger(content="更改操作",operationType=OperationType.U, noticeSystem=NoticeSystem.ALL) publicintupdate(Personperson){ returnDataBase.update(person); } @OperateLoger(content="删除操作",operationType=OperationType.D, noticeSystem=NoticeSystem.ALL) publicintdelete(intid){ returnDataBase.remove(id); } //省略gettersetter方法 } 7.重点改写LogerAspect日志处理类(涉及到的工具类这里省略) @Aspect @Component publicclassLogerAspect{ @Pointcut("execution(*com.manager.*.service.*.*(..))") publicvoidlogAspect(){ } @Before(value="logAspect()&&@annotation(ol)")//注意这里的变化 publicsynchronizedvoidbeforeOperateLog(JoinPointjp,OperateLogerol){ //记录日志暂时不考虑前置通知…… } @After("logAspect()&&@annotation(ol)") publicsynchronizedvoidaddOperateLog(JoinPointjp,OperateLogerol){ System.out.println("调用后置通知……"); OperateRecordoperateRecord=newOperateRecord(); try{ StringIp=NetworkTools.getIpAddrByRequest(); StringopertionType=ol.operationType().toString(); operateRecord.setId(DataBase.getId()+""); operateRecord.setUserId("userId");//测试时候直接写死一个userid字符串 operateRecord.setRsrcCode(ObjectUtils.getObjectName(jp.getSignature().getDeclaringTypeName())+"_"+jp.getSignature().getName()); operateRecord.setOpType(opertionType); operateRecord.setOpDesc(ol.content()); operateRecord.setOpResult("true"); operateRecord.setClientIp(Ip); operateRecord.setParams(Arrays.toString(jp.getArgs())); operateRecord.setOpTime(newRandom().nextInt(1000)+"");//这里用随机数表示,实际操作时间需要计算 operateRecord.setCreateTime(newDate()); operateRecord.setLastUpdTime(newDate()); //接下来查找更新时候,对象变化的字段 Objectobj=jp.getThis(); ObjecttargetObject=null; Map if(ol.targetObject()! =null&&! "".equals(ol.targetObject())){ MethodtargetMethod=null; try{ targetMethod=obj.getClass().getMethod("get"+ol.targetObject()); }catch(Exceptione){ e.printStackTrace(); } if(targetMethod==null){ //如果没有方法的话,就给个默认的 targetMap=newHashMap }else{ targetObject=targetMethod.invoke(obj); targetObject=AopTargetUtils.getTarget(targetObject); targetMap=ObjectUtils.getObjectValue(targetObject); } } Map Stringdif[]=newString[2]; if("C".equals(opertionType)||"R".equals(opertionType)|| "D".equals(opertionType)){ if(ol.targetObject()! =null&&! "".equals(ol.targetObject())){ dif[1]=ObjectUtils.convertMapToString(targetMap); } dif[0]=""; }else{ MethodoldMethod=obj.getClass().getMethod("get"+ol.oldObject()); ObjectoldObject=oldMethod.invoke(obj); oldObject=AopTargetUtils.getTarget(oldObject); oldMap=ObjectUtils.getObjectValue(oldObject); dif=ObjectUparisonMap(oldMap,targetMap); } operateRecord.setPrevContent(dif[0]); operateRecord.setContent(dif[1]); Stringtables=ol.tables();//受影响的表(其他相关处理) DataBase.addLog(operateRecord);//模拟写入数据库 }catch(Exceptione){ e.printStackTrace(); } } 8.添加单元测试方法 publicclassTestModel{ ClassPathXmlApplicationContextcontext; TestServiceservice; @Before publicvoidbefore(){ context=newClassPathXmlApplicationContext("application-context.xml"); service=(TestService)context.getBean("testService"); } @After publicvoidafter(){ System.out.println("查看日志......"); List for(OperateRecord
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- springaop 日志 处理