在正式上代码之前,需要了解的aop知识点:

切面(Aspect):在Spring AOP中,切面可以使用通用类或者在普通类中以@Aspect 注解(@AspectJ风格)来实现
连接点(Joinpoint):在Spring AOP中一个连接点代表一个方法的执行
通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括"around"、"before” 和"after"等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链
切入点(Pointcut):定义出一个或一组方法,当执行这些方法时可产生通知,Spring缺省使用AspectJ切入点语法。

OK知道这么多就可以了,开始我们愉快的代码时光。
先上数据库字段设计

CREATE TABLE `sys_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `table_name` varchar(50) DEFAULT NULL,
  `param` varchar(255) DEFAULT NULL,
  `operate_type` int(11) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `result` char(255) DEFAULT 'success',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创完表,习惯性的用逆向工程(generatorsqlmapcustom),生成一下
没有的话链接在这里(肯定要往表中添加字段,所以这是必须的)

android aldi 返回值 aop 返回值_spring-aop


一)在增强类注入我们的日志service

@Autowired 
	SysLogService sysLogService;

配置我们的spring-mybatis.xml文件,找到切入点
配置多个切入点

<!-- 设置切面 把事务管理的切面设置在service实现类这一层 -->
	<aop:config>
		<!-- 指定aop切面配置 定义一个切面实例 指定使用具体哪一个增强类进行增强 -->
		<aop:aspect ref="ServiceAdvice">
			<!-- pintcut 具体切面的表达式 execution 运行 * 访问权限任意 包路径 *所有类 *所有方法 (..)参数任意 返回值任意 -->
			<aop:pointcut expression="execution(* com.oracle.ssm.service.impl.*.add*(..))"
				id="addCut" />
			<aop:after-returning method="after" pointcut-ref="addCut"
				arg-names="joinPoint,object" returning="object" />
			<aop:pointcut
				expression="execution(* com.oracle.ssm.service.impl.*.insert*(..))"
				id="insertCut" />
			<aop:after-returning method="after" pointcut-ref="insertCut"
				arg-names="joinPoint,object" returning="object" />
			<aop:pointcut
				expression="execution(* com.oracle.ssm.service.impl.*.delete*(..))"
				id="saveCut" />
			<aop:after-returning method="after" pointcut-ref="saveCut"
				arg-names="joinPoint,object" returning="object" />
		</aop:aspect>

	</aop:config>

after-returning:返回后的一个增强方式
arg-names:配置参数 (必须要配置,不配置的话增强类获取不到。报错)
joinpoint:织入点(接入增强)
Object:返回值
二)在after中编写
取方法名:joinpoint.getSignature().getName();
取表名:

// 取方法名
		String methodName = joinpoint.getSignature().getName();
		String tableName = ""; // 表名

		int operate_type = 0;// 操作类型

		if (methodName.contains("add")) {
			tableName = methodName.substring("add".length());
			operate_type = 1;

		}
		if (methodName.contains("insert")) {
			tableName = methodName.substring("insert".length());
			operate_type = 1;

		}
		if (methodName.contains("delete")) {
			tableName = methodName.substring("delete".length(), methodName.indexOf("By"));
			operate_type = 2;
		}
		if (methodName.contains("update")) {
			tableName = methodName.substring("update".length(), methodName.indexOf("By"));
			operate_type = 3;
		}

取参数名称,参数类型。传过来的可能是多个,我们用数组进行处理

Object[] arrays=joinpoint.getArgs();
		StringBuffer rs=new StringBuffer();
		String paramClass;
		for (Object object2 : arrays) {
			//取到参数的类型
			paramClass=object2.getClass().getName();
			paramClass=paramClass.substring(paramClass.lastIndexOf(".")+1);
			rs.append("[参数,类型]"+paramClass+",值:(id:"
			+joinpoint.getArgs()[0]+")");
			
		}

获取用户ID

ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
		HttpSession session = attr.getRequest().getSession(true);
		User user = (User) session.getAttribute("user");

获取返回值:在这里我们用到了Gsonjar包:下载链接(链接:https://pan.baidu.com/s/1EdbM1HjK8WxHxnyKoSBPMw 提取码:1nc4 )

Gson json = new Gson();
		String result = json.toJson(object).toString();

!!!!!!!!!!易错点!!!!!!!!!!!!!!!!!!!
当我们所有值都获取到以后,调用方法:

sysLogService.charuSelective(sysLog);

重点画圈。这里一定要改方法名字,不要用什么Insert add 什么的。

为什么?自己查看一下aop的配置即可,不改的话会出现死循环(这里本人整整卡了4个小时)。

最后启动一下项目,执行一个添加方法。

android aldi 返回值 aop 返回值_切口_02


看下我们的日志记录表:

android aldi 返回值 aop 返回值_android aldi 返回值_03


android aldi 返回值 aop 返回值_切口_04


在执行一个修改的方法(没有返回值)

android aldi 返回值 aop 返回值_日志记录_05