SpringBoot自定义注解(AOP切片)

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.1.5.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.0</version>
</dependency>

自定义注解

package com.licai.web.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @ClassName:  IsBuyGood   
 * @Description:TODO(判断当前用户是否购买指定商品)
 * @param url  未购买,跳转页面的相对路径
 * @param request中需有goodsId   
 * @author: wd
 * @date:  2020年3月20日  上午11:28:45

    * 自定义注解
 * 注解的声明:public @interface 注解名称
 *
 * 元注解:标记注解的注解
 * @Documented:表示该注解会被javadoc命令写入api文档中
 * @Target:注解的标记位置
 *  ElementType.ANNOTATION_TYPE:该注解可以标记别的注解
 *  ElementType.CONSTRUCTOR:标注到构造方法
 *  ElementType.FIELD:标注到成员属性
 *  ElementType.LOCAL_VARIABLE:标注到局部变量
 *  ElementType.METHOD:标注到方法上
 *  ElementType.PACKAGE:标注到包上
 *  ElementType.PARAMETER:标注到方法形参上
 *  ElementType.TYPE:标注到类、接口、枚举类上
 * @Retention:注解的作用范围
 *  RetentionPolicy.SOURCE:注解的有效范围只在源码中,编译后就被丢弃
 *  RetentionPolicy.CLASS:注解有效范围在编译文件中,运行时丢弃
 *  RetentionPolicy.RUNTIME:注解在运行时仍然有效,这个范围的注解可以通过反射获取
 *
 * 注解内的方法声明:
 * 类型 方法名() [defualt 默认值];
 *
 * 注意:
 * 如果一个属性没有设置default默认值,在标记这个注解时,必须给定该属性值
 * 如果一个属性的名字为value,则在赋值时可以省略属性名。当如果需要赋值两个以上的属性,则value不能省略
 * 如果一个属性的类型是数组类型,则应该用{}赋值,如果只要给一个值,{}可以省略

 */
@Target(ElementType.METHOD)//作用范围,方法上
@Retention(RetentionPolicy.RUNTIME)//运行时
@Documented
public @interface IsBuyGood {

    String url();

}

切面类

package com.licai.web.annotations.aspect;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.dubbo.config.annotation.Reference;
import com.app.dubboservice.order.service.DubboOrderService;
import com.app.order.model.Order;
import com.app.user.model.UserInfo;
import com.licai.web.annotations.IsBuyGood;

@Aspect
@Component
public class IsBuyGoodAspect {
	
	@Reference(check = false)
	private DubboOrderService dubboOrderService;
	@Value("${spring.profiles.active}")
    private String profile;
	
    /**
     * 环绕增强
     * 判断controller的方法上有没有@IsLogin注解
     * 如果有就对其进行增强
     * 增强效果
     * 1/给方法的形参列表User user 注入值
     * 如果登录了就注入user
     * 如果没登录就注入null
     * 2.如果IsLogin的value=false表示不强制跳转到登录页面
     * 3.如果IsLogin的value=true表示强制跳转到登录页面,一旦发现cookie中没有值直接跳转不允许执行目标方法
     */
    @Around("@annotation(isBuyGood)")
    //表达式代表所有路径下面的xxxController类中的方法带@IsLogin注解的
    public Object isBuyGood(ProceedingJoinPoint proceedingJoinPoint,IsBuyGood isBuyGood) throws Throwable {
        //获得request请求
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpSession seesion = request.getSession();
		Integer userId=null;
        if(seesion!=null){
			UserInfo userInfo = (UserInfo) seesion.getAttribute("loginUser");
			if(userInfo!=null){
				userId=userInfo.getUserId();
			}
		}

        //表示已经登录或者不需要登录就可以继续操作
        //获得形参列表
        Object[] args = proceedingJoinPoint.getArgs();
        boolean isBuy = false;
        //因为登录后需要带returnUrl跳转到之前的页面,所以需要通过request对象获得url
        String requestURL = request.getRequestURL().toString();
        //带参数
        //requestURL.append(request.getQueryString());
        requestURL=requestURL.replace(request.getRequestURI(),"" );
        String url=requestURL+request.getContextPath()+isBuyGood.url();
        //解决中文乱码问题
//            String url = URLEncoder.encode(requestURL.toString(), "utf-8");
        //同样解决&带参数当做一个参数的问题
//            url = url.replace("&","%26");
        if(userId != null){
            
            String goodId = request.getParameter("goodsId");// 商品id
	        if(userId!=null && !goodId.isEmpty()) {
	            Order order = dubboOrderService.queryUserGoodsOrder(Integer.parseInt(goodId),userId);
	            if(order!=null) {
	                isBuy = true;
	            }else {
	            	isBuy = false;
	            }
	            if (profile != null && "dev".equals(profile)) {
	    			// 测试环境
	    			if("10898".equals(goodId)) {
	    				isBuy = true;
	    			}
	    		}else {
	    			if("11033".equals(goodId) || "11149".equals(goodId) || "11183".equals(goodId)) {
	    				isBuy = true;
	    			}
	    		}
	        }
            if(!isBuy) {
            	return "redirect:"+url;
            }
            //false继续执行目标方法
        }

        //执行目标方法  --- 带指定的形参列表
        Object result = proceedingJoinPoint.proceed(args);
        //执行目标方法后的方法返回值就是目标方法的返回值
        return result;
    }
}

使用

@RequestMapping("lianXi")
@IsBuyGood(url="/home")
public String lianXi() {
    
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于SpringBoot自定义注解AOP的问题,我可以为您提供一些基本的介绍和示例代码。 首先,AOP(Aspect-Oriented Programming)是一种编程范式,它可以在不修改业务逻辑代码的情况下,对应用程序进行横切关注点的切面处理。而Spring AOP作为Spring框架的一部分,提供了一种基于代理模式的AOP实现。 在使用Spring AOP的过程中,自定义注解可以作为切点表达式的一部分,通过对注解的解析,实现对被注解的方法或的切面处理。下面是一个简单的示例代码,演示如何通过自定义注解实现对方法的AOP处理: 首先,定义一个自定义注解: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { String value() default ""; } ``` 然后,在需要被拦截的方法上添加该注解: ```java @Service public class MyService { @MyAnnotation("myAnnotation") public void doSomething() { System.out.println("do something..."); } } ``` 接下来,使用AspectJ的@Aspect注解定义一个切面,并在该中定义一个切点,用于匹配被@MyAnnotation注解的方法: ```java @Aspect @Component public class MyAspect { @Pointcut("@annotation(com.example.demo.annotation.MyAnnotation)") public void myAnnotationPointcut() {} @Before("myAnnotationPointcut()") public void beforeMyAnnotation() { System.out.println("before myAnnotation..."); } } ``` 最后,启动SpringBoot应用程序,调用MyService的doSomething方法,就可以看到输出结果: ```java before myAnnotation... do something... ``` 以上就是一个简单的SpringBoot自定义注解AOP的示例。通过使用自定义注解,可以更加方便地实现对应用程序的切面处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值