java自定义注解,保存用户操作日志

关于注解,很多人都清楚它们的用途,像@Autowired,@Controller,@Service等等

而自定义注解,就是我们自己创建一个注解。

自定义注解的格式:

public @interface 注解名 {定义体}

本文使用自定义注解结合springAop,记录用户的操作日志。


说到Aop切面编程,这种官方词语,看着就慌。

举个例子,现在你要吃?(面包),但你喜欢吃有馅的食物,于是你用水果刀切开一道口,往里头加了点葡萄干,然后又切了道口,往里头挤了点奶油。这样一来,面包就变美味了,切面包 == 切面?

?同理,现在有个修改数据的方法A,因为不知道是谁修改了数据,所以你打算在程序执行方法A后,自动保存操作日志。

于是你开始操刀:

A(){
    /** 执行操作 **/
    saveLog();
}

saveLog(){
    Log log = new Log();
    log.setModule("用户管理");
    log.setAction("修改数据");
    log.setCreateTime(new Date());
    log.setCreateId(userName);
    dao.saveLog(log);
}

很完美?

这时,其他功能也要跟着使用?。虽说能把saveLog()抽成公共方法,但每个需要保存日志的方法,都需要在尾部加上saveLog()。假如又需要在方法执行前,做其他操作,难道又要改成:

A(){
    doSomething();
    /** 执行操作 **/
    saveLog();
}
B(){
    doSomething();
    /** 执行操作 **/
    saveLog();
}
C(){
    doSomething();
    /** 执行操作 **/
    saveLog();
}

这是不可取的?‍。

而切面编程,能在方法执行前后,或者抛出异常时,自动执行一系列方法,非常漂亮的解决了这种问题。


回归主题,来为用户添加操作日志。

在spring配置文件里开启aop:

<aop:aspectj-autoproxy proxy-target-class="true" />

创建自定义注解LogAnnotation,默认模块是用户管理,默认操作是登录。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface LogAnnotation {
	String module() default "用户管理";
	String action() default "登录";
}

创建切面程序:

@Aspect
@Component
public class LogAspect {
	private Logger logger = Logger.getLogger(LogAspect.class);
	@Autowired
	private SysUserLogMapper sysUserLogMapper;
	
	@Pointcut("@annotation(com.plan.LogAnnotation)")
	private void logPointCut() {}
	
	@After("logPointCut()")
	public void after(JoinPoint joinPoint) {
		try {
			SysUserLog log = new SysUserLog();
			setUserInfo(log);
			setLogInfo(joinPoint,log);
			sysUserLogMapper.insert(log);
		} catch (InvalidSessionException e) {
			logger.error(e.getMessage());
		}
	}
	/**
	 * 设置用户信息
	 * @param log
	 */
	public void setUserInfo(SysUserLog log) {
		Session session = SecurityUtils.getSubject().getSession();
		User user = (User) session.getAttribute("user");
		log.setUserId(user.getUserId());
		log.setUserName(user.getChineseName());
		log.setCreateDate(new Date());
	}
	/**
	 * 设置操作信息
	 * @param joinPoint
	 * @param log
	 */
	public void setLogInfo(JoinPoint joinPoint, SysUserLog log){
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
		log.setModule(annotation.module());
		log.setAction(annotation.action());
	}
}

切面编程还有@before,这里就不写出来了。而关于@AfterThrowing,必须是方法体抛出异常,才能捕获到。

在需要记录日志的功能方法上添加注解:

@LogAnnotation(module="用户管理",action="登录")
public String userLogin() {

}

@LogAnnotation 对应的,就是 public @interface LogAnnotation

如此一来,在执行userLogin()方法后,程序会自动执行LogAspect类的after方法,得以记录日志。

以上!!!

另需注意

如果没使用springMVC,而是struts,或许会出现@Autowired类为NULL的情况,此时需要在struts.xml 配置文件上,加上这句:

<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true" />

确保Spring的自动装配策略总是被考虑的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值