1、springaop日志处理基于注解的spring-aop日志处理编写一个简易demo:1, 在maven的pom.xml文件中添加所需jar包org.springframeworkspring-context3.0.5.RELEASEorg.aspectjaspectjweaver1.6.11junitjunit4.8.2test2, 创建如下一个日志处理类/* * 日志记录处理类 * author dell * */AspectComponentpublic class LogerAspect /起一个标记作用 Pointcut(execution (* com.manager.*.serv
2、ice.*.*(.) public void logAspect() /logAspect() 引用上面的标记 Before(value = logAspect() public synchronized void beforeOperateLog(JoinPointjp) /这里可以做些调用之前的控制操作,比如说权限控制,拦截等 System.out.println(“before run.”); After(logAspect() public synchronized void addOperateLog(JoinPointjp) /这里可以做一些调用之后的处理,如记录日志到数据库 Sy
3、stem.out.println(“after run.”); 3, 创建一个TeseService接口,以及接口的实现类TestServiceImplpublic interface TestService public void test();public class TestServiceImpl implement TestService public void test() System.out.println(“service run.”);4, 在application-context.xml 配置文件中添加如下配置 5, 创建一个junit单元测试public class Te
4、stModel ClassPathXmlApplicationContext context; TestService service; Before public void before() context= new ClassPathXmlApplicationContext(application-context.xml); service =(TestService)context.getBean(testService); Test public void test() service.test(); 6, 测试运行结果显示:模拟一个简单的增删改查的日志记录过程1. 首先创建一个描述
5、注解,用与对字段进行描述,后期用得到/* * 注解字段 * author dell * */Target(ElementType.FIELD) /表示该注解只能用于字段Retention (RetentionPolicy.RUNTIME) Documentedpublic interface DescAnnotation /描叙 String description();2. 创建一个操作日志注解(这个写的很好,不是我写的)/* * * author dell * */Target(ElementType.METHOD)Retention(RetentionPolicy.RUNTIME)Doc
6、umentpublic interface OperateLoger /* * 描叙信息 * return */ String content() default 无描述信息; /* * C:增加 R:查询 U:修改 D:删除 * author dell * */ enumOperationType C, R, U, D , LOGIN_IN,LOGIN_OUT ; OperationTypeoperationType() default OperationType.R; /* * U时必须传入原始对象(修改时要有用到,action中必须有getOldBean()方法,也就是先的查询出修改前的
7、对象) * return */ String oldObject() default OldBean; /* * C,U时候用到,目标对象必须传入值(增加,删除,查询时用到,页面传过来的对象,action中必须有getBean()方法) * return */ String targetObject() default Bean; /* * OUT:通知外部系统,IN:通知本系统,ALL:同时通知 * author dell * */ enumNoticeSystem OUT, IN, ALL ; NoticeSystemnoticeSystem() default NoticeSystem.
8、ALL; /* * 对应的表,多个的话以“,”分割 * return */ String tables() default ;3. 创建一个操作记录实体类(也不是我写的,字段记录的很全)Componentpublic class OperateRecord DescAnnotation(description=唯一id) private String id; DescAnnotation(description=用户编号)private String userId; DescAnnotation(description=资源编码)private String rsrcCode; DescAnn
9、otation(description=dict:tab操作类型:C:新增R:查询U:更新D:删除)private String opType; DescAnnotation(description=操作时间)private String opTime; DescAnnotation(description=操作结果)private String opResult; DescAnnotation(description=操作说明)private String opDesc; DescAnnotation(description=传入参数) private String params; Desc
10、Annotation(description=修改前内容只记录修改的)private String prevContent; DescAnnotation(description=修改后内容)private String content; DescAnnotation(description=记录生成日期)private Date createTime; DescAnnotation(description=记录最后更新日期)private Date lastUpdTime; DescAnnotation(description=客户端ip)private String clientIp;/省
11、略getter setter方法,省略toString方法4. 创建一个测试对象public class Person implements Cloneable private Integer id; private String name; private Integer age; /省略getter setter 以及toString,clone 方法5. 用java集合创建一个模拟数据库(数据库操作不是这里讨论的重点)/* * 模拟一个数据库 * author dell * */public class DataBase private static int id=0; private
12、static Listdatas = new ArrayList(); private static List logs= new ArrayList(); static /生成一些测试数据 for (inti = 0; i 3; i+) Person p = new Person(); p.setId(i); p.setName(名称_+i); p.setAge(10+i); datas.add(p); /下面是模拟数据库的操作 public static Person get(int index) returndatas.get(index); public static int add(
13、Person op) returndatas.add(op)?1:0; public static List list() returndatas; public static int update(Person person) for (inti = 0; idatas.size(); i+) if(datas.get(i).getId()=person.getId() datas.set(i, person); return 1; return 0; public static int remove(int index) try datas.remove(index); return 1;
14、 catch (Exception e) e.printStackTrace(); return 0; /往数据库里面添加日志 public static intaddLog(OperateRecordoperateRecord) try logs.add(operateRecord); return 1; catch (Exception e) e.printStackTrace(); return 0; public static ListqueryAllLogs() return logs; /用于模拟生成ID public synchronized static intgetId()
15、return id+; 6. 修改之前TestService接口以及实现类public interface TestService public Person get(int id); publicList list(); publicint add(Person erson); publicint update(Person person); publicint delete(int id);public class TestServiceImpl implements TestService /目标对象(添加,修改时候用到) privatePerson bean; /原始对象(修改时候用到
16、) privatePersonoldBean; OperateLoger(content=查询单个对象操作,operationType=OperationType.R,noticeSystem=NoticeSystem.IN) publicPersonget(int id) returnDataBase.get(id); OperateLoger(content=查询List操作,operationType=OperationType.R,noticeSystem=NoticeSystem.IN) public List list() returnDataBase.list(); Operat
17、eLoger(content=添加操作,operationType=OperationType.C,noticeSystem=NoticeSystem.ALL) publicint add(Personperson) returnDataBase.add(person); OperateLoger(content=更改操作,operationType=OperationType.U,noticeSystem=NoticeSystem.ALL) publicint update(Personperson) returnDataBase.update(person); OperateLoger(c
18、ontent=删除操作,operationType=OperationType.D,noticeSystem=NoticeSystem.ALL) publicint delete(int id) returnDataBase.remove(id); /省略getter setter 方法 7. 重点改写LogerAspect日志处理类(涉及到的工具类这里省略)AspectComponentpublic class LogerAspect Pointcut(execution (* com.manager.*.service.*.*(.) public void logAspect() Befo
19、re(value = logAspect() & annotation(ol) /注意这里的变化 public synchronized void beforeOperateLog(JoinPointjp,OperateLogerol) /记录日志暂时不考虑前置通知 After(logAspect() & annotation(ol) public synchronized void addOperateLog(JoinPointjp, OperateLogerol) System.out.println(调用后置通知); OperateRecordoperateRecord = new Op
20、erateRecord(); try String Ip = NetworkTools.getIpAddrByRequest(); String opertionType = ol.operationType().toString(); operateRecord.setId(DataBase.getId()+); operateRecord.setUserId(userId); /测试时候直接写死一个userid字符串 operateRecord.setRsrcCode(ObjectUtils.getObjectName(jp.getSignature().getDeclaringTypeN
21、ame() + _ + jp.getSignature().getName(); operateRecord.setOpType(opertionType); operateRecord.setOpDesc(ol.content(); operateRecord.setOpResult(true); operateRecord.setClientIp(Ip); operateRecord.setParams(Arrays.toString(jp.getArgs(); operateRecord.setOpTime(new Random().nextInt(1000)+); /这里用随机数表示,
22、实际操作时间需要计算 operateRecord.setCreateTime(new Date(); operateRecord.setLastUpdTime(new Date(); /接下来查找更新时候,对象变化的字段 Object obj = jp.getThis(); Object targetObject = null; MaptargetMap = null; if(ol.targetObject() != null & !.equals(ol.targetObject() Method targetMethod = null; try targetMethod = obj.getC
23、lass().getMethod(get + ol.targetObject(); catch (Exception e) e.printStackTrace(); if(targetMethod = null) /如果没有方法的话,就给个默认的 targetMap = new HashMap(); else targetObject = targetMethod.invoke(obj); targetObject = AopTargetUtils.getTarget(targetObject); targetMap = ObjectUtils.getObjectValue(targetObj
24、ect); MapoldMap = null; String dif = new String2; if(C.equals(opertionType) | R.equals(opertionType) | D.equals(opertionType) if(ol.targetObject() != null & !.equals(ol.targetObject() dif1 = ObjectUtils.convertMapToString(targetMap); dif0 = ; else Method oldMethod = obj.getClass().getMethod(get + ol
25、.oldObject(); Object oldObject = oldMethod.invoke(obj); oldObject = AopTargetUtils.getTarget(oldObject); oldMap = ObjectUtils.getObjectValue(oldObject); dif = ObjectUparisonMap(oldMap, targetMap); operateRecord.setPrevContent(dif0); operateRecord.setContent(dif1); String tables = ol.tables(); /受影响的表
26、(其他相关处理) DataBase.addLog(operateRecord); /模拟写入数据库 catch(Exception e) e.printStackTrace(); 8. 添加单元测试方法public class TestModel ClassPathXmlApplicationContext context; TestService service; Before public void before() context= new ClassPathXmlApplicationContext(application-context.xml); service =(TestService)context.getBean(testService); After public void after() System.out.println(查看日志.); List ops= DataBase.queryAllLogs(); for (OperateRecord
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1