spring boot 自定义注解
java 自定义注解
在项目开发的过程中我们能遇到的自定义注解一般分为两类:
- 通过自定义注解自动获取参数值。比如:@LoginUser
- 通过自定义注解做验证。比如 验签,token验证
上面两类最大的区别就是一个需要返回值一个不需要返回值。
接下来我将对如上两类自定义的处理方法进行实际的实现,自定义的基础理论可以在网上查找一下,我这里就不做详细的介绍。
第一类 @Loguser
实现分为三步:
- 定义一个注解@LoginUser
- 创建一个LoginUser注解的解析器
- 创建一个配置类(在WebMvcConfigurer )
定义一个注解
注意: Target
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
创建一个LoginUser注解的解析器
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private LoginService loginService;
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().isAssignableFrom(User.class) && parameter.hasParameterAnnotation(LoginUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
Long cUserId=(Long) request.getAttribute(Constants.CURRENT_USER_ID,RequestAttributes.SCOPE_REQUEST);
if (cUserId>0) {
User user = loginService.getUserById(cUserId);
if(user == null) {
throw new RuntimeException(i18nService.getMessage("user.not.exist"));
}
//重点是这里返回对象
return user;
}
}
}
创建一个配置类
@Configuration
public class LoginUserConfigurer implements WebMvcConfigurer {
//必须用注入方式,不能用new,否则此对象内部属性无法被注入
@Autowired
private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
/**
* 配置自定义参数解析器
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
}
}
直接可以在代码里面使用
public ResponseResult saveServiceInfo(@LoginUser User loginUser) {
// 下面直接获取数据
loginUser.getUsername();
}
第二类 验证
- 先定义注解
- 定义一个切面
- 直接使用
定义注解
注意: Target
import java.lang.annotation.*;
@Target({ElementType.METHOD,ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ValidatedSignature {
String value() default "";
}
定义切面
Aspect
@Component
@SuppressWarnings({"unused"})
public class ValidatedSignatureAspect {
public static final Logger logger = LoggerFactory.getLogger(ValidatedSignature.class);
public static final String TOKEN_KEY = "token";
/**
* checkUrl,keyUrl,tokenScope是通过Spring的@Value注解来获取配置文件中的配置项
*
* @Value等同于Spring原先的配置模式中的value <bean id="" class="">
* <property name="" value="">
* </bean>
*/
@Pointcut("@annotation(com.louis.kitty.admin.annotation.ValidatedSignature)")
public void annotationPointcut() {
logger.info("annotationPointcut()");
}
@Before("annotationPointcut()")
public void beforePointcut(JoinPoint joinPoint) {
// 此处进入到方法前 可以实现一些业务逻辑
logger.info("beforePointcutJoinPoint joinPoint)");
}
@Around("annotationPointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
logger.info("doAround(ProceedingJoinPoint joinPoint)");
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String[] params = methodSignature.getParameterNames();// 获取参数名称
Class[] paramsType = methodSignature.getParameterTypes();
Object[] args = joinPoint.getArgs();// 获取参数值
JSONObject jsonObj=new JSONObject();
for (int index=0;index<params.length;index++) {
jsonObj.put(params[index],args[index]);
}
logger.info(jsonObj.toJSONString());
int size1=params.length;
int size2=paramsType.length;
int size3=args.length;
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String token = request.getHeader("token");
// if (null == params || params.length == 0) {
// String mes = "Using Token annotation, the token parameter is not passed, and the parameter is not valid.";
// logger.info(mes);
// throw new Exception(mes);
// }
// boolean hasToken = false;
// int index = 0;
// for (int i = 0; i < params.length; i++) {
// if (TOKEN_KEY.equals(params[i])) {
// hasToken = true;
// index = i;
// break;
// }
// }
// if (!hasToken) {
// String mes = "The token parameter is not included in the requested parameter, the parameter is not valid.";
// logger.info(mes);
// throw new Exception(mes);
// }
return jsonObj;
// return joinPoint.proceed();
}
/**
* 在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
*
* @param joinPoint
*/
@AfterReturning("annotationPointcut()")
public void doAfterReturning(JoinPoint joinPoint) {
logger.info("doAfterReturning(JoinPoint joinPoint)");
}
}
代码直接使用
@ValidatedSignature
public ResponseResult saveServiceInfo() {
}
还没有评论,来说两句吧...