使用AOP写一个简单的登录拦截

引入pom依赖

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

定义权限注解

package com.yidong.Aop;

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

@Documented//说明该注解将被包含在javadoc中
@Retention(RetentionPolicy.RUNTIME)// 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target({ElementType.METHOD, ElementType.PARAMETER})//@Target:定义注解的作用目标,方法和方法参数
@Inherited//说明子类可以继承父类中的该注解
public @interface SysLogin {
 //登录用户名
 public String username();
}
切入点表达式
表达式类型说明
execution定位到目标对象的方法上
within定位到具体的类型上
this代理对象的类型
target目标对象的类型
args参数的类型
@args传入的参数有被该注解修饰
@within类型修饰的注解
@annotation方法修饰的注解

execution表达式

语法: execution([访问权限类型] 返回值类型 [全限定类名] 方法名(参数名) [抛出的异常类型])

符合含有
*0到多个符合
方法参数中表示任意个参数,用在报名后表示当前包及其子包
+用在类名后表示当前类及其子类,用在接口后表接口及其实现

实例:

execution(public * *(. .))
指定切入点为:任意公共方法。
execution(* set *(. .))
指定切入点为:任何一个以“set”开始的方法。
execution(* com.xyz.service.*.*(. .))
指定切入点为:定义在service包里的任意类的任意方法。
execution(* com.xyz.service. .*.*(. .))
指定切入点为:定义在service包或者子包里的任意类的任意方法。“..”出现在类名中时,
后面必须跟“*”,表示包、子包下的所有类。
execution(* *.service.*.*(. .))
指定只有一级包下的serivce子包下所有类(接口)中的所有方法为切入点
execution(* *. .service.*.*(. .))
指定所有包下的serivce子包下所有类(接口)中的所有方法为切入点

通知类型

通知类型说明
前置通知目标方法执行之前调用
后置通知目标方法执行完成之后调用
环绕通知目标方法执行前后都会调用方法,且能增强结果
异常处理通知目标方法出现异常调用
最终通知无论程序执行是否正常,该通知都会执行。类似于try…catch中finally代码块

定义切面

  • 前置通知 @Before 在方法之前执行
  • 后置通知 @After 在方法之后执行
  • 异常通知 @AfterThrowing 方法出现异常时执行
  • 最终通知 @AfterReturning 在方法返回后执行
  • 环绕通知 @Around 在方法之前和之后执行(必须使用Object作为返回值类型) 定义入参ProceedingJoinPoint
    point 表示连接点(使用该注解的方法对象)

下面方法是一个写死的登录拦截,当username为admin时有权限,其他就抛异常

package com.yidong.Aop;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
/**
 * 前置通知 @Before 在方法之前执行
后置通知 @After 在方法之后执行
异常通知 @AfterThrowing 方法出现异常时执行
最终通知 @AfterReturning 在方法返回后执行
环绕通知 @Around 在方法之前和之后执行(必须使用Object作为返回值类型) 定义入参ProceedingJoinPoint point 表示连接点(使用该注解的方法对象)
 * @author lWX1003892
 *
 */
@Aspect
@Component
public class SysLoginAspect {
 @Pointcut("@annotation(com.yidong.Aop.SysLogin)")
 public void sysLogin() {
  
 }
// @Before("sysLogin()")
// public void loginAspect(JoinPoint joinPoint) {
//        System.out.println(joinPoint.getSignature().getName() + "收到的参数为" + Arrays.toString(joinPoint.getArgs()));
// }
 @Around("sysLogin()")
 public Object loginAround(ProceedingJoinPoint point) throws Throwable {
  Signature signature = point.getSignature();
  MethodSignature methodSignature = (MethodSignature) signature;
  Method method = methodSignature.getMethod();
  SysLogin login = method.getAnnotation(SysLogin.class);
  if (login==null) {
   return point.proceed();
  }else {
   System.out.println("login==="+login.username());
   if (login.username().equals("admin")) {
    return point.proceed();
   }
   throw new RuntimeException("没有权限");
  }
 }
}

测试controller

当注解中的参数为admin时登录成功 @SysLogin(username = “admin”),为其他参数时会抛异常

 @SysLogin(username = "admin")
 @RequestMapping("/findObj/crm/qryAop")
// @SuppressWarnings("unchecked")
 public Map<String, Object> qryAop(@RequestBody Map<String,Object> map) {
  //返回列表消息头
  Map<String, Object> repMap = new HashMap<String, Object>();
  repMap.put("code", "0");
  return repMap;
 }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值