SpringBoot自定义注解(AOP切片)

布满荆棘的人生 2023-07-17 06:44 22阅读 0赞

依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-aop</artifactId>
  4. <version>2.1.5.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.aspectj</groupId>
  8. <artifactId>aspectjweaver</artifactId>
  9. <version>1.9.0</version>
  10. </dependency>

自定义注解

  1. package com.licai.web.annotations;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. /**
  8. * @ClassName: IsBuyGood
  9. * @Description:TODO(判断当前用户是否购买指定商品)
  10. * @param url 未购买,跳转页面的相对路径
  11. * @param request中需有goodsId
  12. * @author: wd
  13. * @date: 2020年3月20日 上午11:28:45
  14. * 自定义注解
  15. * 注解的声明:public @interface 注解名称
  16. *
  17. * 元注解:标记注解的注解
  18. * @Documented:表示该注解会被javadoc命令写入api文档中
  19. * @Target:注解的标记位置
  20. * ElementType.ANNOTATION_TYPE:该注解可以标记别的注解
  21. * ElementType.CONSTRUCTOR:标注到构造方法
  22. * ElementType.FIELD:标注到成员属性
  23. * ElementType.LOCAL_VARIABLE:标注到局部变量
  24. * ElementType.METHOD:标注到方法上
  25. * ElementType.PACKAGE:标注到包上
  26. * ElementType.PARAMETER:标注到方法形参上
  27. * ElementType.TYPE:标注到类、接口、枚举类上
  28. * @Retention:注解的作用范围
  29. * RetentionPolicy.SOURCE:注解的有效范围只在源码中,编译后就被丢弃
  30. * RetentionPolicy.CLASS:注解有效范围在编译文件中,运行时丢弃
  31. * RetentionPolicy.RUNTIME:注解在运行时仍然有效,这个范围的注解可以通过反射获取
  32. *
  33. * 注解内的方法声明:
  34. * 类型 方法名() [defualt 默认值];
  35. *
  36. * 注意:
  37. * 如果一个属性没有设置default默认值,在标记这个注解时,必须给定该属性值
  38. * 如果一个属性的名字为value,则在赋值时可以省略属性名。当如果需要赋值两个以上的属性,则value不能省略
  39. * 如果一个属性的类型是数组类型,则应该用{}赋值,如果只要给一个值,{}可以省略
  40. */
  41. @Target(ElementType.METHOD)//作用范围,方法上
  42. @Retention(RetentionPolicy.RUNTIME)//运行时
  43. @Documented
  44. public @interface IsBuyGood {
  45. String url();
  46. }

切面类

  1. package com.licai.web.annotations.aspect;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpSession;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.Around;
  6. import org.aspectj.lang.annotation.Aspect;
  7. import org.springframework.beans.factory.annotation.Value;
  8. import org.springframework.stereotype.Component;
  9. import org.springframework.web.context.request.RequestContextHolder;
  10. import org.springframework.web.context.request.ServletRequestAttributes;
  11. import com.alibaba.dubbo.config.annotation.Reference;
  12. import com.app.dubboservice.order.service.DubboOrderService;
  13. import com.app.order.model.Order;
  14. import com.app.user.model.UserInfo;
  15. import com.licai.web.annotations.IsBuyGood;
  16. @Aspect
  17. @Component
  18. public class IsBuyGoodAspect {
  19. @Reference(check = false)
  20. private DubboOrderService dubboOrderService;
  21. @Value("${spring.profiles.active}")
  22. private String profile;
  23. /**
  24. * 环绕增强
  25. * 判断controller的方法上有没有@IsLogin注解
  26. * 如果有就对其进行增强
  27. * 增强效果
  28. * 1/给方法的形参列表User user 注入值
  29. * 如果登录了就注入user
  30. * 如果没登录就注入null
  31. * 2.如果IsLogin的value=false表示不强制跳转到登录页面
  32. * 3.如果IsLogin的value=true表示强制跳转到登录页面,一旦发现cookie中没有值直接跳转不允许执行目标方法
  33. */
  34. @Around("@annotation(isBuyGood)")
  35. //表达式代表所有路径下面的xxxController类中的方法带@IsLogin注解的
  36. public Object isBuyGood(ProceedingJoinPoint proceedingJoinPoint,IsBuyGood isBuyGood) throws Throwable {
  37. //获得request请求
  38. ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  39. HttpServletRequest request = requestAttributes.getRequest();
  40. HttpSession seesion = request.getSession();
  41. Integer userId=null;
  42. if(seesion!=null){
  43. UserInfo userInfo = (UserInfo) seesion.getAttribute("loginUser");
  44. if(userInfo!=null){
  45. userId=userInfo.getUserId();
  46. }
  47. }
  48. //表示已经登录或者不需要登录就可以继续操作
  49. //获得形参列表
  50. Object[] args = proceedingJoinPoint.getArgs();
  51. boolean isBuy = false;
  52. //因为登录后需要带returnUrl跳转到之前的页面,所以需要通过request对象获得url
  53. String requestURL = request.getRequestURL().toString();
  54. //带参数
  55. //requestURL.append(request.getQueryString());
  56. requestURL=requestURL.replace(request.getRequestURI(),"" );
  57. String url=requestURL+request.getContextPath()+isBuyGood.url();
  58. //解决中文乱码问题
  59. // String url = URLEncoder.encode(requestURL.toString(), "utf-8");
  60. //同样解决&带参数当做一个参数的问题
  61. // url = url.replace("&","%26");
  62. if(userId != null){
  63. String goodId = request.getParameter("goodsId");// 商品id
  64. if(userId!=null && !goodId.isEmpty()) {
  65. Order order = dubboOrderService.queryUserGoodsOrder(Integer.parseInt(goodId),userId);
  66. if(order!=null) {
  67. isBuy = true;
  68. }else {
  69. isBuy = false;
  70. }
  71. if (profile != null && "dev".equals(profile)) {
  72. // 测试环境
  73. if("10898".equals(goodId)) {
  74. isBuy = true;
  75. }
  76. }else {
  77. if("11033".equals(goodId) || "11149".equals(goodId) || "11183".equals(goodId)) {
  78. isBuy = true;
  79. }
  80. }
  81. }
  82. if(!isBuy) {
  83. return "redirect:"+url;
  84. }
  85. //false继续执行目标方法
  86. }
  87. //执行目标方法 --- 带指定的形参列表
  88. Object result = proceedingJoinPoint.proceed(args);
  89. //执行目标方法后的方法返回值就是目标方法的返回值
  90. return result;
  91. }
  92. }

使用

  1. @RequestMapping("lianXi")
  2. @IsBuyGood(url="/home")
  3. public String lianXi() {
  4. }

发表评论

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

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

相关阅读