java aop 自动填充默认字段

1,359 阅读3分钟

--有偷懒的欲望,促使人创造更高效的工具


import java.lang.reflect.Field;
import java.util.Date;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.dingxing.mng.beans.Admin;
import org.dingxing.mng.utils.AdminUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/****************************************************************************************
实现AOP的切面主要有以下几个要素:

使用@Aspect注解将一个java类定义为切面类
使用@Pointcut定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等。
根据需要在切入点不同位置的切入内容
使用@Before在切入点开始处切入内容
使用@After在切入点结尾处切入内容
使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
使用@Order(i)注解来标识切面的优先级。i的值越小,优先级越高

现在来看看几个例子:

复制代码
1)execution(* *(..))  
//表示匹配所有方法  
2)execution(public * com. savage.service.UserService.*(..))  
//表示匹配com.savage.server.UserService中所有的公有方法  
3)execution(* com.savage.server..*.*(..))  
//表示匹配com.savage.server包及其子包下的所有方法 


符号 含义
execution()
表达式的主体;
第一个”*“符号
表示返回值的类型任意;
com.sample.service.impl AOP所切的服务的包名,即,我们的业务部分
包名后面的”..“ 表示当前包及子包
第二个”*“ 表示类名,*即所有类。此处可以自定义,下文有举例
.*(..) 表示任何方法名,括号表示参数,两个点表示任何参数类型

https://www.cnblogs.com/Struts-pring/p/9881716.html

执行日志顺序:
总结:doBefore 方法先从高优先级到低优先级依次执行完,然后 doAfterReturning 方法从低优先级到高优先级依次执行完;也就是进入从高到低,出来从低到高;
****************************************************************************************/

/**
 * todo   	insert update 切面用于自动补全业务不大相关统一字段
 * author 	liangguohun
 * datetime 2017年12月31日 上午12:38:29
 */
@Aspect
@Component
@Order(2)
public class DaoAspect {
	/**
	 * todo:		对insert 切面 补全操作人信息初始默认态创建时间等字段值	
	 * author:		梁国魂
	 * datetime:	2017年12月31日 上午12:46:09
	 */
	@Pointcut("execution(public * com.baomidou.mybatisplus.extension.service.impl..*.insert(..))")
	public void doInsert() {
		
	}
	
	@Pointcut("execution(public * com.baomidou.mybatisplus.extension.service.impl..*.upById(..))")
	public void doUpdate() {
		
	}
	
    @Before("doInsert()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
    	Object obj = joinPoint.getArgs()[0];
    	addFieldsValueForCreate(obj);
    }

    
    @Before("doUpdate()")
    public void doUpdate(JoinPoint joinPoint) throws Throwable {
    	Object obj = joinPoint.getArgs()[0];
    	addFieldsValueForUpdate(obj);
    }
    
    /**
     * insert时, 自动补全操作人信息 新建默认字段初始态
     */
    public static void addFieldsValueForCreate(Object obj) {
		Field[] fields = obj.getClass().getDeclaredFields();
		try {
			for (Field f : fields) {
				f.setAccessible(true);
				String fileName = f.getName();
				if(fileName.equals("createTime")) {
					f.set(obj, new Date());// 对应属性 创建值
				} else if(fileName.equals("userId")) {
					Admin admin = AdminUtils.getCurrentAdmin();
					f.set(obj, Integer.parseInt(admin.getId()+""));
				} else if(fileName.equals("isDeleted")) {//未删除1 删除2
					f.set(obj, 1);
				} else if(fileName.equals("canUse")) {	//启用1 禁用2
					f.set(obj, 1);
				}
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

	}
    /**
     * update时, 自动补全操作人信息 更新默认字段初始态
     */
    public static void addFieldsValueForUpdate(Object obj) {
		Field[] fields = obj.getClass().getDeclaredFields();
		//获取属性列表
		try {
			for (Field f : fields) {
				f.setAccessible(true);
				String fileName = f.getName();
				if(fileName.equals("updateTime")) {
					f.set(obj, new Date());// 对应属性 创建值
				} else if(fileName.equals("userId")) {
					Admin admin = AdminUtils.getCurrentAdmin();
					f.set(obj, Integer.parseInt(admin.getId()+""));
				}
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

}