spring AOP 控制日志

配置applicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring" 
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xsi:schemaLocation="http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop.xsd 
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd 
		http://mybatis.org/schema/mybatis-spring 
		http://mybatis.org/schema/mybatis-spring.xsd 
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx.xsd 
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx.xsd">

	spring的配置省略.......

	<!-- 日志切面 这里的路径是处理日志的方法路径 -->
	<context:component-scan base-package="com.test.log.LogAspect"></context:component-scan>
 
	<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"></aop:aspectj-autoproxy>

写一个注解类

凡是需要记录日志的就在方法上加入这个注解

@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {
	
	/** 日志描述 */
    String description() default "";
 
    /** 操作模块*/
    String czmk();
    /** 操作类型*/
    String czlx();

	/** 
	 *  用于区分一个方法使用不同的表的情况 
	 * 2 是操作日志 1 是登录日志
	 * */
    int type() default 2;
}

接口中注解使用

@Api(tags="用户登陆")
@Controller
@RequestMapping("/login")
public class LoginController {
	@ApiOperation(value = "用户登陆",httpMethod="POST",notes = "")
	@RequestMapping(value="init", method=RequestMethod.POST)
	@ResponseBody
	@LogAnnotation(description = "登录系统验证用户名密码",czlx = "登录",czmk = "系统登录",type = 1)
	public Object initLogin(@RequestBody XtUser xTuser, String remeber) {
		j.setCode(200);
		j.setMsg("用户验证成功!");
		j.setSuccess(true);
		return j;
	}
}

写一个日志处理的类

下面有两种方法处理
第一种

@Aspect
@Component
public class LogAspect {
	@Autowired
	private UserService userService ;
	/**
	 * 定义一个切点
	 */
	@Pointcut("@annotation(com.test.web.log.LogAnnotation)")
	private void accAspect() {
	}
	
	/**
	 * 切面处理
	 * @param joinPoint
	 * @param result
	 * @throws Throwable
	 */
	@AfterReturning(pointcut = "accAspect()", returning = "result")
	public void around(JoinPoint joinPoint, Object result) throws Throwable {
	}

第二种

@Aspect
@Component
public class LogAspect {
` /**
     * @Around 环绕通知:
     *   环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。
     *   环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
     */
    /**
     * 项目日志新增操作日志记录
     *
     * @param point
     * @throws Throwable
     */
    @Around("execution(com.test.service.ProjectService.addProject(..))")
    public Object processAddProjectConfig(ProceedingJoinPoint point) throws Throwable {
    }
     /**
     * 项目日志修改操作日志记录
     *
     * @param point
     * @throws Throwable
     */
    @Around("execution(com.test.service.ProjectService.updateProject(..))")
    public Object processUpdateProjectConfig(ProceedingJoinPoint point) throws Throwable {
注意

两者的区别是:

  1. 将切面提取出来了 可以共用一个切面控制
  2. 单独控制切面, 不同的接口使用不同的方法控制日志
    也可以写多个注解类,在不同的类上使用

@AfterReturning标签属性分析:

     value值: 可以写Aop的表达式,如execution、args、within等,多个之间使用&& || !作为连接; 也可以使用引用其他Pointcut;

     pointcut值:和value值用法一样

     returning值:给被增强方法返回值取个名字,给后面引用;(使用了日志控制的类的返回值)

     argNames值:方法入参的名字,Spring4.2.x测试时候发现写不写都可以实现Aop,具体看下面测试.

     如果只需要记录方法返回值的话,只需要配置returning属性,方法入参配置上对应返回值类型或其父类即可,写Object应该肯定没问题吧;

知识点1.returning属性的值和增强方法的入参是按照名称来匹配;
  当增强方法入参名称和returning不一致时,就会抛出异常Returning argument name ‘val’ was not bound in advice arguments

知识点2. 增强方法入参不能出现多余(JoinPoint不算多余),否则会匹配不上; 如果想要获取被增强方法入参,方式有两种,下面有介绍.
  1). 增强方法入参类型必须是 被增强方法返回值类型或者父类,否则增强方法无法执行; void类型的方法返回值是null,可以使用Object类型来接收
  2)查看源码可以得到解释, AspectJAfterReturningAdvice的afterReturning会先判断类型是否匹配来决定执行不执行后置增强;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值