spring实现自定义注解切面编程例如要实现在某几个类之后或之前调用一些操作，就可以用到这个1. 创建自定义注解import java.lang.annotation.*; //注解放置的位置，METHOD是放在方法上 @Target(ElementType.METHOD) //注解在哪个阶段执行 @Retention(RetentionPolicy.RUNTIME) //生成文档 @Documented public @interface ElaSearchRefresh { String id() default ""; String className() default ""; }类中只需要写上自己需要的字段即可，后面可以作为传参使用2. 引入注解变量解析util照抄就完了import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; import java.lang.reflect.Method; import java.util.Map; /** * 该类的作⽤可以把⽅法上的参数绑定到注解的变量中 * 注解的语法 * 变量名 * #{} * 能解析类似 * "#{sysOperateLogDto.operateType}" */ public class AnnotationResolver { private static AnnotationResolver resolver; public static AnnotationResolver newInstance() { if (resolver == null) { return resolver = new AnnotationResolver(); } else { return resolver; } } /** * 解析注解上的值 * * @param joinPoint 需要解析的字符串 * @param str * @return */ public Object resolver(JoinPoint joinPoint, String str) { if (str == null) return null; Object value = null; //如果匹配上了#则把内容当作变量 if (str.matches("#\\{\\D*\\}")) { String newStr = str.replaceAll("#\\{", "").replaceAll("\\}", ""); if (newStr.contains(".")) {//复杂类型 try { value = complexResolver(joinPoint, newStr); } catch (Exception e) { e.printStackTrace(); } } else { value = simpleResolver(joinPoint, newStr); } } else {//⾮变量 value = str; } return value; } private Object complexResolver(JoinPoint joinPoint, String str) throws Exception { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); String[] names = methodSignature.getParameterNames(); Object[] args = joinPoint.getArgs(); boolean jsonParseFlag = false; if (str.startsWith("$JSON$")){ jsonParseFlag = true; str = str.replace("$JSON$",""); } String[] strs = str.split("\\."); for (int i = 0; i < names.length; i++) { if (strs[0].equals(names[i])) { Object obj = args[i]; if (obj instanceof Map){ return ((Map<?, ?>) obj).get(strs[1]); } //支持json解析 if (obj instanceof String && jsonParseFlag){ JSONObject jsonObject = JSON.parseObject(obj.toString()); return jsonObject.get(strs[1]); } Method dmethod = obj.getClass().getDeclaredMethod(getMethodName(strs[1])); Object value = dmethod.invoke(args[i]); return getValue(value, 1, strs); } } return null; } private Object getValue(Object obj, int index, String[] strs) { try { if (obj != null && index < strs.length - 1) { Method method = obj.getClass().getDeclaredMethod(getMethodName(strs[index + 1])); obj = method.invoke(obj); getValue(obj, index + 1, strs); } return obj; } catch (Exception e) { e.printStackTrace(); return null; } } private String getMethodName(String name) { return "get" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase()); } private Object simpleResolver(JoinPoint joinPoint, String str) { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); String[] names = methodSignature.getParameterNames(); Object[] args = joinPoint.getArgs(); for (int i = 0; i < names.length; i++) { if (str.equals(names[i])) { return args[i]; } } return null; } } 3. 创建切面类import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.util.*; @Aspect @Component public class ElaSearchAspect { @Autowired private IBaseDao baseDao; //定义切点 @Pointcut(value = "@annotation(net.zjsos.business.common.business.filebase.aspect.ElaSearchRefresh)") public void elaRefreshPointCut() { } //定义切面 @After("elaRefreshPointCut()") //around需要使用ProceedingJoinPoint point public void after(JoinPoint point) throws Throwable { MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); ElaSearchRefresh annotation = method.getAnnotation(ElaSearchRefresh.class); //利用util来反射解析动态变量属性 String id = AnnotationResolver.newInstance().resolver(point, annotation.id()).toString(); //如果是写死的变量，直接使用annotation.id()获取即可 } //定义切面 @Around("elaRefreshPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { //去执⾏被访问的切⾯ Object result = point.proceed(); //从切⾯织⼊点处通过反射机制获取织⼊点处 MethodSignature signature = (MethodSignature) point.getSignature(); //获取切⼊点所在的方法 Method method = signature.getMethod(); ElaSearchRefresh annotation = method.getAnnotation(ElaSearchRefresh.class); //利用util来反射解析动态变量属性 String id = AnnotationResolver.newInstance().resolver(point, annotation.id()).toString(); //如果是写死的变量，直接使用annotation.id()获取即可 } }4. 使用注解@RequestMapping("/updateAccessByApplyId") //获取动态变量需要加"#{}"，写死的变量直接"xxx"就行了 @ElaSearchRefresh(id = "#{dto.id}") public ResultDto updateAccessByApplyId(@RequestBody @Valid FileBaseUpdateAccessDto dto){ xxxxxxxxxxxxxxxxxxxxxx }