原创

Springboot 自定义登录注解

1. java注解使用是相当频繁,特别是在搭建一些框架时,用到类的反射获取方法和属性,用的尤其多。

    java中元注解有四个: @Retention     @Target     @Document   @Inherited

@Retention:注解的保留位置
	@Retention(RetentionPolicy.SOURCE)    //注解仅存在于源码中,在class字节码文件中不包含
	@Retention(RetentionPolicy.CLASS)     //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
	@Retention(RetentionPolicy.RUNTIME)   //注解会在class字节码文件中存在,在运行时可以通过反射获取到

@Target:注解的作用目标
	@Target(ElementType.TYPE)   //接口、类、枚举、注解
	@Target(ElementType.FIELD) //字段、枚举的常量
	@Target(ElementType.METHOD) //方法
	@Target(ElementType.PARAMETER) //方法参数
	@Target(ElementType.CONSTRUCTOR)  //构造函数
	@Target(ElementType.LOCAL_VARIABLE)//局部变量
	@Target(ElementType.ANNOTATION_TYPE)//注解
	@Target(ElementType.PACKAGE) ///包

@Document:说明该注解将被包含在javadoc中<br/>@Inherited:说明子类可以继承父类中的该注解


2. 创建maven项目,添加pom依赖

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


3. 创建自定义注解类

package com.fliangyun.testaop.aop;

import java.lang.annotation.*;

/**
 * @author 莴苣社区
 * @date 2021年11月30日
 * @description
 */
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Login {

}


4. 创建切点,声明注解的作用

package com.fliangyun.testaop.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author 莴苣社区
 * @date 2021年11月30日
 * @description
 */
@Aspect
@Component
public class LoginAspect {

    /**
     * 声明切点
     */
    @Pointcut("@annotation(Login)")
    public void loginCut(){

    }

    /**
     * 设置切点执行方法
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = "loginCut()")
    public Object login(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        // 判断当前请求的方法是否有@Login注解
        Login login = method.getAnnotation(Login.class);
        if (login != null){
            // 存在注解,执行登录权限验证
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String token = request.getHeader("token");
            if (token == null || token.length() == 0){
                return "未登录";
            }
        }
        return proceedingJoinPoint.proceed();
    }

}


5. 自定义注解的使用

package com.fliangyun.testaop.controller;

import com.fliangyun.testaop.aop.Login;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 莴苣社区
 * @date 2021年11月30日
 * @description
 */
@RestController
public class IndexController {

    /**
     * 这是一个需要登录的方法
     * @return
     */
    @Login
    @ResponseBody
    @GetMapping("needLogin")
    public String needLogin(){
        return "已登录";
    }

    /**
     * 这是一个不需要登录的方法
     * @return
     */
    @ResponseBody
    @GetMapping("login")
    public String notNeedLogin(){
        return "成功";
    }

}


6. 测试

正文到此结束