spring boot 自定义注解

布满荆棘的人生 2021-09-25 02:04 484阅读 0赞

java 自定义注解

在项目开发的过程中我们能遇到的自定义注解一般分为两类

  1. 通过自定义注解自动获取参数值。比如:@LoginUser
  2. 通过自定义注解做验证。比如 验签,token验证
    上面两类最大的区别就是一个需要返回值一个不需要返回值。
    接下来我将对如上两类自定义的处理方法进行实际的实现,自定义的基础理论可以在网上查找一下,我这里就不做详细的介绍。

第一类 @Loguser

实现分为三步:

  1. 定义一个注解@LoginUser
  2. 创建一个LoginUser注解的解析器
  3. 创建一个配置类(在WebMvcConfigurer )

定义一个注解

注意: Target

  1. @Target(ElementType.PARAMETER)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface LoginUser {
  4. }

创建一个LoginUser注解的解析器

  1. @Component
  2. public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
  3. @Autowired
  4. private LoginService loginService;
  5. @Override
  6. public boolean supportsParameter(MethodParameter parameter) {
  7. return parameter.getParameterType().isAssignableFrom(User.class) && parameter.hasParameterAnnotation(LoginUser.class);
  8. }
  9. @Override
  10. public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
  11. Long cUserId=(Long) request.getAttribute(Constants.CURRENT_USER_ID,RequestAttributes.SCOPE_REQUEST);
  12. if (cUserId>0) {
  13. User user = loginService.getUserById(cUserId);
  14. if(user == null) {
  15. throw new RuntimeException(i18nService.getMessage("user.not.exist"));
  16. }
  17. //重点是这里返回对象
  18. return user;
  19. }
  20. }
  21. }

创建一个配置类

  1. @Configuration
  2. public class LoginUserConfigurer implements WebMvcConfigurer {
  3. //必须用注入方式,不能用new,否则此对象内部属性无法被注入
  4. @Autowired
  5. private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
  6. /**
  7. * 配置自定义参数解析器
  8. */
  9. @Override
  10. public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
  11. argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
  12. }
  13. }

直接可以在代码里面使用

  1. public ResponseResult saveServiceInfo(@LoginUser User loginUser) {
  2. // 下面直接获取数据
  3. loginUser.getUsername();
  4. }

第二类 验证

  1. 先定义注解
  2. 定义一个切面
  3. 直接使用

定义注解

注意: Target

  1. import java.lang.annotation.*;
  2. @Target({ElementType.METHOD,ElementType.PARAMETER, ElementType.TYPE})
  3. @Retention(RetentionPolicy.RUNTIME)
  4. @Documented
  5. public @interface ValidatedSignature {
  6. String value() default "";
  7. }

定义切面

  1. Aspect
  2. @Component
  3. @SuppressWarnings({"unused"})
  4. public class ValidatedSignatureAspect {
  5. public static final Logger logger = LoggerFactory.getLogger(ValidatedSignature.class);
  6. public static final String TOKEN_KEY = "token";
  7. /**
  8. * checkUrl,keyUrl,tokenScope是通过Spring的@Value注解来获取配置文件中的配置项
  9. *
  10. * @Value等同于Spring原先的配置模式中的value <bean id="" class="">
  11. * <property name="" value="">
  12. * </bean>
  13. */
  14. @Pointcut("@annotation(com.louis.kitty.admin.annotation.ValidatedSignature)")
  15. public void annotationPointcut() {
  16. logger.info("annotationPointcut()");
  17. }
  18. @Before("annotationPointcut()")
  19. public void beforePointcut(JoinPoint joinPoint) {
  20. // 此处进入到方法前 可以实现一些业务逻辑
  21. logger.info("beforePointcutJoinPoint joinPoint)");
  22. }
  23. @Around("annotationPointcut()")
  24. public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
  25. logger.info("doAround(ProceedingJoinPoint joinPoint)");
  26. MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  27. String[] params = methodSignature.getParameterNames();// 获取参数名称
  28. Class[] paramsType = methodSignature.getParameterTypes();
  29. Object[] args = joinPoint.getArgs();// 获取参数值
  30. JSONObject jsonObj=new JSONObject();
  31. for (int index=0;index<params.length;index++) {
  32. jsonObj.put(params[index],args[index]);
  33. }
  34. logger.info(jsonObj.toJSONString());
  35. int size1=params.length;
  36. int size2=paramsType.length;
  37. int size3=args.length;
  38. RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
  39. HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
  40. String token = request.getHeader("token");
  41. // if (null == params || params.length == 0) {
  42. // String mes = "Using Token annotation, the token parameter is not passed, and the parameter is not valid.";
  43. // logger.info(mes);
  44. // throw new Exception(mes);
  45. // }
  46. // boolean hasToken = false;
  47. // int index = 0;
  48. // for (int i = 0; i < params.length; i++) {
  49. // if (TOKEN_KEY.equals(params[i])) {
  50. // hasToken = true;
  51. // index = i;
  52. // break;
  53. // }
  54. // }
  55. // if (!hasToken) {
  56. // String mes = "The token parameter is not included in the requested parameter, the parameter is not valid.";
  57. // logger.info(mes);
  58. // throw new Exception(mes);
  59. // }
  60. return jsonObj;
  61. // return joinPoint.proceed();
  62. }
  63. /**
  64. * 在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
  65. *
  66. * @param joinPoint
  67. */
  68. @AfterReturning("annotationPointcut()")
  69. public void doAfterReturning(JoinPoint joinPoint) {
  70. logger.info("doAfterReturning(JoinPoint joinPoint)");
  71. }
  72. }

代码直接使用

  1. @ValidatedSignature
  2. public ResponseResult saveServiceInfo() {
  3. }

发表评论

表情:
评论列表 (有 0 条评论,484人围观)

还没有评论,来说两句吧...

相关阅读