aop配合自定义注解实现了什么?
1.将验证逻辑放在aop中,减少对业务代码的侵入。
2.自定义注解可以实现自定义化是否使用aop。
3.当然也可以将结果放在threadLocal里面存储。
1.定义一个自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface userCheck {
int value() default 0;
}
2.定义一个接口
@UserCheck
Result add(String data,UserInfo userInfo){
//业务逻辑
}
3.定义一个ThreadLocal用于保存全局变量
public class UserInfoContext {
//用户信息上下文
private static ThreadLocal<String> userInfoContext = new ThreadLocal<>();
public static String getUserInfoContext() {
return userInfoContext.get();
}
public static void setUserInfoContext(String info) {
userInfoContext.set(info);
}
}
4.进行aop切面
@Service
@Slf4j
@Aspect
public class UserAop {
private final static String USER_INFO = "userInfo";
@Pointcut("@annotation(com.test.aop.UserCheck)")
public void pointcut() {
}
/**
* 处理用户信息
*
* @param joinPoint
*/
@Before("pointcut()")
public void invoke(JoinPoint joinPoint) {
Method method;
try {
method = joinPoint.getTarget().getClass().getMethod(joinPoint.getSignature().getName(), ((MethodSignature) joinPoint.getSignature()).getParameterTypes());
} catch (NoSuchMethodException e) {
return;
}
if (!method.isAnnotationPresent(UserCheck.class)) {
return;
}
Object[] paramValues = joinPoint.getArgs();
Signature signature = joinPoint.getSignature();
String[] paramNames = null;
if (signature instanceof CodeSignature) {
paramNames = ((CodeSignature) signature).getParameterNames();
}
if (paramNames == null) {
throw new BusinessException("入参不能为空!");
}
for (int i = 0; i < paramNames.length; i++) {
if (!USER_INFO.equals(paramNames[i])) {
continue;
}
UserInfo userInfo = (UserInfo) paramValues[i];
if ((StringUtils.isEmpty(userInfo.getInfo()))) {
throw new BusinessException("getInfo值为空");
}
//这里可以加入验证用户信息的逻辑
UserInfoContext.setInfoContext(userInfo.getInfo());
}
}
}