Java注解之自定义注解并实现实战(初学者)

业务需求

半个月前,测试和我说:“如果商家被禁用了,那他就只能提现和查看自己的信息,不能修改。”

这把当时的我难住了。因为我们的商家是在一张表里的,所有的登录却是查的用户表,那怎么判断商家登录的他的商店是否被禁用了呢?我想到了一个以前从来没有尝试过的办法:AOP。

设计是这样的:被禁用的商家想要登录,没问题,可以,但他要想发货,操作商品,那不行,只有解封了才可以操作。在他禁用这段时间,他只能查看他的订单和商品情况,噢,还有可以提现。

于是乎,我东琢磨西琢磨,便琢磨出了这个注解。

代码赏析

1. 依赖

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

2. 自定义注解

/**
 * 商家操作限制
 *
 * @author: YCL
 * @date: 2021-09-09 12:43:35
 */
@Target({
		ElementType.TYPE,//作用于类上
		ElementType.METHOD,//作用于方法上
})
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationIntercept {

	/**
	 * 默认拦截
	 * 
	 * @return
	 */
	boolean intercept() default true;
}

3. 注解实现

A. 首先,定义一个类,啥都不继承

/**
 * 操作限制实现
 *
 * @author: YCL
 * @date: 2021-09-09 12:49:50
 */
@Aspect //标明是切面编程
@Configuration
@Component
public class OperationInterceptAspect {

	@Resource
	private StringRedisTemplate stringRedisTemplate;
	@Resource
	private MallStoreService mallStoreService;

}

B. 解析注解

	
	/**
	 * 这里不能用@annotation(), 不然类上面使用这个注解无效, 得使用@within()
	 */
	@Pointcut("@within(ycl.important.annocation.OperationIntercept)")
	public void pointcut(){
	}

	/**
	 * 一般来说,鼠标悬停在 pointcut() 上加上ctrl键点击会跑到上面的方法,如果没跳就看看类开头的 @Aspect 加了没有
	 * 
	 * 导包:
	 * org.aspectj.lang.JoinPoint
	 * org.aspectj.lang.reflect.MethodSignature
	 * java.lang.reflect.Method
	 * org.springframework.web.context.request.RequestContextHolder
	 */
	@Before("pointcut()")
	
	public void before(JoinPoint joinPoint){
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();

		OperationIntercept annotation = method.getAnnotation(OperationIntercept.class);
		//是否校验, 我这边设置了为true就校验
		boolean intercept = true;
		if (annotation != null)
			intercept = annotation.intercept();
		if (!intercept)
			return;
			
		//获取request,项目的请求头token是被request带过来的,所以这里必须要request
		RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
		if (attributes == null)
			return;
		HttpServletRequest request = (HttpServletRequest) attributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
		if (request == null)
			return;
	
		Long id = mallStoreService.getUserId(request);
		Long mall = mallStoreService.selectIdByUserId(id);
		String s = stringRedisTemplate.opsForValue().get(RedisConstant.MERCHANT_DISABLE + mall);
		if (StrUtil.isNotBlank(s))
			throw new IllegalArgumentException("抱歉, 您被禁用, 无法操作");		
	}

到此,这个注解就结束啦!接下来测试一下

测试

1. 后台禁用

现在如图可以看到,登录上去后用户id 是3,对应的商店id 是 1。

现在如图可以看到,登录上去后用户id 是3,对应的商店id 是 1。

现在把这个3468给禁用掉

现在把这个3468给禁用掉

redis里会出现一个禁用标志

redis里出现一个商家被禁用标志

2. 在商品的api上配置注解

挖个坑:这个注解可以作用在类上和方法上。如果在一个配置上这个注解的类里面,一个方法配置不校验,另一个不配置会怎么样呢?

再挖个坑:那如果在一个没有配置这个注解的类里面,一个方法加上这个注解,另一个不加,又会怎么样呢?
坑 1 图
坑 1 图

坑 2 图
坑 2 图

3. 商家操作

我们先看看这个商店发布的商品的 id 是多少
在这里插入图片描述

A. 我们来看看坑一的查商品,能不能查到

在这里插入图片描述

B. 来看看坑一的商品下架

在这里插入图片描述

C. 再看看第二个坑的主页

在这里插入图片描述

D. 第二个坑的第二个

在这里插入图片描述

总结

  1. 当我们在类上配置了这个注解后,因为本注解默认是校验,所以里面的所有方法都会一同被校验,这时当我们需要某个方法不需要校验时再单独给他配置一下就可以了。
  2. 当我们在类上不配置这个注解后,下面的所有注解就都用不了了。

为什么呢?按照常理来说,这个配置放不放在类上,和方法是无影响的呀?

好吧,我也不清楚他咋会这样……也算挖了第三个坑,以后来填了……

结语

希望我们同代码一起携手共进,一起为自己的目标努力!!

由衷感谢您的观看,您的收获和支持就是我的最大动力!!再次感谢!!

END

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值